Stuart Henderson([email protected]) on 2018.02.10 10:41:11 +0000:
> This comment needs fixing or removing, otherwise ok.
> Feel free to use this accompanying manpage diff.

Hi sthen, thanks

updated diff,this is only the kernel part + manpage.
I added the RTP constants to the manpage, as all the other ones are there as
well.
The other change is to move from u_char to unsinged int, because the other
socket options are unsinged int as well.

i will send the ospfd diff as seperate mail.

ok?

(benno_route_priofilter_2_kernel.diff)

diff --git share/man/man4/route.4 share/man/man4/route.4
index 654b9a1505a..4e5d26724e6 100644
--- share/man/man4/route.4
+++ share/man/man4/route.4
@@ -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
diff --git sys/net/route.h sys/net/route.h
index 1ca0a22c45f..b27d42bd555 100644
--- sys/net/route.h
+++ sys/net/route.h
@@ -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 sys/net/rtsock.c sys/net/rtsock.c
index 35bdd09d143..09c622840aa 100644
--- sys/net/rtsock.c
+++ sys/net/rtsock.c
@@ -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(u_char);
+                       *mtod(m, u_char *) = 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:

Reply via email to