diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2019-07-23 06:26:45 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2019-07-23 06:26:45 +0000 |
commit | 0624761f19d6c13ded76efa536423758080cae9e (patch) | |
tree | 3e8542f5edc21c6911a070093bb684c803a581ad | |
parent | d76f83e51fa4a42f79a777af15b8e1e45ad286ec (diff) |
Clean up RIB related kroute code. Introduce a way to flush a FIB table
from the RDE. Make sure that all nexthops don't get removed in the FIB
when a FIB table is removed. This should only happen for the main FIB.
Remove F_RIB_HASNOFIB which is just confusing since there is already
F_RIB_NOFIB and F_RIB_NOFIBSYNC.
OK benno@
-rw-r--r-- | usr.sbin/bgpd/bgpd.c | 10 | ||||
-rw-r--r-- | usr.sbin/bgpd/bgpd.h | 5 | ||||
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 64 | ||||
-rw-r--r-- | usr.sbin/bgpd/parse.y | 4 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde.c | 12 |
5 files changed, 75 insertions, 20 deletions
diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index 9bdc39a05be..61fc8d160a8 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.220 2019/07/19 07:40:41 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.221 2019/07/23 06:26:44 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -740,6 +740,14 @@ dispatch_imsg(struct imsgbuf *ibuf, int idx, struct bgpd_config *conf) conf->fib_priority)) rv = -1; break; + case IMSG_KROUTE_FLUSH: + if (idx != PFD_PIPE_ROUTE) + log_warnx("route request not from RDE"); + else if (imsg.hdr.len != IMSG_HEADER_SIZE) + log_warnx("wrong imsg len"); + else if (kr_flush(imsg.hdr.peerid)) + rv = -1; + break; case IMSG_NEXTHOP_ADD: if (idx != PFD_PIPE_ROUTE) log_warnx("nexthop request not from RDE"); diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index b18eea2c047..56c99e9f585 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.389 2019/07/19 07:40:41 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.390 2019/07/23 06:26:44 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -506,6 +506,7 @@ enum imsg_type { IMSG_MRT_CLOSE, IMSG_KROUTE_CHANGE, IMSG_KROUTE_DELETE, + IMSG_KROUTE_FLUSH, IMSG_NEXTHOP_ADD, IMSG_NEXTHOP_REMOVE, IMSG_NEXTHOP_UPDATE, @@ -1073,7 +1074,6 @@ extern struct rib_names ribnames; #define F_RIB_NOEVALUATE 0x0002 #define F_RIB_NOFIB 0x0004 #define F_RIB_NOFIBSYNC 0x0008 -#define F_RIB_HASNOFIB (F_RIB_NOFIB | F_RIB_NOEVALUATE) /* 4-byte magic AS number */ #define AS_TRANS 23456 @@ -1191,6 +1191,7 @@ void ktable_postload(u_int8_t); int ktable_exists(u_int, u_int *); int kr_change(u_int, struct kroute_full *, u_int8_t); int kr_delete(u_int, struct kroute_full *, u_int8_t); +int kr_flush(u_int); void kr_shutdown(u_int8_t, u_int); void kr_fib_couple(u_int, u_int8_t); void kr_fib_couple_all(u_int8_t); diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c index 57eefc6cf5c..ada0581a150 100644 --- a/usr.sbin/bgpd/kroute.c +++ b/usr.sbin/bgpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.236 2019/05/06 09:49:26 claudio Exp $ */ +/* $OpenBSD: kroute.c,v 1.237 2019/07/23 06:26:44 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -311,7 +311,8 @@ ktable_new(u_int rtableid, u_int rdomid, char *name, int fs, u_int8_t fib_prio) /* everything is up and running */ kt->state = RECONF_REINIT; - log_debug("%s: %s for rtableid %d", __func__, name, rtableid); + log_debug("%s: %s with rtableid %d rdomain %d", __func__, name, + rtableid, rdomid); return (0); } @@ -351,7 +352,9 @@ ktable_destroy(struct ktable *kt, u_int8_t fib_prio) log_debug("%s: freeing ktable %s rtableid %u", __func__, kt->descr, kt->rtableid); - knexthop_clear(kt); + /* only clear nexthop table if it is the main rdomain table */ + if (kt->rtableid == kt->nhtableid) + knexthop_clear(kt); kroute_clear(kt); kroute6_clear(kt); kr_net_clear(kt); @@ -395,7 +398,7 @@ ktable_update(u_int rtableid, char *name, int flags, u_int8_t fib_prio) } } - if (flags & F_RIB_HASNOFIB) + if (flags & (F_RIB_NOFIB | F_RIB_NOEVALUATE)) /* only rdomain table must exist */ return (0); @@ -758,6 +761,42 @@ kr_delete(u_int rtableid, struct kroute_full *kl, u_int8_t fib_prio) } int +kr_flush(u_int rtableid) +{ + struct ktable *kt; + struct kroute_node *kr, *next; + struct kroute6_node *kr6, *next6; + + if ((kt = ktable_get(rtableid)) == NULL) + /* too noisy during reloads, just ignore */ + return (0); + + RB_FOREACH_SAFE(kr, kroute_tree, &kt->krt, next) + if ((kr->r.flags & F_BGPD_INSERTED)) { + if (kt->fib_sync) /* coupled */ + send_rtmsg(kr_state.fd, RTM_DELETE, kt, + &kr->r, kr->r.priority); + rtlabel_unref(kr->r.labelid); + + if (kroute_remove(kt, kr) == -1) + return (-1); + } + RB_FOREACH_SAFE(kr6, kroute6_tree, &kt->krt6, next6) + if ((kr6->r.flags & F_BGPD_INSERTED)) { + if (kt->fib_sync) /* coupled */ + send_rt6msg(kr_state.fd, RTM_DELETE, kt, + &kr6->r, kr6->r.priority); + rtlabel_unref(kr6->r.labelid); + + if (kroute6_remove(kt, kr6) == -1) + return (-1); + } + + kt->fib_sync = 0; + return (0); +} + +int kr4_delete(struct ktable *kt, struct kroute_full *kl, u_int8_t fib_prio) { struct kroute_node *kr; @@ -1543,8 +1582,10 @@ kr_reload(void) if ((kt = ktable_get(rid)) == NULL) continue; - RB_FOREACH(nh, knexthop_tree, KT2KNT(kt)) - knexthop_validate(kt, nh); + /* if this is the main nexthop table revalidate nexthops */ + if (kt->rtableid == kt->nhtableid) + RB_FOREACH(nh, knexthop_tree, KT2KNT(kt)) + knexthop_validate(kt, nh); TAILQ_FOREACH(n, &kt->krn, entry) if (n->net.type == NETWORK_DEFAULT) { @@ -2372,6 +2413,9 @@ knexthop_validate(struct ktable *kt, struct knexthop_node *kn) oldk = kn->kroute; kroute_detach_nexthop(kt, kn); + if ((kt = ktable_get(kt->nhtableid)) == NULL) + fatalx("%s: lost nexthop routing table", __func__); + switch (kn->nexthop.aid) { case AID_INET: kr = kroute_match(kt, kn->nexthop.v4.s_addr, 0); @@ -2474,14 +2518,14 @@ kroute_match(struct ktable *kt, in_addr_t key, int matchall) ina = ntohl(key); - /* we will never match the default route */ + /* this will never match the default route */ for (i = 32; i > 0; i--) if ((kr = kroute_find(kt, htonl(ina & prefixlen2mask(i)), i, RTP_ANY)) != NULL) if (matchall || bgpd_filternexthop(&kr->r, NULL) == 0) return (kr); - /* if we don't have a match yet, try to find a default route */ + /* so if there is no match yet, lookup the default route */ if ((kr = kroute_find(kt, 0, 0, RTP_ANY)) != NULL) if (matchall || bgpd_filternexthop(&kr->r, NULL) == 0) return (kr); @@ -2496,7 +2540,7 @@ kroute6_match(struct ktable *kt, struct in6_addr *key, int matchall) struct kroute6_node *kr6; struct in6_addr ina; - /* we will never match the default route */ + /* this will never match the default route */ for (i = 128; i > 0; i--) { inet6applymask(&ina, key, i); if ((kr6 = kroute6_find(kt, &ina, i, RTP_ANY)) != NULL) @@ -2504,7 +2548,7 @@ kroute6_match(struct ktable *kt, struct in6_addr *key, int matchall) return (kr6); } - /* if we don't have a match yet, try to find a default route */ + /* so if there is no match yet, lookup the default route */ if ((kr6 = kroute6_find(kt, &in6addr_any, 0, RTP_ANY)) != NULL) if (matchall || bgpd_filternexthop(NULL, &kr6->r) == 0) return (kr6); diff --git a/usr.sbin/bgpd/parse.y b/usr.sbin/bgpd/parse.y index 7a0ef65021c..b1ab562c2f0 100644 --- a/usr.sbin/bgpd/parse.y +++ b/usr.sbin/bgpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.393 2019/07/17 10:13:26 claudio Exp $ */ +/* $OpenBSD: parse.y,v 1.394 2019/07/23 06:26:44 claudio Exp $ */ /* * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -3902,7 +3902,7 @@ add_rib(char *name, u_int rtableid, u_int16_t flags) return (-1); } rr->flags |= flags; - if ((rr->flags & F_RIB_HASNOFIB) == 0) { + if ((rr->flags & (F_RIB_NOFIB | F_RIB_NOEVALUATE)) == 0) { if (ktable_exists(rtableid, &rdom) != 1) { yyerror("rtable id %u does not exist", rtableid); free(rr); diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c index 700ca7a5fe1..47d8c8c048b 100644 --- a/usr.sbin/bgpd/rde.c +++ b/usr.sbin/bgpd/rde.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.c,v 1.476 2019/07/17 10:13:26 claudio Exp $ */ +/* $OpenBSD: rde.c,v 1.477 2019/07/23 06:26:44 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -811,13 +811,15 @@ rde_dispatch_imsg_parent(struct imsgbuf *ibuf) rib = rib_byid(rib_find(rn.name)); if (rib == NULL) rib = rib_new(rn.name, rn.rtableid, rn.flags); - else if ((rib->flags & F_RIB_HASNOFIB) != - (rn.flags & F_RIB_HASNOFIB) || (rib->rtableid != - rn.rtableid && !(rn.flags & F_RIB_HASNOFIB))) { + else if ( + (rib->flags & (F_RIB_NOFIB | F_RIB_NOEVALUATE)) != + (rn.flags & (F_RIB_NOFIB | F_RIB_NOEVALUATE)) || + (rib->rtableid != rn.rtableid && + !(rn.flags & (F_RIB_NOFIB | F_RIB_NOEVALUATE)))) { struct filter_head *in_rules; struct rib_desc *ribd = rib_desc(rib); /* - * Big hammer in the F_RIB_HASNOFIB case but + * Big hammer in the F_RIB_NOFIB case but * not often enough used to optimise it more. * Need to save the filters so that they're not * lost. If the rtableid changes but there is |