Index | Thread | Search

From:
Claudio Jeker <cjeker@diehard.n-r-g.com>
Subject:
bgpd: fix softreload bug in the RDE
To:
tech@openbsd.org
Date:
Tue, 28 Apr 2026 10:34:23 +0200

Download raw body.

Thread
  • Claudio Jeker:

    bgpd: fix softreload bug in the RDE

In rde_reload_done() the code handling the peer->reconf_rib case has a
continue which skips the code path that actually reapplies the outbound
filters. This is a bug since the code needs to reapply the outbound
filters for every peer.

Removing the continue changes the way peer->reconf_rib and
peer->reconf_out behave. Before only one of them was possible at any time
but now in the reconf_rib case reconf_out is most probably also set.
Because of this switch the order of checks in rde_softreconfig_in_done()
so that reconf_rib has precedence.

Noticed while reworking the filters.
-- 
:wq Claudio

Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde.c,v
diff -u -p -r1.694 rde.c
--- rde.c	27 Apr 2026 15:52:20 -0000	1.694
+++ rde.c	28 Apr 2026 08:28:17 -0000
@@ -4003,7 +4003,6 @@ rde_reload_done(void)
 				fatal("%s: prefix_dump_new", __func__);
 			log_peer_info(&peer->conf, "flushing Adj-RIB-Out");
 			softreconfig++;	/* account for the running flush */
-			continue;
 		}
 
 		/* reapply outbound filters for this peer */
@@ -4213,7 +4212,13 @@ rde_softreconfig_in_done(void *arg, uint
 	RB_FOREACH(peer, peer_tree, &peertable) {
 		uint8_t aid;
 
-		if (peer->reconf_out) {
+		if (peer->reconf_rib) {
+			/* dump the full table to neighbors that changed rib */
+			for (aid = AID_MIN; aid < AID_MAX; aid++) {
+				if (peer->capa.mp[aid])
+					peer_dump(peer, aid);
+			}
+		} else if (peer->reconf_out) {
 			if (peer->export_type == EXPORT_NONE) {
 				/* nothing to do here */
 				peer->reconf_out = 0;
@@ -4227,12 +4232,6 @@ rde_softreconfig_in_done(void *arg, uint
 			} else
 				rib_byid(peer->loc_rib_id)->state =
 				    RECONF_RELOAD;
-		} else if (peer->reconf_rib) {
-			/* dump the full table to neighbors that changed rib */
-			for (aid = AID_MIN; aid < AID_MAX; aid++) {
-				if (peer->capa.mp[aid])
-					peer_dump(peer, aid);
-			}
 		}
 	}