summaryrefslogtreecommitdiffstats
path: root/sysdep
diff options
context:
space:
mode:
authorOndrej Zajicek <santiago@crfreenet.org>2010-04-04 15:41:31 +0200
committerOndrej Zajicek <santiago@crfreenet.org>2010-04-04 15:41:31 +0200
commitc429d4a4ba2cc8778634461e8adea33e0f0ae022 (patch)
tree5cc8102345bf3ce872da92aca84fa63cf67c4e20 /sysdep
parentd2d2b5d2ae43f608d03304d280367b658650138b (diff)
downloadbird-c429d4a4ba2cc8778634461e8adea33e0f0ae022.tar
bird-c429d4a4ba2cc8778634461e8adea33e0f0ae022.zip
Restrict export of device routes to the kernel protocol.
In usual configuration, such export is already restricted with the aid of the direct protocol but there are some races that can circumvent it. This makes it harder to break kernel device routes. Also adds an option to disable this restriction.
Diffstat (limited to 'sysdep')
-rw-r--r--sysdep/bsd/krt-sock.c8
-rw-r--r--sysdep/linux/netlink/netlink.c10
-rw-r--r--sysdep/unix/krt.Y3
-rw-r--r--sysdep/unix/krt.c22
-rw-r--r--sysdep/unix/krt.h1
5 files changed, 27 insertions, 17 deletions
diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c
index 32c269d..d991ea1 100644
--- a/sysdep/bsd/krt-sock.c
+++ b/sysdep/bsd/krt-sock.c
@@ -40,10 +40,6 @@ krt_capable(rte *e)
{
rta *a = e->attrs;
-#ifdef CONFIG_AUTO_ROUTES
- if (a->source == RTS_DEVICE)
- return 0;
-#endif
return
a->cast == RTC_UNICAST &&
(a->dest == RTD_ROUTER
@@ -163,7 +159,7 @@ krt_sock_send(int cmd, rte *e)
#endif
if(!i->addr) {
- log(L_ERR "KIF: interface \"%s\" has no IP addess", i->name);
+ log(L_ERR "KRT: interface %s has no IP addess", i->name);
return;
}
@@ -185,7 +181,7 @@ krt_sock_send(int cmd, rte *e)
msg.rtm.rtm_msglen = l;
if ((l = write(rt_sock, (char *)&msg, l)) < 0) {
- log(L_ERR "KIF: Error sending route %I/%d to kernel", net->n.prefix, net->n.pxlen);
+ log(L_ERR "KRT: Error sending route %I/%d to kernel", net->n.prefix, net->n.pxlen);
}
}
diff --git a/sysdep/linux/netlink/netlink.c b/sysdep/linux/netlink/netlink.c
index b59b32f..f31ef9f 100644
--- a/sysdep/linux/netlink/netlink.c
+++ b/sysdep/linux/netlink/netlink.c
@@ -460,20 +460,14 @@ krt_capable(rte *e)
{
rta *a = e->attrs;
- if (a->cast != RTC_UNICAST
-#if 0
- && a->cast != RTC_ANYCAST
-#endif
- )
- return 0;
- if (a->source == RTS_DEVICE) /* Kernel takes care of device routes itself */
+ if (a->cast != RTC_UNICAST)
return 0;
+
switch (a->dest)
{
case RTD_ROUTER:
if (ipa_has_link_scope(a->gw) && (a->iface == NULL))
return 0;
-
case RTD_DEVICE:
case RTD_BLACKHOLE:
case RTD_UNREACHABLE:
diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y
index 40f1af9..0375a13 100644
--- a/sysdep/unix/krt.Y
+++ b/sysdep/unix/krt.Y
@@ -17,7 +17,7 @@ CF_DEFINES
CF_DECLS
-CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE)
+CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES)
CF_GRAMMAR
@@ -56,6 +56,7 @@ kern_item:
cf_error("Learning of kernel routes not supported in this configuration");
#endif
}
+ | DEVICE ROUTES bool { THIS_KRT->devroutes = $3; }
;
/* Kernel interface protocol */
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index c8887b7..419bdd9 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -734,6 +734,25 @@ krt_scan(timer *t UNUSED)
/*
* Updates
*/
+static int
+krt_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool *pool)
+{
+ struct krt_proto *p = (struct krt_proto *) P;
+ rte *e = *new;
+
+ if (e->attrs->proto == P)
+ return -1;
+
+ if (!KRT_CF->devroutes &&
+ (e->attrs->dest == RTD_DEVICE) &&
+ (e->attrs->source != RTS_STATIC_DEVICE))
+ return -1;
+
+ if (!krt_capable(e))
+ return -1;
+
+ return 0;
+}
static void
krt_notify(struct proto *P, struct rtable *table UNUSED, net *net,
@@ -743,8 +762,6 @@ krt_notify(struct proto *P, struct rtable *table UNUSED, net *net,
if (shutting_down)
return;
- if (new && (!krt_capable(new) || new->attrs->source == RTS_INHERIT))
- new = NULL;
if (!(net->n.flags & KRF_INSTALLED))
old = NULL;
if (new)
@@ -871,6 +888,7 @@ krt_init(struct proto_config *c)
struct krt_proto *p = proto_new(c, sizeof(struct krt_proto));
p->p.accept_ra_types = RA_OPTIMAL;
+ p->p.import_control = krt_import_control;
p->p.rt_notify = krt_notify;
return &p->p;
}
diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h
index 1d9e144..ed61621 100644
--- a/sysdep/unix/krt.h
+++ b/sysdep/unix/krt.h
@@ -47,6 +47,7 @@ struct krt_config {
int persist; /* Keep routes when we exit */
int scan_time; /* How often we re-scan routes */
int learn; /* Learn routes from other sources */
+ int devroutes; /* Allow export of device routes */
};
struct krt_proto {