Commit 149614fa3b for frr
commit 149614fa3b16149e3da66c53d8e5d58774deacfa
Author: Kyle Qi <kyle@nexthop.ai>
Date: Tue Oct 20 18:23:42 2026 +0000
bgpd: send one BMP Loc-RIB End-of-RIB per AFI/SAFI
bmp_eor() wrote one EoR per peer that negotiated the AFI/SAFI for every
peer type. For Loc-RIB that sent duplicate, identical EoRs with several
peers and none with zero peers. Send a single Loc-RIB EoR for
bgp->peer_self instead; pre/post-policy EoRs stay per peer.
Signed-off-by: Kyle Qi <kyle@nexthop.ai>
diff --git a/bgpd/bgp_bmp.c b/bgpd/bgp_bmp.c
index 2b5dfc6c52..c078e58d2a 100644
--- a/bgpd/bgp_bmp.c
+++ b/bgpd/bgp_bmp.c
@@ -1253,12 +1253,40 @@ static int bmp_peer_backward(struct peer *peer)
return 0;
}
+/* write one EoR route monitoring message (pre-built update in s) for peer */
+static void bmp_eor_write(struct bmp *bmp, struct stream *s, struct peer *peer, afi_t afi,
+ uint8_t flags, uint8_t peer_type_flag)
+{
+ struct bgp *bgp = peer->bgp;
+ struct stream *s2;
+ uint64_t peer_distinguisher = 0;
+
+ /* skip this message if peer distinguisher is not available */
+ if (bmp_get_peer_distinguisher(bgp, afi, peer_type_flag, &peer_distinguisher)) {
+ zlog_warn("skipping bmp message for reason: can't get peer distinguisher");
+ return;
+ }
+
+ s2 = stream_new(BGP_MAX_PACKET_SIZE);
+
+ bmp_common_hdr(s2, BMP_VERSION_3, BMP_TYPE_ROUTE_MONITORING);
+
+ bmp_per_peer_hdr(s2, bgp, peer, flags, peer_type_flag, peer_distinguisher, NULL);
+
+ stream_putl_at(s2, BMP_LENGTH_POS, stream_get_endp(s) + stream_get_endp(s2));
+
+ bmp->cnt_update++;
+ pullwr_write_stream(bmp->pullwr, s2);
+ pullwr_write_stream(bmp->pullwr, s);
+ stream_free(s2);
+}
+
static void bmp_eor(struct bmp *bmp, afi_t afi, safi_t safi, uint8_t flags, uint8_t peer_type_flag,
struct bgp *bgp)
{
struct peer *peer;
struct listnode *node;
- struct stream *s, *s2;
+ struct stream *s;
iana_afi_t pkt_afi = IANA_AFI_IPV4;
iana_safi_t pkt_safi = IANA_SAFI_UNICAST;
@@ -1290,32 +1318,18 @@ static void bmp_eor(struct bmp *bmp, afi_t afi, safi_t safi, uint8_t flags, uint
bgp_packet_set_size(s);
+ /* Loc-RIB is a single instance: one EoR, not one per negotiated peer */
+ if (peer_type_flag == BMP_PEER_TYPE_LOC_RIB_INSTANCE) {
+ bmp_eor_write(bmp, s, bgp->peer_self, afi, flags, peer_type_flag);
+ stream_free(s);
+ return;
+ }
+
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
if (!peer->afc_nego[afi][safi])
continue;
- uint64_t peer_distinguisher = 0;
- /* skip this message if peer distinguisher is not available */
- if (bmp_get_peer_distinguisher(peer->bgp, afi, peer_type_flag, &peer_distinguisher)) {
- zlog_warn(
- "skipping bmp message for reason: can't get peer distinguisher");
- continue;
- }
-
- s2 = stream_new(BGP_MAX_PACKET_SIZE);
-
- bmp_common_hdr(s2, BMP_VERSION_3,
- BMP_TYPE_ROUTE_MONITORING);
-
- bmp_per_peer_hdr(s2, bgp, peer, flags, peer_type_flag, peer_distinguisher, NULL);
-
- stream_putl_at(s2, BMP_LENGTH_POS,
- stream_get_endp(s) + stream_get_endp(s2));
-
- bmp->cnt_update++;
- pullwr_write_stream(bmp->pullwr, s2);
- pullwr_write_stream(bmp->pullwr, s);
- stream_free(s2);
+ bmp_eor_write(bmp, s, peer, afi, flags, peer_type_flag);
}
stream_free(s);
}