Download raw body.
bgpd: fix adj-rib-out cache issue with add-path
The adj-rib-out remains cached when a peer goes down.
When the session is reestablished the code checks if the sync is still
valid or if a full peer_dump is needed. This depends also on the
capabilities of the session.
If a session drops from add-path send X to no add-path send then the
adj-rib-out is a bit desynced and up_generate_updates() does not all the
required cleanup.
In the EVAL_SYNC case up_generate_updates() should check if the
adjout_prefix (p) returned was for an add-path path. This is the case if
path_id_tx is not 0. In that case withdraw all paths before calling
up_process_prefix().
The add-path side already does this by default.
Most other cases where the adj-rib-out gets desynced is during config
reloads (e.g. switching export modes). There the code already does a
RIB flush and the resync.
--
:wq Claudio
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
diff -u -p -r1.202 rde_update.c
--- rde_update.c 20 Jul 2026 13:25:49 -0000 1.202
+++ rde_update.c 20 Jul 2026 14:22:36 -0000
@@ -228,6 +228,18 @@ up_generate_updates(struct rde_peer *pee
p = adjout_prefix_first(re->prefix, peer->adjout_bid);
+ /*
+ * In case the peer switched from add-path send to no add-path,
+ * flush all the cached prefixes during initial sync.
+ */
+ if (mode == EVAL_SYNC && p != NULL && p->path_id_tx != 0) {
+ do {
+ adjout_prefix_withdraw(peer, re->prefix, p, 1);
+ p = adjout_prefix_next(re->prefix,
+ peer->adjout_bid, p);
+ } while(p != NULL);
+ }
+
new = prefix_best(re);
while (new != NULL) {
switch (up_process_prefix(peer, new, p, mode)) {
bgpd: fix adj-rib-out cache issue with add-path