summaryrefslogtreecommitdiff
path: root/sysdep/unix/krt.c
diff options
context:
space:
mode:
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