mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Dropped the internal kernel protocol table for learnt routes.
The learnt routes are now pushed all into the connected table, not only the best one. This shouldn't do any damage in well managed setups, yet it should be noted that it is a change of behavior. If anybody misses a feature which they implemented by misusing this internal learn table, let us know, we'll consider implementing it in a better way.
This commit is contained in:
parent
6b0368cc2c
commit
9efaf6bafe
@ -2042,11 +2042,10 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
|
||||
s->net = lp_alloc(s->pool, net->length);
|
||||
net_copy(s->net, net);
|
||||
|
||||
s->attrs = ra;
|
||||
|
||||
ea_set_attr_data(&ra, &ea_gen_nexthop, 0,
|
||||
nhad.ad.data, nhad.ad.length);
|
||||
|
||||
s->attrs = ra;
|
||||
s->proto = p;
|
||||
s->new = new;
|
||||
s->krt_src = krt_src;
|
||||
|
@ -302,236 +302,29 @@ krt_uptodate(rte *a, rte *b)
|
||||
return (a->attrs == b->attrs);
|
||||
}
|
||||
|
||||
static void
|
||||
krt_learn_announce_update(struct krt_proto *p, rte *e)
|
||||
{
|
||||
rte e0 = {
|
||||
.attrs = ea_clone(e->attrs),
|
||||
.src = p->p.main_source,
|
||||
};
|
||||
|
||||
rte_update(p->p.main_channel, e->net, &e0, p->p.main_source);
|
||||
}
|
||||
|
||||
static void
|
||||
krt_learn_announce_delete(struct krt_proto *p, net_addr *n)
|
||||
{
|
||||
rte_update(p->p.main_channel, n, NULL, p->p.main_source);
|
||||
}
|
||||
|
||||
/* Called when alien route is discovered during scan */
|
||||
static void
|
||||
krt_learn_scan(struct krt_proto *p, rte *e)
|
||||
{
|
||||
net *n = net_get(p->krt_table, e->net);
|
||||
struct rte_storage *m, **mm;
|
||||
rte e0 = {
|
||||
.attrs = e->attrs,
|
||||
.src = rt_get_source(&p->p, krt_metric(e)),
|
||||
};
|
||||
|
||||
struct rte_storage *ee = rte_store(e, n, p->krt_table);
|
||||
ea_set_attr_u32(&e0.attrs, &ea_gen_preference, 0, p->p.main_channel->preference);
|
||||
|
||||
for(mm = &n->routes; m = *mm; mm = &m->next)
|
||||
if (krt_same_key(&m->rte, e))
|
||||
break;
|
||||
if (m)
|
||||
{
|
||||
if (krt_uptodate(&m->rte, e))
|
||||
{
|
||||
krt_trace_in_rl(&rl_alien, p, e, "[alien] seen");
|
||||
rte_free(ee);
|
||||
m->rte.pflags |= KRT_REF_SEEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
krt_trace_in(p, e, "[alien] updated");
|
||||
*mm = m->next;
|
||||
rte_free(m);
|
||||
m = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
krt_trace_in(p, e, "[alien] created");
|
||||
|
||||
if (!m)
|
||||
{
|
||||
ee->next = n->routes;
|
||||
n->routes = ee;
|
||||
ee->rte.pflags |= KRT_REF_SEEN;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
krt_learn_prune(struct krt_proto *p)
|
||||
{
|
||||
struct fib *fib = &p->krt_table->fib;
|
||||
struct fib_iterator fit;
|
||||
|
||||
KRT_TRACE(p, D_EVENTS, "Pruning inherited routes");
|
||||
|
||||
FIB_ITERATE_INIT(&fit, fib);
|
||||
again:
|
||||
FIB_ITERATE_START(fib, &fit, net, n)
|
||||
{
|
||||
struct rte_storage *e, **ee, *best, **pbest, *old_best;
|
||||
|
||||
/*
|
||||
* Note that old_best may be NULL even if there was an old best route in
|
||||
* the previous step, because it might be replaced in krt_learn_scan().
|
||||
* But in that case there is a new valid best route.
|
||||
*/
|
||||
|
||||
old_best = NULL;
|
||||
best = NULL;
|
||||
pbest = NULL;
|
||||
ee = &n->routes;
|
||||
while (e = *ee)
|
||||
{
|
||||
if (e->rte.pflags & KRT_REF_BEST)
|
||||
old_best = e;
|
||||
|
||||
if (!(e->rte.pflags & KRT_REF_SEEN))
|
||||
{
|
||||
*ee = e->next;
|
||||
rte_free(e);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!best || krt_metric(&best->rte) > krt_metric(&e->rte))
|
||||
{
|
||||
best = e;
|
||||
pbest = ee;
|
||||
}
|
||||
|
||||
e->rte.pflags &= ~(KRT_REF_SEEN | KRT_REF_BEST);
|
||||
ee = &e->next;
|
||||
}
|
||||
if (!n->routes)
|
||||
{
|
||||
DBG("%I/%d: deleting\n", n->n.prefix, n->n.pxlen);
|
||||
if (old_best)
|
||||
krt_learn_announce_delete(p, n->n.addr);
|
||||
|
||||
FIB_ITERATE_PUT(&fit);
|
||||
fib_delete(fib, n);
|
||||
goto again;
|
||||
}
|
||||
|
||||
best->rte.pflags |= KRT_REF_BEST;
|
||||
*pbest = best->next;
|
||||
best->next = n->routes;
|
||||
n->routes = best;
|
||||
|
||||
if ((best != old_best) || p->reload)
|
||||
{
|
||||
DBG("%I/%d: announcing (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(&best->rte));
|
||||
krt_learn_announce_update(p, &best->rte);
|
||||
}
|
||||
else
|
||||
DBG("%I/%d: uptodate (metric=%d)\n", n->n.prefix, n->n.pxlen, krt_metric(&best->rte));
|
||||
}
|
||||
FIB_ITERATE_END;
|
||||
|
||||
p->reload = 0;
|
||||
rte_update(p->p.main_channel, e->net, &e0, e0.src);
|
||||
}
|
||||
|
||||
static void
|
||||
krt_learn_async(struct krt_proto *p, rte *e, int new)
|
||||
{
|
||||
net *n = net_get(p->krt_table, e->net);
|
||||
struct rte_storage *g, **gg, *best, **bestp, *old_best;
|
||||
|
||||
ea_set_attr_u32(&e->attrs, &ea_gen_preference, 0, p->p.main_channel->preference);
|
||||
struct rte_storage *ee = rte_store(e, n, p->krt_table);
|
||||
|
||||
old_best = n->routes;
|
||||
for(gg=&n->routes; g = *gg; gg = &g->next)
|
||||
if (krt_same_key(&g->rte, e))
|
||||
break;
|
||||
if (new)
|
||||
{
|
||||
if (g)
|
||||
{
|
||||
if (krt_uptodate(&g->rte, e))
|
||||
{
|
||||
krt_trace_in(p, e, "[alien async] same");
|
||||
rte_free(ee);
|
||||
return;
|
||||
}
|
||||
krt_trace_in(p, e, "[alien async] updated");
|
||||
*gg = g->next;
|
||||
rte_free(g);
|
||||
}
|
||||
else
|
||||
krt_trace_in(p, e, "[alien async] created");
|
||||
return krt_learn_scan(p, e);
|
||||
|
||||
ee->next = n->routes;
|
||||
n->routes = ee;
|
||||
}
|
||||
else if (!g)
|
||||
{
|
||||
krt_trace_in(p, e, "[alien async] delete failed");
|
||||
rte_free(ee);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
krt_trace_in(p, e, "[alien async] removed");
|
||||
*gg = g->next;
|
||||
rte_free(ee);
|
||||
rte_free(g);
|
||||
}
|
||||
best = n->routes;
|
||||
bestp = &n->routes;
|
||||
for(gg=&n->routes; g=*gg; gg=&g->next)
|
||||
{
|
||||
if (krt_metric(&best->rte) > krt_metric(&g->rte))
|
||||
{
|
||||
best = g;
|
||||
bestp = gg;
|
||||
}
|
||||
|
||||
g->rte.pflags &= ~KRT_REF_BEST;
|
||||
}
|
||||
|
||||
if (best)
|
||||
{
|
||||
best->rte.pflags |= KRT_REF_BEST;
|
||||
*bestp = best->next;
|
||||
best->next = n->routes;
|
||||
n->routes = best;
|
||||
}
|
||||
|
||||
if (best != old_best)
|
||||
{
|
||||
DBG("krt_learn_async: distributing change\n");
|
||||
if (best)
|
||||
krt_learn_announce_update(p, &best->rte);
|
||||
else
|
||||
krt_learn_announce_delete(p, n->n.addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
krt_learn_init(struct krt_proto *p)
|
||||
{
|
||||
if (KRT_CF->learn)
|
||||
{
|
||||
struct rtable_config *cf = mb_allocz(p->p.pool, sizeof(struct rtable_config));
|
||||
cf->name = "Inherited";
|
||||
cf->addr_type = p->p.net_type;
|
||||
cf->internal = 1;
|
||||
|
||||
p->krt_table = rt_setup(p->p.pool, cf);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
krt_dump(struct proto *P)
|
||||
{
|
||||
struct krt_proto *p = (struct krt_proto *) P;
|
||||
|
||||
if (!KRT_CF->learn)
|
||||
return;
|
||||
debug("KRT: Table of inheritable routes\n");
|
||||
rt_dump(p->krt_table);
|
||||
struct rte_src *src = rt_find_source(&p->p, krt_metric(e));
|
||||
if (src)
|
||||
rte_update(p->p.main_channel, e->net, NULL, src);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -738,11 +531,6 @@ krt_prune(struct krt_proto *p)
|
||||
}
|
||||
FIB_WALK_END;
|
||||
|
||||
#ifdef KRT_ALLOW_LEARN
|
||||
if (KRT_CF->learn)
|
||||
krt_learn_prune(p);
|
||||
#endif
|
||||
|
||||
if (p->ready)
|
||||
p->initialized = 1;
|
||||
}
|
||||
@ -1053,10 +841,6 @@ krt_start(struct proto *P)
|
||||
bmap_init(&p->seen_map, p->p.pool, 1024);
|
||||
add_tail(&krt_proto_list, &p->krt_node);
|
||||
|
||||
#ifdef KRT_ALLOW_LEARN
|
||||
krt_learn_init(p);
|
||||
#endif
|
||||
|
||||
if (!krt_sys_start(p))
|
||||
{
|
||||
rem_node(&p->krt_node);
|
||||
@ -1172,9 +956,6 @@ struct protocol proto_unix_kernel = {
|
||||
.shutdown = krt_shutdown,
|
||||
.reconfigure = krt_reconfigure,
|
||||
.copy_config = krt_copy_config,
|
||||
#ifdef KRT_ALLOW_LEARN
|
||||
.dump = krt_dump,
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -55,10 +55,6 @@ struct krt_proto {
|
||||
struct proto p;
|
||||
struct krt_state sys; /* Sysdep state */
|
||||
|
||||
#ifdef KRT_ALLOW_LEARN
|
||||
struct rtable *krt_table; /* Internal table of inherited routes */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_ALL_TABLES_AT_ONCE
|
||||
timer *scan_timer;
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user