0
0
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:
Maria Matejka 2022-07-11 17:04:52 +02:00
parent 6b0368cc2c
commit 9efaf6bafe
3 changed files with 11 additions and 235 deletions

View File

@ -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;

View File

@ -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

View File

@ -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