]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: backpressure - fix to properly remove dest for bgp under deletion
authorRajasekar Raja <rajasekarr@nvidia.com>
Wed, 10 Jul 2024 23:46:29 +0000 (16:46 -0700)
committerMergify <37929162+mergify[bot]@users.noreply.github.com>
Tue, 16 Jul 2024 16:15:31 +0000 (16:15 +0000)
In case of imported routes (L3vni/vrf leaks), when a bgp instance is
being deleted, the peer->bgp comparision with the incoming bgp to remove
the dest from the pending fifo is wrong. This can lead to the fifo
having stale entries resulting in crash.

Two changes are done here.
 - Instead of pop/push items in list if the struct bgp doesnt match,
   simply iterate the list and remove the expected ones.

 - Corrected the way bgp is fetched from dest rather than relying on
   path_info->peer so that it works for all kinds of routes.

Ticket :#3980988

Signed-off-by: Chirag Shah <chirag @nvidia.com>
Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>
(cherry picked from commit 4395fcd8e120958a91d3a11f918e9071b1cb5619)

bgpd/bgp_evpn.c
bgpd/bgpd.c

index 6680b54f7665546b493328dbf4b86b157c20ebdb..9a796ef91b4bc8d7c2aec03db107c6c76506c2cc 100644 (file)
@@ -6332,16 +6332,16 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
 void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
 {
        struct bgp_dest *dest = NULL;
-       uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head);
+       struct bgp_dest *dest_next = NULL;
 
-       while (ann_count) {
-               dest = zebra_announce_pop(&bm->zebra_announce_head);
-               ann_count--;
+       for (dest = zebra_announce_first(&bm->zebra_announce_head); dest;
+            dest = dest_next) {
+               dest_next = zebra_announce_next(&bm->zebra_announce_head, dest);
                if (dest->za_vpn == vpn) {
                        bgp_path_info_unlock(dest->za_bgp_pi);
                        bgp_dest_unlock_node(dest);
-               } else
-                       zebra_announce_add_tail(&bm->zebra_announce_head, dest);
+                       zebra_announce_del(&bm->zebra_announce_head, dest);
+               }
        }
 
        bgp_evpn_remote_ip_hash_destroy(vpn);
index 1949ede1244fa2477943e76467b05834a6bd48c2..a5ba540135317437cafde6691f47c82e755dc706 100644 (file)
@@ -3913,19 +3913,25 @@ int bgp_delete(struct bgp *bgp)
        safi_t safi;
        int i;
        struct bgp_dest *dest = NULL;
+       struct bgp_dest *dest_next = NULL;
+       struct bgp_table *dest_table = NULL;
        struct graceful_restart_info *gr_info;
-       uint32_t ann_count = zebra_announce_count(&bm->zebra_announce_head);
 
        assert(bgp);
 
-       while (ann_count) {
-               dest = zebra_announce_pop(&bm->zebra_announce_head);
-               ann_count--;
-               if (dest->za_bgp_pi->peer->bgp == bgp) {
+       /*
+        * Iterate the pending dest list and remove all the dest pertaininig to
+        * the bgp under delete.
+        */
+       for (dest = zebra_announce_first(&bm->zebra_announce_head); dest;
+            dest = dest_next) {
+               dest_next = zebra_announce_next(&bm->zebra_announce_head, dest);
+               dest_table = bgp_dest_table(dest);
+               if (dest_table->bgp == bgp) {
                        bgp_path_info_unlock(dest->za_bgp_pi);
                        bgp_dest_unlock_node(dest);
-               } else
-                       zebra_announce_add_tail(&bm->zebra_announce_head, dest);
+                       zebra_announce_del(&bm->zebra_announce_head, dest);
+               }
        }
 
        bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL);