Add a ROUTE_PRIOFILTER socket option for roueing sockets that
authorbenno <benno@openbsd.org>
Sun, 11 Feb 2018 02:26:55 +0000 (02:26 +0000)
committerbenno <benno@openbsd.org>
Sun, 11 Feb 2018 02:26:55 +0000 (02:26 +0000)
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.

share/man/man4/route.4
sys/net/route.h
sys/net/rtsock.c

index 654b9a1..7051c42 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: route.4,v 1.44 2018/01/12 04:36:44 deraadt Exp $
+.\"    $OpenBSD: route.4,v 1.45 2018/02/11 02:26:55 benno Exp $
 .\"    $NetBSD: route.4,v 1.3 1994/11/30 16:22:31 jtc Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
@@ -30,7 +30,7 @@
 .\"
 .\"     @(#)route.4    8.6 (Berkeley) 4/19/94
 .\"
-.Dd $Mdocdate: January 12 2018 $
+.Dd $Mdocdate: February 11 2018 $
 .Dt ROUTE 4
 .Os
 .Sh NAME
@@ -210,6 +210,41 @@ if (setsockopt(routefd, PF_ROUTE, ROUTE_MSGFILTER,
        err(1, "setsockopt(ROUTE_MSGFILTER)");
 .Ed
 .Pp
+Similarly, a process can specify that it is only interested in messages
+relating to routes where the priority is no more than a certain value
+by issuing a setsockopt call with the
+.Dv ROUTE_PRIOFILTER
+option.
+For example, to select only local, directly connected and static routes:
+.Bd -literal -offset indent
+unsigned int maxprio = RTP_STATIC;
+
+if (setsockopt(routefd, PF_ROUTE, ROUTE_PRIOFILTER,
+    &maxprio, sizeof(maxprio)) == -1)
+       err(1, "setsockopt(ROUTE_PRIOFILTER)");
+.Ed
+.Pp
+The predefined constants for the routing priorities are:
+.Bd -literal
+#define RTP_NONE       0       /* unset priority use sane default */
+#define RTP_LOCAL      1       /* local address routes (must be the highest) */
+#define RTP_CONNECTED  4       /* directly connected routes */
+#define RTP_STATIC     8       /* static routes base priority */
+#define RTP_EIGRP      28      /* EIGRP routes */
+#define RTP_OSPF       32      /* OSPF routes */
+#define RTP_ISIS       36      /* IS-IS routes */
+#define RTP_RIP                40      /* RIP routes */
+#define RTP_BGP                48      /* BGP routes */
+#define RTP_DEFAULT    56      /* routes that have nothing set */
+#define RTP_PROPOSAL_STATIC    57
+#define RTP_PROPOSAL_DHCLIENT  58
+#define RTP_PROPOSAL_SLAAC     59
+#define RTP_MAX                63      /* maximum priority */
+#define RTP_ANY                64      /* any of the above */
+#define RTP_MASK       0x7f
+#define RTP_DOWN       0x80    /* route/link is down */
+.Ed
+.Pp
 If a route is in use when it is deleted,
 the routing entry will be marked down and removed from the routing table,
 but the resources associated with it will not
index 1ca0a22..9f5459a 100644 (file)
@@ -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
index 35bdd09..70497d2 100644 (file)
@@ -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: