mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
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.
This commit is contained in:
@@ -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)
|
||||
|
@@ -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
|
||||
*/
|
||||
|
@@ -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 */
|
||||
|
||||
|
Reference in New Issue
Block a user