diff options
author | Martin Mares <mj@ucw.cz> | 1999-03-04 18:36:18 +0000 |
---|---|---|
committer | Martin Mares <mj@ucw.cz> | 1999-03-04 18:36:18 +0000 |
commit | e16155ae4aaee5d9ba7b6940f8312b36707718e4 (patch) | |
tree | de2bbd930af01a8620871688e8ba36ba9d0111be /sysdep/unix/krt.c | |
parent | 2253c9e239253d2094b4b1cabd97d296af885afb (diff) |
KRT: Implemented asynchronous route / interface state notifications
(via Netlink). Tweaked kernel synchronization rules a bit. Discovered
locking bug in kernel Netlink :-)
Future plans: Hunt all the bugs and solve all the FIXME's.
Diffstat (limited to 'sysdep/unix/krt.c')
-rw-r--r-- | sysdep/unix/krt.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 5fbd52c7..aa875ccf 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 */ |