mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-23 18:21:54 +00:00
fixed duplicate routes propagation
This commit is contained in:
parent
b50224a003
commit
7092bdc0c9
@ -519,7 +519,6 @@ void rt_refresh_end(struct rt_import_request *);
|
|||||||
void rt_schedule_prune(rtable_private *t);
|
void rt_schedule_prune(rtable_private *t);
|
||||||
void rte_dump(struct rte_storage *);
|
void rte_dump(struct rte_storage *);
|
||||||
void rte_free(struct rte_storage *, rtable_private *);
|
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(rtable *);
|
||||||
void rt_dump_all(void);
|
void rt_dump_all(void);
|
||||||
void rt_dump_hooks(rtable *);
|
void rt_dump_hooks(rtable *);
|
||||||
|
@ -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)
|
rte_store(const rte *r, net *net, rtable_private *tab)
|
||||||
{
|
{
|
||||||
struct rte_storage *e = sl_alloc(tab->rte_slab);
|
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);
|
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;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,10 +1289,11 @@ rte_validate(struct channel *ch, rte *e)
|
|||||||
static int
|
static int
|
||||||
rte_same(rte *x, rte *y)
|
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 */
|
/* rte.flags are not checked, as they are mostly internal to rtable */
|
||||||
return
|
return
|
||||||
x->attrs == y->attrs &&
|
x->attrs == y->attrs &&
|
||||||
x->pflags == y->pflags &&
|
|
||||||
x->src == y->src &&
|
x->src == y->src &&
|
||||||
rte_is_filtered(x) == rte_is_filtered(y);
|
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 */
|
/* Find and remove original route from the same protocol */
|
||||||
struct rte_storage **before_old = rte_find(net, src);
|
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)
|
if (*before_old)
|
||||||
{
|
{
|
||||||
old = &(old_stored = (*before_old))->rte;
|
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++;
|
stats->updates_ignored++;
|
||||||
rt_rte_trace_in(D_ROUTES, req, new, "ignored");
|
rt_rte_trace_in(D_ROUTES, req, new, "ignored");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rta_free(new->attrs);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1356,12 +1363,6 @@ rte_recalculate(rtable_private *table, struct rt_import_hook *c, net *net, rte *
|
|||||||
table->rt_count--;
|
table->rt_count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!old && !new)
|
|
||||||
{
|
|
||||||
stats->withdraws_ignored++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (req->preimport)
|
if (req->preimport)
|
||||||
new = req->preimport(req, new, old);
|
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 (new && !old)
|
||||||
if (CHANNEL_LIMIT_PUSH(c, RX))
|
if (CHANNEL_LIMIT_PUSH(c, RX))
|
||||||
|
{
|
||||||
|
rta_free(new->attrs);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!new && old)
|
if (!new && old)
|
||||||
CHANNEL_LIMIT_POP(c, RX);
|
CHANNEL_LIMIT_POP(c, RX);
|
||||||
@ -1540,7 +1544,10 @@ channel_preimport(struct rt_import_request *req, rte *new, rte *old)
|
|||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
rta_free(new->attrs);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!new_in && old_in)
|
if (!new_in && old_in)
|
||||||
CHANNEL_LIMIT_POP(c, 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;
|
a->cached = 0;
|
||||||
|
|
||||||
rte e0 = *old;
|
rte e0 = *old;
|
||||||
e0.attrs = a;
|
e0.attrs = rta_lookup(a);
|
||||||
|
|
||||||
return rte_store(&e0, n, tab);
|
return rte_store(&e0, n, tab);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user