diff options
author | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-02-09 15:53:16 +0100 |
---|---|---|
committer | Ondrej Zajicek (work) <santiago@crfreenet.org> | 2019-02-09 15:53:16 +0100 |
commit | cd16538fc91778e31f8241f62ee47056f099c051 (patch) | |
tree | e94474a81ff652c8d8d6d46722aac62043aa3770 /nest/rt-table.c | |
parent | 6e8fb66859a17b295cd9246264221a75cdbe6c55 (diff) | |
parent | f9b97f1c6282be398d2c2bb896dbb453f638f720 (diff) |
Merge remote-tracking branch 'origin/mq-opt'
Diffstat (limited to 'nest/rt-table.c')
-rw-r--r-- | nest/rt-table.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/nest/rt-table.c b/nest/rt-table.c index 194eadf8..a1900532 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -405,8 +405,6 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int si rt = rt0; *rt_free = NULL; - rte_make_tmp_attrs(&rt, pool); - v = p->preexport ? p->preexport(p, &rt, pool) : 0; if (v < 0) { @@ -425,6 +423,8 @@ export_filter_(struct channel *c, rte *rt0, rte **rt_free, linpool *pool, int si goto accept; } + rte_make_tmp_attrs(&rt, pool); + v = filter && ((filter == FILTER_REJECT) || (f_run(filter, &rt, pool, (silent ? FF_SILENT : 0)) > F_ACCEPT)); @@ -1368,7 +1368,10 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) rte_update_lock(); if (new) { - nn = net_get(c->table, n); + /* Create a temporary table node */ + nn = alloca(sizeof(net) + n->length); + memset(nn, 0, sizeof(net) + n->length); + net_copy(nn->n.addr, n); new->net = nn; new->sender = c; @@ -1419,6 +1422,10 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) if (!rta_is_cached(new->attrs)) /* Need to copy attributes */ new->attrs = rta_lookup(new->attrs); new->flags |= REF_COW; + + /* Use the actual struct network, not the dummy one */ + nn = net_get(c->table, n); + new->net = nn; } else { @@ -1433,16 +1440,21 @@ rte_update2(struct channel *c, const net_addr *n, rte *new, struct rte_src *src) } recalc: + /* And recalculate the best route */ rte_hide_dummy_routes(nn, &dummy); rte_recalculate(c, nn, new, src); rte_unhide_dummy_routes(nn, &dummy); + rte_update_unlock(); return; drop: rte_free(new); new = NULL; - goto recalc; + if (nn = net_find(c->table, n)) + goto recalc; + + rte_update_unlock(); } /* Independent call to rte_announce(), used from next hop @@ -1499,12 +1511,14 @@ rt_examine(rtable *t, net_addr *a, struct proto *p, struct filter *filter) rte_update_lock(); /* Rest is stripped down export_filter() */ - rte_make_tmp_attrs(&rt, rte_update_pool); int v = p->preexport ? p->preexport(p, &rt, rte_update_pool) : 0; if (v == RIC_PROCESS) + { + rte_make_tmp_attrs(&rt, rte_update_pool); v = (f_run(filter, &rt, rte_update_pool, FF_SILENT) <= F_ACCEPT); + } - /* Discard temporary rte */ + /* Discard temporary rte */ if (rt != n->routes) rte_free(rt); |