summaryrefslogtreecommitdiff
path: root/sysdep/unix/krt.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-07-11 17:04:52 +0200
committerMaria Matejka <mq@ucw.cz>2022-07-11 17:04:52 +0200
commit9efaf6bafea1c69629e59c6504980fb2986287fe (patch)
tree8674003cef5c7b21031500ea24f35b045a95cbe7 /sysdep/unix/krt.c
parent6b0368cc2c317d1acc0881a96b32ded291d82741 (diff)
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.
Diffstat (limited to 'sysdep/unix/krt.c')
-rw-r--r--sysdep/unix/krt.c239
1 files changed, 10 insertions, 229 deletions
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index a37d3186..67d19cbb 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -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;
-
- struct rte_storage *ee = rte_store(e, n, p->krt_table);
-
- 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;
+ rte e0 = {
+ .attrs = e->attrs,
+ .src = rt_get_source(&p->p, krt_metric(e)),
+ };
- 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;
+ ea_set_attr_u32(&e0.attrs, &ea_gen_preference, 0, p->p.main_channel->preference);
- 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");
-
- 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;
- }
+ return krt_learn_scan(p, e);
- 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