]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: bmp, handle imported bgp instances for peer up/down events
authorPhilippe Guibert <philippe.guibert@6wind.com>
Thu, 7 Nov 2024 13:28:39 +0000 (14:28 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 7 Jan 2025 14:35:31 +0000 (15:35 +0100)
Only the peer transition events of the local BGP instance where BMP
is configured, were handled.
Add the support for peers from imported BGP instances:
- Add an internal API bmp_send_bt() function to handle stream
emission per bmp target
- Modify the BMP peer transition code to export the peer status
notifications to all BMP instances importing it.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
bgpd/bgp_bmp.c

index 91d566f3e57f66504514c7fb01c6198d2c76a448..99f9206fb2c0a99ebe501e739ea275439c3a38c9 100644 (file)
@@ -53,6 +53,7 @@ static void bmp_active_put(struct bmp_active *ba);
 static int bmp_route_update_bgpbmp(struct bmp_targets *bt, afi_t afi, safi_t safi,
                                   struct bgp_dest *bn, struct bgp_path_info *old_route,
                                   struct bgp_path_info *new_route);
+static void bmp_send_all_bgp(struct peer *peer, bool down);
 
 DEFINE_MGROUP(BMP, "BMP (BGP Monitoring Protocol)");
 
@@ -652,19 +653,26 @@ static int bmp_send_peerup_vrf(struct bmp *bmp)
        return 0;
 }
 
+static void bmp_send_bt(struct bmp_targets *bt, struct stream *s)
+{
+       struct bmp *bmp;
+
+       frr_each (bmp_session, &bt->sessions, bmp)
+               pullwr_write_stream(bmp->pullwr, s);
+}
+
 /* send a stream to all bmp sessions configured in a bgp instance */
 /* XXX: kludge - filling the pullwr's buffer */
 static void bmp_send_all(struct bmp_bgp *bmpbgp, struct stream *s)
 {
        struct bmp_targets *bt;
-       struct bmp *bmp;
 
        if (!s)
                return;
 
        frr_each(bmp_targets, &bmpbgp->targets, bt)
-               frr_each(bmp_session, &bt->sessions, bmp)
-                       pullwr_write_stream(bmp->pullwr, s);
+               bmp_send_bt(bt, s);
+
        stream_free(s);
 }
 
@@ -904,14 +912,10 @@ static int bmp_outgoing_packet(struct peer *peer, uint8_t type, bgp_size_t size,
 
 static int bmp_peer_status_changed(struct peer *peer)
 {
-       struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
        struct bmp_bgp_peer *bbpeer, *bbdopp;
 
        frrtrace(1, frr_bgp, bmp_peer_status_changed, peer);
 
-       if (!bmpbgp)
-               return 0;
-
        if (peer->connection->status == Deleted) {
                bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid);
                if (bbpeer) {
@@ -946,20 +950,16 @@ static int bmp_peer_status_changed(struct peer *peer)
                }
        }
 
-       bmp_send_all_safe(bmpbgp, bmp_peerstate(peer, false));
+       bmp_send_all_bgp(peer, false);
        return 0;
 }
 
 static int bmp_peer_backward(struct peer *peer)
 {
-       struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
        struct bmp_bgp_peer *bbpeer;
 
        frrtrace(1, frr_bgp, bmp_peer_backward_transition, peer);
 
-       if (!bmpbgp)
-               return 0;
-
        bbpeer = bmp_bgp_peer_find(peer->qobj_node.nid);
        if (bbpeer) {
                XFREE(MTYPE_BMP_OPEN, bbpeer->open_tx);
@@ -968,7 +968,7 @@ static int bmp_peer_backward(struct peer *peer)
                bbpeer->open_rx_len = 0;
        }
 
-       bmp_send_all_safe(bmpbgp, bmp_peerstate(peer, true));
+       bmp_send_all_bgp(peer, true);
        return 0;
 }
 
@@ -2249,6 +2249,35 @@ static struct bmp_imported_bgp *bmp_imported_bgp_find(struct bmp_targets *bt, ch
        return bmp_imported_bgps_find(&bt->imported_bgps, &dummy);
 }
 
+static void bmp_send_all_bgp(struct peer *peer, bool down)
+{
+       struct bmp_bgp *bmpbgp = bmp_bgp_find(peer->bgp);
+       struct bgp *bgp_vrf;
+       struct listnode *node;
+       struct stream *s = NULL;
+       struct bmp_targets *bt;
+
+       s = bmp_peerstate(peer, down);
+       if (!s)
+               return;
+
+       if (bmpbgp) {
+               frr_each (bmp_targets, &bmpbgp->targets, bt)
+                       bmp_send_bt(bt, s);
+       }
+       for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, bgp_vrf)) {
+               bmpbgp = bmp_bgp_find(bgp_vrf);
+               if (!bmpbgp)
+                       continue;
+               frr_each (bmp_targets, &bmpbgp->targets, bt) {
+                       if (bgp_vrf != peer->bgp && !bmp_imported_bgp_find(bt, peer->bgp->name))
+                               continue;
+                       bmp_send_bt(bt, s);
+               }
+       }
+       stream_free(s);
+}
+
 static void bmp_imported_bgp_put(struct bmp_targets *bt, struct bmp_imported_bgp *bib)
 {
        bmp_imported_bgps_del(&bt->imported_bgps, bib);