diff options
author | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2020-08-13 04:58:23 +0000 |
---|---|---|
committer | Jonathan Matthew <jmatthew@cvs.openbsd.org> | 2020-08-13 04:58:23 +0000 |
commit | 64bbc8e322d6caafd2b0373cfe0eb463698155f9 (patch) | |
tree | d9533faed5f69f2ce2eaa94c9915bf0eddd90c7f | |
parent | f620df6caf35c1a822d11eb62c35f8cd0ee83878 (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.h | 4 | ||||
-rw-r--r-- | sys/net/rtsock.c | 23 |
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: |