Download raw body.
bgpd: fix accounting errors for pending updates
On Thu, Mar 13, 2025 at 04:22:58PM +0100, Claudio Jeker wrote:
> With the introduction of the adj-rib-out cache the pending update count
> could go off (wrap around 0).
>
> There are two issues:
> - In peer_blast_upcall() we need to increase pending_update for every
> prefix we insert.
> - In prefix_adjout_flush_pending() the EoR marker needs special handling.
> The EoR marker is not counted in pending_update but when unlinking it
> we need to free the marker. It will be inserted again when we blast
> out the table.
All this makes sense.
> With these two diffs the pending updates is now correct in my tests.
> The pending withdraws does not have this issue since the accouting already
> happens in prefix_adjout_destroy().
Yes, that looks right, too.
ok tb
> --
> :wq Claudio
>
> Index: rde_peer.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_peer.c,v
> diff -u -p -r1.47 rde_peer.c
> --- rde_peer.c 20 Feb 2025 19:47:31 -0000 1.47
> +++ rde_peer.c 12 Mar 2025 13:33:01 -0000
> @@ -523,14 +523,18 @@ peer_stale(struct rde_peer *peer, uint8_
> static void
> peer_blast_upcall(struct prefix *p, void *ptr)
> {
> + struct rde_peer *peer;
> +
> if (p->flags & PREFIX_FLAG_DEAD) {
> /* ignore dead prefixes, they will go away soon */
> } else if ((p->flags & PREFIX_FLAG_MASK) == 0) {
> + peer = prefix_peer(p);
> /* put entries on the update queue if not already on a queue */
> p->flags |= PREFIX_FLAG_UPDATE;
> - if (RB_INSERT(prefix_tree, &prefix_peer(p)->updates[p->pt->aid],
> + if (RB_INSERT(prefix_tree, &peer->updates[p->pt->aid],
> p) != NULL)
> fatalx("%s: RB tree invariant violated", __func__);
> + peer->stats.pending_update++;
> }
> }
>
> Index: rde_rib.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
> diff -u -p -r1.267 rde_rib.c
> --- rde_rib.c 14 Jan 2025 12:24:23 -0000 1.267
> +++ rde_rib.c 12 Mar 2025 16:21:28 -0000
> @@ -1430,7 +1430,11 @@ prefix_adjout_flush_pending(struct rde_p
> RB_FOREACH_SAFE(p, prefix_tree, &peer->updates[aid], np) {
> p->flags &= ~PREFIX_FLAG_UPDATE;
> RB_REMOVE(prefix_tree, &peer->updates[aid], p);
> - peer->stats.pending_update--;
> + if (p->flags & PREFIX_FLAG_EOR) {
> + prefix_adjout_destroy(p);
> + } else {
> + peer->stats.pending_update--;
> + }
> }
> }
> }
>
bgpd: fix accounting errors for pending updates