bgpd: backpressure - fix to properly remove dest for bgp under deletion

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 4395fcd8e1)
This commit is contained in:
Rajasekar Raja 2024-07-10 16:46:29 -07:00 committed by Mergify
parent ed272429fc
commit 9f9c0bc244
2 changed files with 19 additions and 13 deletions

View 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);

View 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);