route socket filter on priority

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

route socket filter on priority

Sebastian Benoit-3


- add ROUTE_PRIOFILTER
- it has one argument that is interpreted as a route priority
- all route updates with prio lower or equal will pass the filter,
  all with higher priority value will be filtered.
- example use in ospfd

comments/oks?

(benno_ospfd_route_priofilter_1.diff)

diff --git sys/net/route.h sys/net/route.h
index 1ca0a22c45f..7a4008b7ac1 100644
--- sys/net/route.h
+++ sys/net/route.h
@@ -298,6 +298,9 @@ struct rt_msghdr {
 #define ROUTE_TABLEFILTER 2 /* change routing table the socket is listening
    on, RTABLE_ANY listens on all tables. */
 
+#define ROUTE_PRIOFILTER 3 /* change routing table the socket is listening
+   on, RTABLE_ANY listens on all tables. */
+
 #define ROUTE_FILTER(m) (1 << (m))
 #define RTABLE_ANY 0xffffffff
 
diff --git sys/net/rtsock.c sys/net/rtsock.c
index 35bdd09d143..5f4244e6057 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)
 
@@ -309,6 +310,7 @@ route_ctloutput(int op, struct socket *so, int level, int optname,
  struct routecb *rop = sotoroutecb(so);
  int error = 0;
  unsigned int tid;
+ u_char prio;
 
  if (level != AF_ROUTE)
  return (EINVAL);
@@ -333,6 +335,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(u_char)) {
+ error = EINVAL;
+ break;
+ }
+ prio = *mtod(m, u_char *);
+ if (prio > RTP_MAX)
+ error = EINVAL;
+ else
+ rop->priority = prio;
+ break;
  default:
  error = ENOPROTOOPT;
  break;
@@ -348,6 +361,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 +448,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:
diff --git usr.sbin/ospfd/kroute.c usr.sbin/ospfd/kroute.c
index 17febefbdcb..a5c069aa540 100644
--- usr.sbin/ospfd/kroute.c
+++ usr.sbin/ospfd/kroute.c
@@ -127,10 +127,11 @@ kif_init(void)
 }
 
 int
-kr_init(int fs, u_int rdomain)
+kr_init(int fs, u_int rdomain, u_int8_t redis_label_or_prefix)
 {
  int opt = 0, rcvbuf, default_rcvbuf;
  socklen_t optlen;
+ u_char filter_prio = RTP_OSPF;
 
  kr_state.fib_sync = fs;
  kr_state.rdomain = rdomain;
@@ -146,6 +147,14 @@ kr_init(int fs, u_int rdomain)
     &opt, sizeof(opt)) == -1)
  log_warn("kr_init: setsockopt"); /* not fatal */
 
+ if (redis_label_or_prefix)
+ filter_prio = 0;
+ if (setsockopt(kr_state.fd, AF_ROUTE, ROUTE_PRIOFILTER, &filter_prio,
+    sizeof(filter_prio)) == -1) {
+ log_warn("%s: setsockopt AF_ROUTE ROUTE_PRIOFILTER", __func__);
+ return (-1);
+ }
+
  /* grow receive buffer, don't wanna miss messages */
  optlen = sizeof(default_rcvbuf);
  if (getsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF,
diff --git usr.sbin/ospfd/ospfd.c usr.sbin/ospfd/ospfd.c
index 3c5057ae04e..0e91819f673 100644
--- usr.sbin/ospfd/ospfd.c
+++ usr.sbin/ospfd/ospfd.c
@@ -265,7 +265,7 @@ main(int argc, char *argv[])
  event_add(&iev_rde->ev, NULL);
 
  if (kr_init(!(ospfd_conf->flags & OSPFD_FLAG_NO_FIB_UPDATE),
-    ospfd_conf->rdomain) == -1)
+    ospfd_conf->rdomain, ospfd_conf->redist_label_or_prefix) == -1)
  fatalx("kr_init failed");
 
  /* remove unneeded stuff from config */
diff --git usr.sbin/ospfd/ospfd.h usr.sbin/ospfd/ospfd.h
index af082b1079c..ca66511228a 100644
--- usr.sbin/ospfd/ospfd.h
+++ usr.sbin/ospfd/ospfd.h
@@ -397,6 +397,7 @@ struct ospfd_conf {
  u_int8_t rfc1583compat;
  u_int8_t border;
  u_int8_t redistribute;
+ u_int8_t redist_label_or_prefix;
  u_int rdomain;
  char *csock;
 };
@@ -567,7 +568,7 @@ u_int16_t iso_cksum(void *, u_int16_t, u_int16_t);
 /* kroute.c */
 int kif_init(void);
 void kif_clear(void);
-int kr_init(int, u_int);
+int kr_init(int, u_int, u_int8_t);
 int kr_change(struct kroute *, int);
 int kr_delete(struct kroute *);
 void kr_shutdown(void);
diff --git usr.sbin/ospfd/parse.y usr.sbin/ospfd/parse.y
index 4bf64d5d7e3..deb93cc6524 100644
--- usr.sbin/ospfd/parse.y
+++ usr.sbin/ospfd/parse.y
@@ -302,6 +302,7 @@ redistribute : no REDISTRIBUTE NUMBER '/' NUMBER optlist dependon {
  r->dependon[0] = '\0';
  free($7);
  $$ = r;
+ conf->redist_label_or_prefix = 1;
  }
  | no REDISTRIBUTE STRING optlist dependon {
  struct redistribute *r;
@@ -314,9 +315,10 @@ redistribute : no REDISTRIBUTE NUMBER '/' NUMBER optlist dependon {
  r->type = REDIST_STATIC;
  else if (!strcmp($3, "connected"))
  r->type = REDIST_CONNECTED;
- else if (host($3, &r->addr, &r->mask))
+ else if (host($3, &r->addr, &r->mask)) {
  r->type = REDIST_ADDR;
- else {
+ conf->redist_label_or_prefix = (!$1);
+ } else {
  yyerror("unknown redistribute type");
  free($3);
  free(r);
@@ -343,6 +345,8 @@ redistribute : no REDISTRIBUTE NUMBER '/' NUMBER optlist dependon {
  r->label = rtlabel_name2id($4);
  if ($1)
  r->type |= REDIST_NO;
+ else
+ conf->redist_label_or_prefix = 1;
  r->metric = $5;
  if ($6)
  strlcpy(r->dependon, $6, sizeof(r->dependon));

Reply | Threaded
Open this post in threaded view
|

Re: route socket filter on priority

Tom Smyth
Nice feature
lots of real world use cases.


On 10 Feb 2018 9:19 AM, "Sebastian Benoit" <[hidden email]> wrote:

>
>
> - add ROUTE_PRIOFILTER
> - it has one argument that is interpreted as a route priority
> - all route updates with prio lower or equal will pass the filter,
>   all with higher priority value will be filtered.
> - example use in ospfd
>
> comments/oks?
>
> (benno_ospfd_route_priofilter_1.diff)
>
> diff --git sys/net/route.h sys/net/route.h
> index 1ca0a22c45f..7a4008b7ac1 100644
> --- sys/net/route.h
> +++ sys/net/route.h
> @@ -298,6 +298,9 @@ struct rt_msghdr {
>  #define ROUTE_TABLEFILTER 2    /* change routing table the socket is
> listening
>                                    on, RTABLE_ANY listens on all tables. */
>
> +#define ROUTE_PRIOFILTER 3     /* change routing table the socket is
> listening
> +                                  on, RTABLE_ANY listens on all tables. */
> +
>  #define ROUTE_FILTER(m)        (1 << (m))
>  #define RTABLE_ANY     0xffffffff
>
> diff --git sys/net/rtsock.c sys/net/rtsock.c
> index 35bdd09d143..5f4244e6057 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)
>
> @@ -309,6 +310,7 @@ route_ctloutput(int op, struct socket *so, int level,
> int optname,
>         struct routecb *rop = sotoroutecb(so);
>         int error = 0;
>         unsigned int tid;
> +       u_char prio;
>
>         if (level != AF_ROUTE)
>                 return (EINVAL);
> @@ -333,6 +335,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(u_char)) {
> +                               error = EINVAL;
> +                               break;
> +                       }
> +                       prio = *mtod(m, u_char *);
> +                       if (prio > RTP_MAX)
> +                               error = EINVAL;
> +                       else
> +                               rop->priority = prio;
> +                       break;
>                 default:
>                         error = ENOPROTOOPT;
>                         break;
> @@ -348,6 +361,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 +448,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:
> diff --git usr.sbin/ospfd/kroute.c usr.sbin/ospfd/kroute.c
> index 17febefbdcb..a5c069aa540 100644
> --- usr.sbin/ospfd/kroute.c
> +++ usr.sbin/ospfd/kroute.c
> @@ -127,10 +127,11 @@ kif_init(void)
>  }
>
>  int
> -kr_init(int fs, u_int rdomain)
> +kr_init(int fs, u_int rdomain, u_int8_t redis_label_or_prefix)
>  {
>         int             opt = 0, rcvbuf, default_rcvbuf;
>         socklen_t       optlen;
> +       u_char          filter_prio = RTP_OSPF;
>
>         kr_state.fib_sync = fs;
>         kr_state.rdomain = rdomain;
> @@ -146,6 +147,14 @@ kr_init(int fs, u_int rdomain)
>             &opt, sizeof(opt)) == -1)
>                 log_warn("kr_init: setsockopt");        /* not fatal */
>
> +       if (redis_label_or_prefix)
> +               filter_prio = 0;
> +       if (setsockopt(kr_state.fd, AF_ROUTE, ROUTE_PRIOFILTER,
> &filter_prio,
> +           sizeof(filter_prio)) == -1) {
> +               log_warn("%s: setsockopt AF_ROUTE ROUTE_PRIOFILTER",
> __func__);
> +               return (-1);
> +       }
> +
>         /* grow receive buffer, don't wanna miss messages */
>         optlen = sizeof(default_rcvbuf);
>         if (getsockopt(kr_state.fd, SOL_SOCKET, SO_RCVBUF,
> diff --git usr.sbin/ospfd/ospfd.c usr.sbin/ospfd/ospfd.c
> index 3c5057ae04e..0e91819f673 100644
> --- usr.sbin/ospfd/ospfd.c
> +++ usr.sbin/ospfd/ospfd.c
> @@ -265,7 +265,7 @@ main(int argc, char *argv[])
>         event_add(&iev_rde->ev, NULL);
>
>         if (kr_init(!(ospfd_conf->flags & OSPFD_FLAG_NO_FIB_UPDATE),
> -           ospfd_conf->rdomain) == -1)
> +           ospfd_conf->rdomain, ospfd_conf->redist_label_or_prefix) ==
> -1)
>                 fatalx("kr_init failed");
>
>         /* remove unneeded stuff from config */
> diff --git usr.sbin/ospfd/ospfd.h usr.sbin/ospfd/ospfd.h
> index af082b1079c..ca66511228a 100644
> --- usr.sbin/ospfd/ospfd.h
> +++ usr.sbin/ospfd/ospfd.h
> @@ -397,6 +397,7 @@ struct ospfd_conf {
>         u_int8_t                rfc1583compat;
>         u_int8_t                border;
>         u_int8_t                redistribute;
> +       u_int8_t                redist_label_or_prefix;
>         u_int                   rdomain;
>         char                    *csock;
>  };
> @@ -567,7 +568,7 @@ u_int16_t    iso_cksum(void *, u_int16_t, u_int16_t);
>  /* kroute.c */
>  int             kif_init(void);
>  void            kif_clear(void);
> -int             kr_init(int, u_int);
> +int             kr_init(int, u_int, u_int8_t);
>  int             kr_change(struct kroute *, int);
>  int             kr_delete(struct kroute *);
>  void            kr_shutdown(void);
> diff --git usr.sbin/ospfd/parse.y usr.sbin/ospfd/parse.y
> index 4bf64d5d7e3..deb93cc6524 100644
> --- usr.sbin/ospfd/parse.y
> +++ usr.sbin/ospfd/parse.y
> @@ -302,6 +302,7 @@ redistribute        : no REDISTRIBUTE NUMBER '/'
> NUMBER optlist dependon {
>                                 r->dependon[0] = '\0';
>                         free($7);
>                         $$ = r;
> +                       conf->redist_label_or_prefix = 1;
>                 }
>                 | no REDISTRIBUTE STRING optlist dependon {
>                         struct redistribute     *r;
> @@ -314,9 +315,10 @@ redistribute       : no REDISTRIBUTE NUMBER '/'
> NUMBER optlist dependon {
>                                 r->type = REDIST_STATIC;
>                         else if (!strcmp($3, "connected"))
>                                 r->type = REDIST_CONNECTED;
> -                       else if (host($3, &r->addr, &r->mask))
> +                       else if (host($3, &r->addr, &r->mask)) {
>                                 r->type = REDIST_ADDR;
> -                       else {
> +                               conf->redist_label_or_prefix = (!$1);
> +                       } else {
>                                 yyerror("unknown redistribute type");
>                                 free($3);
>                                 free(r);
> @@ -343,6 +345,8 @@ redistribute        : no REDISTRIBUTE NUMBER '/'
> NUMBER optlist dependon {
>                         r->label = rtlabel_name2id($4);
>                         if ($1)
>                                 r->type |= REDIST_NO;
> +                       else
> +                               conf->redist_label_or_prefix = 1;
>                         r->metric = $5;
>                         if ($6)
>                                 strlcpy(r->dependon, $6,
> sizeof(r->dependon));
>
>
Reply | Threaded
Open this post in threaded view
|

Re: route socket filter on priority

Stuart Henderson
In reply to this post by Sebastian Benoit-3
On 2018/02/10 10:12, Sebastian Benoit wrote:

>
>
> - add ROUTE_PRIOFILTER
> - it has one argument that is interpreted as a route priority
> - all route updates with prio lower or equal will pass the filter,
>   all with higher priority value will be filtered.
> - example use in ospfd
>
> comments/oks?
>
> (benno_ospfd_route_priofilter_1.diff)
>
> diff --git sys/net/route.h sys/net/route.h
> index 1ca0a22c45f..7a4008b7ac1 100644
> --- sys/net/route.h
> +++ sys/net/route.h
> @@ -298,6 +298,9 @@ struct rt_msghdr {
>  #define ROUTE_TABLEFILTER 2 /* change routing table the socket is listening
>     on, RTABLE_ANY listens on all tables. */
>  
> +#define ROUTE_PRIOFILTER 3 /* change routing table the socket is listening
> +   on, RTABLE_ANY listens on all tables. */
> +

This comment needs fixing or removing, otherwise ok.
Feel free to use this accompanying manpage diff.

Index: route.4
===================================================================
RCS file: /cvs/src/share/man/man4/route.4,v
retrieving revision 1.44
diff -u -p -r1.44 route.4
--- route.4 12 Jan 2018 04:36:44 -0000 1.44
+++ route.4 10 Feb 2018 10:39:08 -0000
@@ -210,6 +210,20 @@ if (setsockopt(routefd, PF_ROUTE, ROUTE_
  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 static, directly connected and local routes:
+.Bd -literal -offset indent
+u_char maxprio;
+
+if (setsockopt(routefd, PF_ROUTE, ROUTE_PRIOFILTER,
+    &maxprio, sizeof(maxprio)) == -1)
+ err(1, "setsockopt(ROUTE_PRIOFILTER)");
+.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

Reply | Threaded
Open this post in threaded view
|

Re: route socket filter on priority

Sebastian Benoit-3
Stuart Henderson([hidden email]) 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 | Threaded
Open this post in threaded view
|

Re: route socket filter on priority

Claudio Jeker-3
On Sun, Feb 11, 2018 at 02:14:32AM +0100, Sebastian Benoit wrote:

> Stuart Henderson([hidden email]) 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?
>

Comments inline

> (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;

The types here need to be changed to unsigned int as well.

>   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:

Apart from that OK claudio@
--
:wq Claudio