diff options
Diffstat (limited to 'sysdep/unix')
-rw-r--r-- | sysdep/unix/krt-set.c | 3 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 38 | ||||
-rw-r--r-- | sysdep/unix/krt.h | 7 |
3 files changed, 46 insertions, 2 deletions
diff --git a/sysdep/unix/krt-set.c b/sysdep/unix/krt-set.c index dae01f4..2165255 100644 --- a/sysdep/unix/krt-set.c +++ b/sysdep/unix/krt-set.c @@ -43,7 +43,7 @@ krt_capable_op(rte *e) rta *a = e->attrs; #ifdef CONFIG_AUTO_ROUTES - if (a->dest == RTD_ROUTER && a->source == RTS_DEVICE) + if (a->source == RTS_DEVICE) return 0; #endif return krt_capable(e); @@ -115,6 +115,7 @@ krt_add_route(rte *new) void krt_set_notify(struct proto *x, net *net, rte *new, rte *old) { + /* FIXME: Fold remove/add route here */ if (old) krt_remove_route(old); if (new) diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 5fbd52c..aa875cc 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -78,6 +78,7 @@ krt_got_route(struct krt_proto *p, rte *e) { rte *old; net *net = e->net; + int src = e->u.krt_sync.src; int verdict; if (net->n.flags) @@ -97,7 +98,7 @@ krt_got_route(struct krt_proto *p, rte *e) else verdict = KRF_UPDATE; } - else if (KRT_CF->learn && !net->routes) + else if (KRT_CF->learn && !net->routes && (src == KRT_SRC_ALIEN || src < 0)) verdict = KRF_LEARN; else verdict = KRF_DELETE; @@ -188,6 +189,41 @@ krt_prune(struct krt_proto *p) FIB_WALK_END; } +void +krt_got_route_async(struct krt_proto *p, rte *e, int new) +{ + net *net = e->net; + rte *old = net->routes; + int src = e->u.krt_sync.src; + + switch (src) + { + case KRT_SRC_BIRD: + ASSERT(0); + case KRT_SRC_REDIRECT: + DBG("It's a redirect, kill him! Kill! Kill!\n"); + krt_set_notify(&p->p, net, NULL, e); + break; + default: /* Alien or unspecified */ + if (KRT_CF->learn && new) + { + /* + * FIXME: This is limited to one inherited route per destination as we + * use single protocol for all inherited routes. Probably leave it + * as-is (and document it :)), because the correct solution is to + * multiple kernel tables anyway. + */ + DBG("Learning\n"); + rte_update(net, &p->p, e); + } + else + { + DBG("Discarding\n"); + rte_update(net, &p->p, NULL); + } + } +} + /* * Periodic scanning */ diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index 1c59799..02814c6 100644 --- a/sysdep/unix/krt.h +++ b/sysdep/unix/krt.h @@ -52,6 +52,13 @@ extern struct proto_config *cf_krt; #define KRT_CF ((struct krt_config *)p->p.cf) void krt_got_route(struct krt_proto *p, struct rte *e); +void krt_got_route_async(struct krt_proto *p, struct rte *e, int new); + +/* Values for rte->u.krt_sync.src */ +#define KRT_SRC_UNKNOWN -1 /* Nobody knows */ +#define KRT_SRC_BIRD 0 /* Our route (not passed in async mode) */ +#define KRT_SRC_REDIRECT 1 /* Redirect route, delete it */ +#define KRT_SRC_ALIEN 2 /* Route installed by someone else */ /* krt-scan.c */ |