Download raw body.
bgpd: adjust Adj-RIB-Out operations to support down peers
Both prefix_adjout_update() and prefix_adjout_withdraw() insert a RB tree
node into the update / withdraw tree structures. Those RB_INSERTs result
in the update to be sent out.
In preparation for caching the Adj-RIB-Out over a session restart add a
check in the two functions to only do this RB tree insert if the peer is
up. For prefix_adjout_update() nothing else needs to be done (the prefix
is still linked in the actual Adj-RIB-Out (called adj_rib_out) but on a
withdraw the prefix is already unlinked for the adj_rib_out and needs to
be destroyed. To make this work correctly mark the prefix as dead since
it is already unlinked and therefor dead.
Right now this is a no-op since prefix_adjout_update() and
prefix_adjout_withdraw() are only called for peers that are up but this
diff is complex enough to send it out alone.
--
:wq Claudio
Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
diff -u -p -r1.263 rde_rib.c
--- rde_rib.c 14 Aug 2024 19:09:51 -0000 1.263
+++ rde_rib.c 10 Dec 2024 15:42:04 -0000
@@ -1321,10 +1321,12 @@ prefix_adjout_update(struct prefix *p, s
if (p->flags & PREFIX_FLAG_MASK)
fatalx("%s: bad flags %x", __func__, p->flags);
- p->flags |= PREFIX_FLAG_UPDATE;
- if (RB_INSERT(prefix_tree, &peer->updates[pte->aid], p) != NULL)
- fatalx("%s: RB tree invariant violated", __func__);
- peer->stats.pending_update++;
+ if (peer_is_up(peer)) {
+ p->flags |= PREFIX_FLAG_UPDATE;
+ if (RB_INSERT(prefix_tree, &peer->updates[pte->aid], p) != NULL)
+ fatalx("%s: RB tree invariant violated", __func__);
+ peer->stats.pending_update++;
+ }
}
/*
@@ -1360,10 +1362,17 @@ prefix_adjout_withdraw(struct prefix *p)
p->flags &= ~PREFIX_FLAG_MASK;
p->lastchange = getmonotime();
- p->flags |= PREFIX_FLAG_WITHDRAW;
- if (RB_INSERT(prefix_tree, &peer->withdraws[p->pt->aid], p) != NULL)
- fatalx("%s: RB tree invariant violated", __func__);
- peer->stats.pending_withdraw++;
+ if (peer_is_up(peer)) {
+ p->flags |= PREFIX_FLAG_WITHDRAW;
+ if (RB_INSERT(prefix_tree, &peer->withdraws[p->pt->aid],
+ p) != NULL)
+ fatalx("%s: RB tree invariant violated", __func__);
+ peer->stats.pending_withdraw++;
+ } else {
+ /* mark prefix dead to skip unlink on destroy */
+ p->flags |= PREFIX_FLAG_DEAD;
+ prefix_adjout_destroy(p);
+ }
}
void
bgpd: adjust Adj-RIB-Out operations to support down peers