From 5c3375847a20f94acabd5f46fe7a0b9b4914ccb5 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Tue, 20 Oct 2020 09:26:51 -0700 Subject: [PATCH] bgpd: fix crash in the MH cleanup handling The MH datastructures were being released before the paths that were referencing them. Fix is to do the MH cleanup last. The MH finish function has also been stripped down to only do a datastructure cleanup i.e. avoid sending route updates etc. Ticket: 31376 Signed-off-by: Anuradha Karuppiah --- bgpd/bgp_evpn_mh.c | 25 +++++++++++++------------ bgpd/bgp_main.c | 3 +++ bgpd/bgpd.c | 1 - 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c index 934c22d168..7809810363 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -1313,11 +1313,14 @@ static struct bgp_evpn_es *bgp_evpn_es_new(struct bgp *bgp, const esi_t *esi) * This just frees appropriate memory, caller should have taken other * needed actions. */ -static void bgp_evpn_es_free(struct bgp_evpn_es *es) +static void bgp_evpn_es_free(struct bgp_evpn_es *es, const char *caller) { if (es->flags & (BGP_EVPNES_LOCAL | BGP_EVPNES_REMOTE)) return; + if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) + zlog_debug("%s: es %s free", caller, es->esi_str); + /* cleanup resources maintained against the ES */ list_delete(&es->es_evi_list); list_delete(&es->es_vtep_list); @@ -1365,7 +1368,7 @@ static void bgp_evpn_es_local_info_clear(struct bgp_evpn_es *es) bf_release_index(bm->rd_idspace, es->rd_id); - bgp_evpn_es_free(es); + bgp_evpn_es_free(es, __func__); } /* eval remote info associated with the ES */ @@ -1376,7 +1379,7 @@ static void bgp_evpn_es_remote_info_re_eval(struct bgp_evpn_es *es) } else { if (CHECK_FLAG(es->flags, BGP_EVPNES_REMOTE)) { UNSET_FLAG(es->flags, BGP_EVPNES_REMOTE); - bgp_evpn_es_free(es); + bgp_evpn_es_free(es, __func__); } } } @@ -2313,7 +2316,7 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, if (!es_evi) { es_evi = bgp_evpn_es_evi_new(es, vpn); if (!es_evi) { - bgp_evpn_es_free(es); + bgp_evpn_es_free(es, __func__); return -1; } } @@ -2892,15 +2895,13 @@ void bgp_evpn_mh_finish(void) { struct bgp_evpn_es *es; struct bgp_evpn_es *es_next; - struct bgp *bgp; - bgp = bgp_get_evpn(); - if (bgp) { - RB_FOREACH_SAFE(es, bgp_es_rb_head, - &bgp_mh_info->es_rb_tree, es_next) { - /* XXX - need to force free remote ESs here */ - bgp_evpn_local_es_do_del(bgp, es); - } + if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) + zlog_debug("evpn mh finish"); + + RB_FOREACH_SAFE (es, bgp_es_rb_head, &bgp_mh_info->es_rb_tree, + es_next) { + bgp_evpn_es_local_info_clear(es); } thread_cancel(bgp_mh_info->t_cons_check); list_delete(&bgp_mh_info->local_es_list); diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index b082aa9c6a..fa67cfd562 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -60,6 +60,7 @@ #include "bgpd/bgp_keepalives.h" #include "bgpd/bgp_network.h" #include "bgpd/bgp_errors.h" +#include "bgpd/bgp_evpn_mh.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -205,6 +206,8 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) if (bgp_default) bgp_delete(bgp_default); + bgp_evpn_mh_finish(); + /* reverse bgp_dump_init */ bgp_dump_finish(); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 3c707b41ca..cf9ff038de 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7240,7 +7240,6 @@ void bgp_terminate(void) BGP_TIMER_OFF(bm->t_rmap_update); bgp_mac_finish(); - bgp_evpn_mh_finish(); } struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, -- 2.39.5