summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Matthew <jmatthew@cvs.openbsd.org>2020-08-13 04:58:23 +0000
committerJonathan Matthew <jmatthew@cvs.openbsd.org>2020-08-13 04:58:23 +0000
commit64bbc8e322d6caafd2b0373cfe0eb463698155f9 (patch)
treed9533faed5f69f2ce2eaa94c9915bf0eddd90c7f
parentf620df6caf35c1a822d11eb62c35f8cd0ee83878 (diff)
Add a ROUTE_FLAGFILTER socket option for routing sockets, allowing
filtering out messages for routes with flags matching any bit in a mask. This allows routing daemons to opt out of receiving messages for L2 and broadcast route entries, which they currently discard. ok dlg@ sthen@ deraadt@
-rw-r--r--sys/net/route.h4
-rw-r--r--sys/net/rtsock.c23
2 files changed, 22 insertions, 5 deletions
diff --git a/sys/net/route.h b/sys/net/route.h
index 0f78a4c36d4..25e486cabf4 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.181 2020/03/10 21:35:41 krw Exp $ */
+/* $OpenBSD: route.h,v 1.182 2020/08/13 04:58:22 jmatthew Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -297,6 +297,8 @@ struct rt_msghdr {
#define ROUTE_PRIOFILTER 3 /* only pass updates with a priority higher or
equal (actual value lower) to the specified
priority. */
+#define ROUTE_FLAGFILTER 4 /* do not pass updates for routes with flags
+ in this bitmask. */
#define ROUTE_FILTER(m) (1 << (m))
#define RTABLE_ANY 0xffffffff
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 9d4ccadd4e2..fa84ddc25e5 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.299 2020/06/24 22:03:42 cheloha Exp $ */
+/* $OpenBSD: rtsock.c,v 1.300 2020/08/13 04:58:22 jmatthew Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -145,6 +145,7 @@ struct rtpcb {
struct refcnt rop_refcnt;
struct timeout rop_timeout;
unsigned int rop_msgfilter;
+ unsigned int rop_flagfilter;
unsigned int rop_flags;
u_int rop_rtableid;
unsigned short rop_proto;
@@ -402,6 +403,12 @@ route_ctloutput(int op, struct socket *so, int level, int optname,
else
rop->rop_priority = prio;
break;
+ case ROUTE_FLAGFILTER:
+ if (m == NULL || m->m_len != sizeof(unsigned int))
+ error = EINVAL;
+ else
+ rop->rop_flagfilter = *mtod(m, unsigned int *);
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -421,6 +428,10 @@ route_ctloutput(int op, struct socket *so, int level, int optname,
m->m_len = sizeof(unsigned int);
*mtod(m, unsigned int *) = rop->rop_priority;
break;
+ case ROUTE_FLAGFILTER:
+ m->m_len = sizeof(unsigned int);
+ *mtod(m, unsigned int *) = rop->rop_flagfilter;
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -516,9 +527,13 @@ next:
/* filter messages that the process does not want */
rtm = mtod(m, struct rt_msghdr *);
/* but RTM_DESYNC can't be filtered */
- if (rtm->rtm_type != RTM_DESYNC && rop->rop_msgfilter != 0 &&
- !(rop->rop_msgfilter & (1 << rtm->rtm_type)))
- goto next;
+ if (rtm->rtm_type != RTM_DESYNC) {
+ if (rop->rop_msgfilter != 0 &&
+ !(rop->rop_msgfilter & (1 << rtm->rtm_type)))
+ goto next;
+ if (ISSET(rop->rop_flagfilter, rtm->rtm_flags))
+ goto next;
+ }
switch (rtm->rtm_type) {
case RTM_IFANNOUNCE:
case RTM_DESYNC: