Hi all, sorry for to be late, but here is my ospfd patch for setting custom routing priorities on ospfd (based on 5.4 sources)
My parse.y is more precise than Florian's, it allows priorities greater than static routes (RTP_STATIC) and lower than RTP_MAX (63). Also, when /etc/rc.d/ospfd reload is launched, fib is decouples, priority changed and fib recoupled. It works nearly perfect. The only missing point is that "ospfctl sh fib" shows both fib with old and new prio (but real routing table only has new fib priority). --- ../OpenBSD54/usr.sbin/ospfd/kroute.c 2013-07-07 18:26:04.000000000 +0200 +++ ospfd/kroute.c 2013-11-07 17:26:58.395763302 +0100 @@ -254,7 +254,7 @@ 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 = get_conf()->fib_priority; kn->r.ext_tag = kroute[i].ext_tag; rtlabel_unref(kn->r.rtlabel); /* for RTM_CHANGE */ kn->r.rtlabel = kroute[i].rtlabel; @@ -278,7 +278,7 @@ 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, get_conf()->fib_priority); if (kr != NULL && kr->next == NULL && krcount == 1) /* single path OSPF route */ action = RTM_CHANGE; @@ -289,7 +289,7 @@ int kr_delete_fib(struct kroute_node *kr) { - if (kr->r.priority != RTP_OSPF) + if (kr->r.priority != get_conf()->fib_priority) log_warn("kr_delete_fib: %s/%d has wrong priority %d", inet_ntoa(kr->r.prefix), kr->r.prefixlen, kr->r.priority); @@ -308,7 +308,7 @@ struct kroute_node *kr, *nkr; if ((kr = kroute_find(kroute->prefix.s_addr, kroute->prefixlen, - RTP_OSPF)) == NULL) + get_conf()->fib_priority)) == NULL) return (0); while (kr != NULL) { @@ -340,7 +340,7 @@ kr_state.fib_sync = 1; RB_FOREACH(kr, kroute_tree, &krt) - if (kr->r.priority == RTP_OSPF) + if (kr->r.priority == get_conf()->fib_priority) for (kn = kr; kn != NULL; kn = kn->next) send_rtmsg(kr_state.fd, RTM_ADD, &kn->r); @@ -357,7 +357,7 @@ return; RB_FOREACH(kr, kroute_tree, &krt) - if (kr->r.priority == RTP_OSPF) + if (kr->r.priority == get_conf()->fib_priority) for (kn = kr; kn != NULL; kn = kn->next) send_rtmsg(kr_state.fd, RTM_DELETE, &kn->r); @@ -410,7 +410,7 @@ kn = kr->next; if (kr->serial != kr_state.fib_serial) { - if (kr->r.priority == RTP_OSPF) { + if (kr->r.priority == get_conf()->fib_priority) { kr->serial = kr_state.fib_serial; if (send_rtmsg(kr_state.fd, RTM_ADD, &kr->r) != 0) @@ -1142,7 +1142,7 @@ bzero(&hdr, sizeof(hdr)); hdr.rtm_version = RTM_VERSION; hdr.rtm_type = action; - hdr.rtm_priority = RTP_OSPF; + hdr.rtm_priority = get_conf()->fib_priority; hdr.rtm_tableid = kr_state.rdomain; /* rtableid */ if (action == RTM_CHANGE) hdr.rtm_fmask = RTF_REJECT|RTF_BLACKHOLE; @@ -1373,7 +1373,7 @@ if (rtm->rtm_flags & RTF_MPATH) mpath = 1; prio = rtm->rtm_priority; - flags = (prio == RTP_OSPF) ? + flags = (prio == get_conf()->fib_priority) ? F_OSPFD_INSERTED : F_KERNEL; switch (sa->sa_family) { @@ -1432,7 +1432,7 @@ != NULL) { /* get the correct route */ kr = okr; - if ((mpath || prio == RTP_OSPF) && + if ((mpath || prio == get_conf()->fib_priority) && (kr = kroute_matchgw(okr, nexthop)) == NULL) { log_warnx("dispatch_rtmsg " @@ -1481,7 +1481,7 @@ kr->r.ifindex = ifindex; kr->r.priority = prio; - if (rtm->rtm_priority == RTP_OSPF) { + if (rtm->rtm_priority == get_conf()->fib_priority) { log_warnx("alien OSPF route %s/%d", inet_ntoa(prefix), prefixlen); rv = send_rtmsg(kr_state.fd, diff: ../OpenBSD54/usr.sbin/ospfd/obj: Aucun fichier ou dossier de ce type diff: ospfd/obj: Aucun fichier ou dossier de ce type diff -u ../OpenBSD54/usr.sbin/ospfd/ospfd.c ospfd/ospfd.c --- ../OpenBSD54/usr.sbin/ospfd/ospfd.c 2013-07-07 18:26:04.000000000 +0200 +++ ospfd/ospfd.c 2013-11-07 17:56:27.595760396 +0100 @@ -681,6 +681,7 @@ struct iface *iface; struct redistribute *r; int rchange = 0; + uint8_t pchange = 0; /* change of rtr_id needs a restart */ conf->flags = xconf->flags; @@ -690,6 +691,17 @@ SIMPLEQ_EMPTY(&xconf->redist_list)) rchange = 1; conf->rfc1583compat = xconf->rfc1583compat; + + /* flag for fib reloading, only when routing priority changes */ + if (conf->fib_priority != xconf->fib_priority) { + kr_fib_decouple(); + pchange = 1; + } + + conf->fib_priority = xconf->fib_priority; + + if (pchange == 1) + kr_fib_couple(); if (ospfd_process == PROC_MAIN) { /* main process does neither use areas nor interfaces */ @@ -891,3 +903,7 @@ return (i); return (NULL); } + +struct ospfd_conf* get_conf() { + return (ospfd_conf); +} diff -u ../OpenBSD54/usr.sbin/ospfd/ospfd.conf.5 ospfd/ospfd.conf.5 --- ../OpenBSD54/usr.sbin/ospfd/ospfd.conf.5 2012-10-09 00:48:09.000000000 +0200 +++ ospfd/ospfd.conf.5 2013-11-07 17:57:35.222426952 +0100 @@ -101,6 +101,11 @@ .Ic stub Ic router option to ensure that no traffic tries to transit via this router. .Pp +.It Ic fib-priority Ar prio +Set the routing priority to +.Ar prio . +The default is 32. +.Pp .It Ic rdomain Ar tableid Specifies the routing table .Xr ospfd 8 diff -u ../OpenBSD54/usr.sbin/ospfd/ospfd.h ospfd/ospfd.h --- ../OpenBSD54/usr.sbin/ospfd/ospfd.h 2013-02-16 04:03:42.000000000 +0100 +++ ospfd/ospfd.h 2013-11-07 14:16:07.395782105 +0100 @@ -386,6 +386,7 @@ u_int8_t rfc1583compat; u_int8_t border; u_int8_t redistribute; + u_int8_t fib_priority; u_int rdomain; char *csock; }; @@ -592,6 +593,7 @@ void imsg_event_add(struct imsgev *); int imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, pid_t, int, void *, u_int16_t); +struct ospfd_conf* get_conf(void); /* printconf.c */ void print_config(struct ospfd_conf *); diff -u ../OpenBSD54/usr.sbin/ospfd/parse.y ospfd/parse.y --- ../OpenBSD54/usr.sbin/ospfd/parse.y 2013-07-07 18:26:04.000000000 +0200 +++ ospfd/parse.y 2013-11-07 17:29:40.195763036 +0100 @@ -37,6 +37,7 @@ #include <stdio.h> #include <string.h> #include <syslog.h> +#include <net/route.h> #include "ospf.h" #include "ospfd.h" @@ -96,6 +97,7 @@ enum auth_type auth_type; u_int8_t auth_keyid; u_int8_t priority; + u_int8_t fib_priority; }; struct config_defaults globaldefs; @@ -120,7 +122,7 @@ %token AREA INTERFACE ROUTERID FIBUPDATE REDISTRIBUTE RTLABEL RDOMAIN %token RFC1583COMPAT STUB ROUTER SPFDELAY SPFHOLDTIME EXTTAG %token AUTHKEY AUTHTYPE AUTHMD AUTHMDKEYID -%token METRIC PASSIVE +%token METRIC PASSIVE FIBPRIORITY %token HELLOINTERVAL FASTHELLOINTERVAL TRANSMITDELAY %token RETRANSMITINTERVAL ROUTERDEADTIME ROUTERPRIORITY %token SET TYPE @@ -209,6 +211,13 @@ } free($2); } + | FIBPRIORITY NUMBER { + if ($2 <= RTP_STATIC || $2 > RTP_MAX) { + yyerror("invalid fib-priority"); + YYERROR; + } + conf->fib_priority = $2; + } | FIBUPDATE yesno { if ($2 == 0) conf->flags |= OSPFD_FLAG_NO_FIB_UPDATE; @@ -725,6 +734,7 @@ {"demote", DEMOTE}, {"external-tag", EXTTAG}, {"fast-hello-interval", FASTHELLOINTERVAL}, + {"fib-priority", FIBPRIORITY}, {"fib-update", FIBUPDATE}, {"hello-interval", HELLOINTERVAL}, {"include", INCLUDE}, @@ -1094,6 +1104,7 @@ 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) { free(conf);