From 3e51611556ed516afe781402181b30679e4e2308 Mon Sep 17 00:00:00 2001 From: claudio Date: Wed, 4 Sep 2024 15:06:36 +0000 Subject: [PATCH] Qualifying nexthops via BGP does not properly work since nexthops need to be rechecked when a BGP route is added (or changed). We need to revalidate nexthops on inserts (kroute_insert) and on change (krX_change but only for AID_INET and AID_INET6 -- no nexthops in the other tables) the nexthop needs to be updated. Only validate nexthops if 'nexthop qualify via bgp' is enabled. For route changes the code can depend on the F_NEXTHOP flag. Fix for: https://github.com/openbgpd-portable/openbgpd-portable/issues/81 OK tb@ --- usr.sbin/bgpd/bgpd.c | 8 +++++++- usr.sbin/bgpd/bgpd.h | 3 ++- usr.sbin/bgpd/kroute.c | 13 ++++++++++--- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/usr.sbin/bgpd/bgpd.c b/usr.sbin/bgpd/bgpd.c index e997d680259..bb0e19d01a8 100644 --- a/usr.sbin/bgpd/bgpd.c +++ b/usr.sbin/bgpd/bgpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.c,v 1.266 2024/09/04 13:30:10 claudio Exp $ */ +/* $OpenBSD: bgpd.c,v 1.267 2024/09/04 15:06:36 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1181,6 +1181,12 @@ bgpd_oknexthop(struct kroute_full *kf) return (1); } +int +bgpd_has_bgpnh(void) +{ + return ((cflags & BGPD_FLAG_NEXTHOP_BGP) != 0); +} + int control_setup(struct bgpd_config *conf) { diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 78e245b5d26..c558d636b44 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.495 2024/08/14 19:09:51 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.496 2024/09/04 15:06:36 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1416,6 +1416,7 @@ void send_imsg_session(int, pid_t, void *, uint16_t); 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 *); diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c index 6da5986faec..a806ae8a094 100644 --- a/usr.sbin/bgpd/kroute.c +++ b/usr.sbin/bgpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.309 2024/01/09 13:41:32 claudio Exp $ */ +/* $OpenBSD: kroute.c,v 1.310 2024/09/04 15:06:36 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -511,6 +511,9 @@ kr4_change(struct ktable *kt, struct kroute_full *kf) 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 kroute_full *kf) 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 kroute_full *kf) 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); -- 2.20.1