Download raw body.
bgpd: fix nexthop qualify via bgp
Qualifying nexthops via BGP is currently busted because the nexthops are
not rechecked once a new BGP route is added. We need to keep track of
nexthops both on inserts (kroute_insert) and on change (krX_change but
only for AID_INET and AID_INET6 -- no nexthops in the other tables)
We don't want to always validate all nexthops so only do this if 'nexthop
qualify via bgp' is enabled. For route changes we can depend on the
F_NEXTHOP flag.
This code can be further optimised but it requires a lot of buck for the
bang.
See also: https://github.com/openbgpd-portable/openbgpd-portable/issues/81
--
:wq Claudio
Index: bgpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.c,v
diff -u -p -r1.265 bgpd.c
--- bgpd.c 12 Aug 2024 09:04:23 -0000 1.265
+++ bgpd.c 4 Sep 2024 13:20:02 -0000
@@ -1178,6 +1178,12 @@ bgpd_oknexthop(struct kroute_full *kf)
}
int
+bgpd_has_bgpnh(void)
+{
+ return ((cflags & BGPD_FLAG_NEXTHOP_BGP) != 0);
+}
+
+int
control_setup(struct bgpd_config *conf)
{
int fd, restricted;
Index: bgpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/bgpd.h,v
diff -u -p -r1.495 bgpd.h
--- bgpd.h 14 Aug 2024 19:09:51 -0000 1.495
+++ bgpd.h 4 Sep 2024 13:20:02 -0000
@@ -1416,6 +1416,7 @@ void send_imsg_session(int, pid_t, voi
int send_network(int, struct network_config *,
struct filter_set_head *);
int bgpd_oknexthop(struct kroute_full *);
+int bgpd_has_bgpnh(void);
void set_pollfd(struct pollfd *, struct imsgbuf *);
int handle_pollfd(struct pollfd *, struct imsgbuf *);
Index: kroute.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/kroute.c,v
diff -u -p -r1.309 kroute.c
--- kroute.c 9 Jan 2024 13:41:32 -0000 1.309
+++ kroute.c 4 Sep 2024 13:57:18 -0000
@@ -511,6 +511,9 @@ kr4_change(struct ktable *kt, struct kro
else
kr->flags &= ~F_REJECT;
+ if (kr->flags & F_NEXTHOP)
+ knexthop_update(kt, kf);
+
if (send_rtmsg(RTM_CHANGE, kt, kf))
kr->flags |= F_BGPD_INSERTED;
}
@@ -549,6 +552,9 @@ kr6_change(struct ktable *kt, struct kro
else
kr6->flags &= ~F_REJECT;
+ if (kr6->flags & F_NEXTHOP)
+ knexthop_update(kt, kf);
+
if (send_rtmsg(RTM_CHANGE, kt, kf))
kr6->flags |= F_BGPD_INSERTED;
}
@@ -1719,13 +1725,14 @@ kroute_insert(struct ktable *kt, struct
break;
}
- /* XXX this is wrong for nexthop validated via BGP */
- if (!(kf->flags & F_BGPD)) {
+ if (bgpd_has_bgpnh() || !(kf->flags & F_BGPD)) {
RB_FOREACH(n, knexthop_tree, KT2KNT(kt))
if (prefix_compare(&kf->prefix, &n->nexthop,
kf->prefixlen) == 0)
knexthop_validate(kt, n);
+ }
+ if (!(kf->flags & F_BGPD)) {
/* redistribute multipath routes only once */
if (!multipath)
kr_redistribute(IMSG_NETWORK_ADD, kt, kf);
bgpd: fix nexthop qualify via bgp