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