From 98bcec602bf1c4951a77d9457e24ddcc98311aa7 Mon Sep 17 00:00:00 2001 From: remi Date: Fri, 28 Dec 2018 19:25:11 +0000 Subject: Add config option fib-priority to set a custom prio for routes ospfd inserts into the kernel routing table. OK claudio@ --- usr.sbin/ospfd/kroute.c | 48 +++++++++++++++++++++++++++++++-------------- usr.sbin/ospfd/ospfd.c | 14 +++++++++++-- usr.sbin/ospfd/ospfd.conf.5 | 9 +++++++-- usr.sbin/ospfd/ospfd.h | 6 ++++-- usr.sbin/ospfd/parse.y | 16 ++++++++++++--- usr.sbin/ospfd/printconf.c | 4 +++- 6 files changed, 72 insertions(+), 25 deletions(-) diff --git a/usr.sbin/ospfd/kroute.c b/usr.sbin/ospfd/kroute.c index 9e396975f2e..40348c13040 100644 --- a/usr.sbin/ospfd/kroute.c +++ b/usr.sbin/ospfd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.111 2018/07/10 11:49:04 friehm Exp $ */ +/* $OpenBSD: kroute.c,v 1.112 2018/12/28 19:25:10 remi Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -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, struct kroute *kroute, int krcount, 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 krcount) 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 krcount) 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 kroute *kroute) 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, diff --git a/usr.sbin/ospfd/ospfd.c b/usr.sbin/ospfd/ospfd.c index 8052ab49394..d3d995180cc 100644 --- a/usr.sbin/ospfd/ospfd.c +++ b/usr.sbin/ospfd/ospfd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.c,v 1.101 2018/10/29 22:13:33 remi Exp $ */ +/* $OpenBSD: ospfd.c,v 1.102 2018/12/28 19:25:10 remi Exp $ */ /* * Copyright (c) 2005 Claudio Jeker @@ -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, struct ospfd_conf *xconf) 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; } diff --git a/usr.sbin/ospfd/ospfd.conf.5 b/usr.sbin/ospfd/ospfd.conf.5 index f9abfd2b188..e3ce8323e99 100644 --- a/usr.sbin/ospfd/ospfd.conf.5 +++ b/usr.sbin/ospfd/ospfd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ospfd.conf.5,v 1.54 2018/07/27 05:23:24 jmc Exp $ +.\" $OpenBSD: ospfd.conf.5,v 1.55 2018/12/28 19:25:10 remi Exp $ .\" .\" Copyright (c) 2005 Esben Norby .\" Copyright (c) 2004 Claudio Jeker @@ -17,7 +17,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 27 2018 $ +.Dd $Mdocdate: December 28 2018 $ .Dt OSPFD.CONF 5 .Os .Sh NAME @@ -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 diff --git a/usr.sbin/ospfd/ospfd.h b/usr.sbin/ospfd/ospfd.h index 3e8a5af4ab2..8cab0810910 100644 --- a/usr.sbin/ospfd/ospfd.h +++ b/usr.sbin/ospfd/ospfd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfd.h,v 1.102 2018/08/29 08:43:17 remi Exp $ */ +/* $OpenBSD: ospfd.h,v 1.103 2018/12/28 19:25:10 remi Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -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, 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); diff --git a/usr.sbin/ospfd/parse.y b/usr.sbin/ospfd/parse.y index 7bc38d6f20e..be6aac3dc2a 100644 --- a/usr.sbin/ospfd/parse.y +++ b/usr.sbin/ospfd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.93 2018/11/01 00:18:44 sashan Exp $ */ +/* $OpenBSD: parse.y,v 1.94 2018/12/28 19:25:10 remi Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -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) { diff --git a/usr.sbin/ospfd/printconf.c b/usr.sbin/ospfd/printconf.c index 576e0acba38..93ed4e68e4b 100644 --- a/usr.sbin/ospfd/printconf.c +++ b/usr.sbin/ospfd/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.19 2018/07/11 15:41:19 remi Exp $ */ +/* $OpenBSD: printconf.c,v 1.20 2018/12/28 19:25:10 remi Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby @@ -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); -- cgit v1.2.3