summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorSebastian Benoit <benno@cvs.openbsd.org>2018-02-11 02:26:56 +0000
committerSebastian Benoit <benno@cvs.openbsd.org>2018-02-11 02:26:56 +0000
commit8be66dc7d815621f140bc4584e7c4594c5ea8c04 (patch)
treeee511bd4cdb5e0b7a79d296b65f5dc3a5735639d /sys
parentdf8f883ccbec11aac60a2921d683bbe707f71796 (diff)
Add a ROUTE_PRIOFILTER socket option for roueing sockets that
allows filtering on the priority of the route. All routes up to the specified value will be passed. ok claudio, ok henning previous version, feedback and manpage from sthen.
Diffstat (limited to 'sys')
-rw-r--r--sys/net/route.h5
-rw-r--r--sys/net/rtsock.c22
2 files changed, 24 insertions, 3 deletions
diff --git a/sys/net/route.h b/sys/net/route.h
index 1ca0a22c45f..9f5459a9a62 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.167 2017/08/02 08:38:28 mpi Exp $ */
+/* $OpenBSD: route.h,v 1.168 2018/02/11 02:26:55 benno Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -297,6 +297,9 @@ struct rt_msghdr {
sent to the client. */
#define ROUTE_TABLEFILTER 2 /* change routing table the socket is listening
on, RTABLE_ANY listens on all tables. */
+#define ROUTE_PRIOFILTER 3 /* only pass updates with a priority higher or
+ equal (actual value lower) to the specified
+ priority. */
#define ROUTE_FILTER(m) (1 << (m))
#define RTABLE_ANY 0xffffffff
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 35bdd09d143..70497d29a93 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.260 2018/02/08 22:24:41 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.261 2018/02/11 02:26:55 benno Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -141,6 +141,7 @@ struct routecb {
unsigned int msgfilter;
unsigned int flags;
u_int rtableid;
+ u_char priority;
};
#define sotoroutecb(so) ((struct routecb *)(so)->so_pcb)
@@ -308,7 +309,7 @@ route_ctloutput(int op, struct socket *so, int level, int optname,
{
struct routecb *rop = sotoroutecb(so);
int error = 0;
- unsigned int tid;
+ unsigned int tid, prio;
if (level != AF_ROUTE)
return (EINVAL);
@@ -333,6 +334,17 @@ route_ctloutput(int op, struct socket *so, int level, int optname,
else
rop->rtableid = tid;
break;
+ case ROUTE_PRIOFILTER:
+ if (m == NULL || m->m_len != sizeof(unsigned int)) {
+ error = EINVAL;
+ break;
+ }
+ prio = *mtod(m, unsigned int *);
+ if (prio > RTP_MAX)
+ error = EINVAL;
+ else
+ rop->priority = prio;
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -348,6 +360,10 @@ route_ctloutput(int op, struct socket *so, int level, int optname,
m->m_len = sizeof(unsigned int);
*mtod(m, unsigned int *) = rop->rtableid;
break;
+ case ROUTE_PRIOFILTER:
+ m->m_len = sizeof(unsigned int);
+ *mtod(m, unsigned int *) = rop->priority;
+ break;
default:
error = ENOPROTOOPT;
break;
@@ -431,6 +447,8 @@ route_input(struct mbuf *m0, struct socket *so, sa_family_t sa_family)
if (rtm->rtm_type != RTM_DESYNC && rop->msgfilter != 0 &&
!(rop->msgfilter & (1 << rtm->rtm_type)))
continue;
+ if (rop->priority != 0 && rop->priority < rtm->rtm_priority)
+ continue;
switch (rtm->rtm_type) {
case RTM_IFANNOUNCE:
case RTM_DESYNC: