summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2019-07-23 06:26:45 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2019-07-23 06:26:45 +0000
commit0624761f19d6c13ded76efa536423758080cae9e (patch)
tree3e8542f5edc21c6911a070093bb684c803a581ad
parentd76f83e51fa4a42f79a777af15b8e1e45ad286ec (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.c10
-rw-r--r--usr.sbin/bgpd/bgpd.h5
-rw-r--r--usr.sbin/bgpd/kroute.c64
-rw-r--r--usr.sbin/bgpd/parse.y4
-rw-r--r--usr.sbin/bgpd/rde.c12
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