diff options
author | Maria Matejka <mq@jmq.cz> | 2021-11-25 20:21:58 +0000 |
---|---|---|
committer | Maria Matejka <mq@ucw.cz> | 2021-12-01 14:02:23 +0100 |
commit | 7092bdc0c9fa77b5cad1c29b342b81f01ba087be (patch) | |
tree | dd02ce69f07d19cbbc77377f99cfe2075a014a44 /nest | |
parent | b50224a00351904f25a5105a98d56a62ed2c33a4 (diff) |
fixed duplicate routes propagation
Diffstat (limited to 'nest')
-rw-r--r-- | nest/route.h | 1 | ||||
-rw-r--r-- | nest/rt-table.c | 35 |
2 files changed, 21 insertions, 15 deletions
diff --git a/nest/route.h b/nest/route.h index f060ad63..9f09ae3a 100644 --- a/nest/route.h +++ b/nest/route.h @@ -519,7 +519,6 @@ void rt_refresh_end(struct rt_import_request *); void rt_schedule_prune(rtable_private *t); void rte_dump(struct rte_storage *); void rte_free(struct rte_storage *, rtable_private *); -struct rte_storage *rte_store(const rte *, net *net, rtable_private *); void rt_dump(rtable *); void rt_dump_all(void); void rt_dump_hooks(rtable *); diff --git a/nest/rt-table.c b/nest/rt-table.c index ada54396..e231b9a3 100644 --- a/nest/rt-table.c +++ b/nest/rt-table.c @@ -341,7 +341,7 @@ rte_find(net *net, struct rte_src *src) } -struct rte_storage * +static struct rte_storage * rte_store(const rte *r, net *net, rtable_private *tab) { struct rte_storage *e = sl_alloc(tab->rte_slab); @@ -351,11 +351,6 @@ rte_store(const rte *r, net *net, rtable_private *tab) rt_lock_source(e->rte.src); - if (e->rte.attrs->cached) - e->rte.attrs = rta_clone(e->rte.attrs); - else - e->rte.attrs = rta_lookup(e->rte.attrs); - return e; } @@ -1294,10 +1289,11 @@ rte_validate(struct channel *ch, rte *e) static int rte_same(rte *x, rte *y) { + ASSERT_DIE(x->attrs->cached && y->attrs->cached); + /* rte.flags are not checked, as they are mostly internal to rtable */ return x->attrs == y->attrs && - x->pflags == y->pflags && x->src == y->src && rte_is_filtered(x) == rte_is_filtered(y); } @@ -1320,6 +1316,15 @@ rte_recalculate(rtable_private *table, struct rt_import_hook *c, net *net, rte * /* Find and remove original route from the same protocol */ struct rte_storage **before_old = rte_find(net, src); + if (!*before_old && !new) + { + stats->withdraws_ignored++; + return; + } + + if (new) + new->attrs = rta_is_cached(new->attrs) ? rta_clone(new->attrs) : rta_lookup(new->attrs); + if (*before_old) { old = &(old_stored = (*before_old))->rte; @@ -1349,6 +1354,8 @@ rte_recalculate(rtable_private *table, struct rt_import_hook *c, net *net, rte * stats->updates_ignored++; rt_rte_trace_in(D_ROUTES, req, new, "ignored"); } + + rta_free(new->attrs); return; } @@ -1356,12 +1363,6 @@ rte_recalculate(rtable_private *table, struct rt_import_hook *c, net *net, rte * table->rt_count--; } - if (!old && !new) - { - stats->withdraws_ignored++; - return; - } - if (req->preimport) new = req->preimport(req, new, old); @@ -1523,7 +1524,10 @@ channel_preimport(struct rt_import_request *req, rte *new, rte *old) { if (new && !old) if (CHANNEL_LIMIT_PUSH(c, RX)) + { + rta_free(new->attrs); return NULL; + } if (!new && old) CHANNEL_LIMIT_POP(c, RX); @@ -1540,7 +1544,10 @@ channel_preimport(struct rt_import_request *req, rte *new, rte *old) return new; } else + { + rta_free(new->attrs); return NULL; + } if (!new_in && old_in) CHANNEL_LIMIT_POP(c, IN); @@ -2671,7 +2678,7 @@ rt_next_hop_update_rte(rtable_private *tab, net *n, rte *old) a->cached = 0; rte e0 = *old; - e0.attrs = a; + e0.attrs = rta_lookup(a); return rte_store(&e0, n, tab); } |