ping

On Mon, Dec 10, 2018 at 10:40:22AM +0100, Remi Locherer wrote:
> Hi,
> 
> below patch adds "fib-priority" to ospfd.conf which allows to set a
> custom priority to routes. 32 is still the default if not set. Changing
> the priority with a reload is also supported.
> 
> A discussion about the feature can be found here:
> https://marc.info/?l=openbsd-tech&m=138360663119816&w=2
> 
> My first idea was to add an additional parameter to the functions that
> need it. But that that is not practical since then need the event that calls
> kr_dispatch_msg() needs to be reset. Because of that I added fib_prio to 
> struct kr_state.
> 
> 
> OK?
> 
> Remi
> 
> 
> 
> cvs diff: Diffing .
> Index: kroute.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ospfd/kroute.c,v
> retrieving revision 1.111
> diff -u -p -r1.111 kroute.c
> --- kroute.c  10 Jul 2018 11:49:04 -0000      1.111
> +++ kroute.c  9 Dec 2018 21:39:46 -0000
> @@ -45,6 +45,7 @@ struct {
>       pid_t                   pid;
>       int                     fib_sync;
>       int                     fib_serial;
> +     u_int8_t                fib_prio;
>       int                     fd;
>       struct event            ev;
>       struct event            reload;
> @@ -127,14 +128,15 @@ kif_init(void)
>  }
>  
>  int
> -kr_init(int fs, u_int rdomain, int redis_label_or_prefix)
> +kr_init(int fs, u_int rdomain, int redis_label_or_prefix, u_int8_t fib_prio)
>  {
>       int             opt = 0, rcvbuf, default_rcvbuf;
>       socklen_t       optlen;
> -     int             filter_prio = RTP_OSPF;
> +     int             filter_prio = fib_prio;
>  
>       kr_state.fib_sync = fs;
>       kr_state.rdomain = rdomain;
> +     kr_state.fib_prio = fib_prio;
>  
>       if ((kr_state.fd = socket(AF_ROUTE,
>           SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, AF_INET)) == -1) {
> @@ -262,7 +264,7 @@ kr_change_fib(struct kroute_node *kr, st
>               kn->r.prefixlen = kroute[i].prefixlen;
>               kn->r.nexthop.s_addr = kroute[i].nexthop.s_addr;
>               kn->r.flags = kroute[i].flags | F_OSPFD_INSERTED;
> -             kn->r.priority = RTP_OSPF;
> +             kn->r.priority = kr_state.fib_prio;
>               kn->r.ext_tag = kroute[i].ext_tag;
>               rtlabel_unref(kn->r.rtlabel);   /* for RTM_CHANGE */
>               kn->r.rtlabel = kroute[i].rtlabel;
> @@ -286,7 +288,8 @@ kr_change(struct kroute *kroute, int krc
>  
>       kroute->rtlabel = rtlabel_tag2id(kroute->ext_tag);
>  
> -     kr = kroute_find(kroute->prefix.s_addr, kroute->prefixlen, RTP_OSPF);
> +     kr = kroute_find(kroute->prefix.s_addr, kroute->prefixlen,
> +         kr_state.fib_prio);
>       if (kr != NULL && kr->next == NULL && krcount == 1)
>               /* single path OSPF route */
>               action = RTM_CHANGE;
> @@ -297,7 +300,7 @@ kr_change(struct kroute *kroute, int krc
>  int
>  kr_delete_fib(struct kroute_node *kr)
>  {
> -     if (kr->r.priority != RTP_OSPF)
> +     if (kr->r.priority != kr_state.fib_prio)
>               log_warn("kr_delete_fib: %s/%d has wrong priority %d",
>                   inet_ntoa(kr->r.prefix), kr->r.prefixlen, kr->r.priority);
>  
> @@ -316,7 +319,7 @@ kr_delete(struct kroute *kroute)
>       struct kroute_node      *kr, *nkr;
>  
>       if ((kr = kroute_find(kroute->prefix.s_addr, kroute->prefixlen,
> -         RTP_OSPF)) == NULL)
> +         kr_state.fib_prio)) == NULL)
>               return (0);
>  
>       while (kr != NULL) {
> @@ -348,7 +351,7 @@ kr_fib_couple(void)
>       kr_state.fib_sync = 1;
>  
>       RB_FOREACH(kr, kroute_tree, &krt)
> -             if (kr->r.priority == RTP_OSPF)
> +             if (kr->r.priority == kr_state.fib_prio)
>                       for (kn = kr; kn != NULL; kn = kn->next)
>                               send_rtmsg(kr_state.fd, RTM_ADD, &kn->r);
>  
> @@ -365,7 +368,7 @@ kr_fib_decouple(void)
>               return;
>  
>       RB_FOREACH(kr, kroute_tree, &krt)
> -             if (kr->r.priority == RTP_OSPF)
> +             if (kr->r.priority == kr_state.fib_prio)
>                       for (kn = kr; kn != NULL; kn = kn->next)
>                               send_rtmsg(kr_state.fd, RTM_DELETE, &kn->r);
>  
> @@ -418,7 +421,7 @@ kr_fib_reload()
>                       kn = kr->next;
>  
>                       if (kr->serial != kr_state.fib_serial) {
> -                             if (kr->r.priority == RTP_OSPF) {
> +                             if (kr->r.priority == kr_state.fib_prio) {
>                                       kr->serial = kr_state.fib_serial;
>                                       if (send_rtmsg(kr_state.fd,
>                                           RTM_ADD, &kr->r) != 0)
> @@ -431,6 +434,21 @@ kr_fib_reload()
>       }
>  }
>  
> +void
> +kr_fib_update_prio(u_int8_t fib_prio)
> +{
> +     struct kroute_node      *kr;
> +
> +     RB_FOREACH(kr, kroute_tree, &krt)
> +             if ((kr->r.flags & F_OSPFD_INSERTED))
> +                     kr->r.priority = fib_prio;
> +
> +     log_info("fib priority changed from %hhu to %hhu",
> +         kr_state.fib_prio, fib_prio);
> +
> +     kr_state.fib_prio = fib_prio;
> + }
> +
>  /* ARGSUSED */
>  void
>  kr_dispatch_msg(int fd, short event, void *bula)
> @@ -618,7 +636,7 @@ kr_reload(int redis_label_or_prefix)
>       struct kroute_node      *kr, *kn;
>       u_int32_t                dummy;
>       int                      r;
> -     int                      filter_prio = RTP_OSPF;
> +     int                      filter_prio = kr_state.fib_prio;
>  
>       /* update the priority filter */
>       if (redis_label_or_prefix) {
> @@ -1173,7 +1191,7 @@ send_rtmsg(int fd, int action, struct kr
>       bzero(&hdr, sizeof(hdr));
>       hdr.rtm_version = RTM_VERSION;
>       hdr.rtm_type = action;
> -     hdr.rtm_priority = RTP_OSPF;
> +     hdr.rtm_priority = kr_state.fib_prio;
>       hdr.rtm_tableid = kr_state.rdomain;     /* rtableid */
>       if (action == RTM_CHANGE)
>               hdr.rtm_fmask = RTF_REJECT|RTF_BLACKHOLE;
> @@ -1414,7 +1432,7 @@ rtmsg_process(char *buf, size_t len)
>                       if (rtm->rtm_flags & RTF_MPATH)
>                               mpath = 1;
>                       prio = rtm->rtm_priority;
> -                     flags = (prio == RTP_OSPF) ?
> +                     flags = (prio == kr_state.fib_prio) ?
>                           F_OSPFD_INSERTED : F_KERNEL;
>  
>                       switch (sa->sa_family) {
> @@ -1480,7 +1498,7 @@ rtmsg_process(char *buf, size_t len)
>                           != NULL) {
>                               /* get the correct route */
>                               kr = okr;
> -                             if ((mpath || prio == RTP_OSPF) &&
> +                             if ((mpath || prio == kr_state.fib_prio) &&
>                                   (kr = kroute_matchgw(okr, nexthop)) ==
>                                   NULL) {
>                                       log_warnx("dispatch_rtmsg "
> @@ -1529,7 +1547,7 @@ add:
>                               kr->r.ifindex = ifindex;
>                               kr->r.priority = prio;
>  
> -                             if (rtm->rtm_priority == RTP_OSPF) {
> +                             if (rtm->rtm_priority == kr_state.fib_prio) {
>                                       log_warnx("alien OSPF route %s/%d",
>                                           inet_ntoa(prefix), prefixlen);
>                                       rv = send_rtmsg(kr_state.fd,
> Index: ospfd.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
> retrieving revision 1.101
> diff -u -p -r1.101 ospfd.c
> --- ospfd.c   29 Oct 2018 22:13:33 -0000      1.101
> +++ ospfd.c   9 Dec 2018 21:34:03 -0000
> @@ -286,7 +286,8 @@ main(int argc, char *argv[])
>               fatal("unveil");
>  
>       if (kr_init(!(ospfd_conf->flags & OSPFD_FLAG_NO_FIB_UPDATE),
> -         ospfd_conf->rdomain, ospfd_conf->redist_label_or_prefix) == -1)
> +         ospfd_conf->rdomain, ospfd_conf->redist_label_or_prefix,
> +         ospfd_conf->fib_priority) == -1)
>               fatalx("kr_init failed");
>  
>       /* remove unneeded stuff from config */
> @@ -707,6 +708,15 @@ merge_config(struct ospfd_conf *conf, st
>                       SIMPLEQ_REMOVE_HEAD(&xconf->redist_list, entry);
>                       SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry);
>               }
> +
> +             /* adjust FIB priority if changed */
> +             if (conf->fib_priority != xconf->fib_priority) {
> +                     kr_fib_decouple();
> +                     kr_fib_update_prio(xconf->fib_priority);
> +                     conf->fib_priority = xconf->fib_priority;
> +                     kr_fib_couple();
> +             }
> +
>               goto done;
>       }
>  
> Index: ospfd.conf.5
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ospfd/ospfd.conf.5,v
> retrieving revision 1.54
> diff -u -p -r1.54 ospfd.conf.5
> --- ospfd.conf.5      27 Jul 2018 05:23:24 -0000      1.54
> +++ ospfd.conf.5      11 Nov 2018 21:40:41 -0000
> @@ -83,6 +83,11 @@ interface.
>  The only settings that can be set globally and not overruled are listed 
> below.
>  .Pp
>  .Bl -tag -width Ds -compact
> +.It Ic fib-priority Ar prio
> +Set the routing priority to
> +.Ar prio .
> +The default is 32.
> +.Pp
>  .It Xo
>  .Ic fib-update
>  .Pq Ic yes Ns | Ns Ic no
> Index: ospfd.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ospfd/ospfd.h,v
> retrieving revision 1.102
> diff -u -p -r1.102 ospfd.h
> --- ospfd.h   29 Aug 2018 08:43:17 -0000      1.102
> +++ ospfd.h   9 Dec 2018 20:54:15 -0000
> @@ -402,6 +402,7 @@ struct ospfd_conf {
>       u_int8_t                rfc1583compat;
>       u_int8_t                border;
>       u_int8_t                redistribute;
> +     u_int8_t                fib_priority;
>       u_int                   rdomain;
>       char                    *csock;
>  };
> @@ -572,13 +573,14 @@ u_int16_t        iso_cksum(void *, u_int16_t, 
>  /* kroute.c */
>  int           kif_init(void);
>  void          kif_clear(void);
> -int           kr_init(int, u_int, int);
> +int           kr_init(int, u_int, int, u_int8_t);
>  int           kr_change(struct kroute *, int);
>  int           kr_delete(struct kroute *);
>  void          kr_shutdown(void);
>  void          kr_fib_couple(void);
>  void          kr_fib_decouple(void);
>  void          kr_fib_reload(void);
> +void          kr_fib_update_prio(u_int8_t);
>  void          kr_dispatch_msg(int, short, void *);
>  void          kr_show_route(struct imsg *);
>  void          kr_ifinfo(char *, pid_t);
> Index: parse.y
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ospfd/parse.y,v
> retrieving revision 1.93
> diff -u -p -r1.93 parse.y
> --- parse.y   1 Nov 2018 00:18:44 -0000       1.93
> +++ parse.y   11 Nov 2018 22:35:00 -0000
> @@ -25,6 +25,7 @@
>  #include <sys/types.h>
>  #include <sys/socket.h>
>  #include <sys/stat.h>
> +#include <net/route.h>
>  #include <netinet/in.h>
>  #include <arpa/inet.h>
>  #include <ctype.h>
> @@ -125,8 +126,8 @@ typedef struct {
>  
>  %}
>  
> -%token       AREA INTERFACE ROUTERID FIBUPDATE REDISTRIBUTE RTLABEL RDOMAIN
> -%token       RFC1583COMPAT STUB ROUTER SPFDELAY SPFHOLDTIME EXTTAG
> +%token       AREA INTERFACE ROUTERID FIBPRIORITY FIBUPDATE REDISTRIBUTE 
> RTLABEL
> +%token       RDOMAIN RFC1583COMPAT STUB ROUTER SPFDELAY SPFHOLDTIME EXTTAG
>  %token       AUTHKEY AUTHTYPE AUTHMD AUTHMDKEYID
>  %token       METRIC PASSIVE
>  %token       HELLOINTERVAL FASTHELLOINTERVAL TRANSMITDELAY
> @@ -229,6 +230,13 @@ conf_main        : ROUTERID STRING {
>                       }
>                       free($2);
>               }
> +             | FIBPRIORITY NUMBER {
> +                     if ($2 <= RTP_NONE || $2 > RTP_MAX) {
> +                             yyerror("invalid fib-priority");
> +                             YYERROR;
> +                     }
> +                     conf->fib_priority = $2;
> +             }
>               | FIBUPDATE yesno {
>                       if ($2 == 0)
>                               conf->flags |= OSPFD_FLAG_NO_FIB_UPDATE;
> @@ -804,6 +812,7 @@ lookup(char *s)
>               {"depend",              DEPEND},
>               {"external-tag",        EXTTAG},
>               {"fast-hello-interval", FASTHELLOINTERVAL},
> +             {"fib-priority",        FIBPRIORITY},
>               {"fib-update",          FIBUPDATE},
>               {"hello-interval",      HELLOINTERVAL},
>               {"include",             INCLUDE},
> @@ -1204,6 +1213,7 @@ parse_config(char *filename, int opts)
>       conf->spf_delay = DEFAULT_SPF_DELAY;
>       conf->spf_hold_time = DEFAULT_SPF_HOLDTIME;
>       conf->spf_state = SPF_IDLE;
> +     conf->fib_priority = RTP_OSPF;
>  
>       if ((file = pushfile(filename,
>           !(conf->opts & OSPFD_OPT_NOACTION))) == NULL) {
> Index: printconf.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/ospfd/printconf.c,v
> retrieving revision 1.19
> diff -u -p -r1.19 printconf.c
> --- printconf.c       11 Jul 2018 15:41:19 -0000      1.19
> +++ printconf.c       11 Nov 2018 22:17:37 -0000
> @@ -44,6 +44,8 @@ print_mainconf(struct ospfd_conf *conf)
>       else
>               printf("fib-update yes\n");
>  
> +     printf("fib-priority %hhu\n", conf->fib_priority);
> +
>       if (conf->rdomain)
>               printf("rdomain %d\n", conf->rdomain);
>  
> 

Reply via email to