From 45a859f1c3892e4a3ecc0ae731f2a81f1e6e86e9 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 f064f87830..b7b2514838 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c @@ -1316,11 +1316,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); @@ -1367,7 +1370,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 */ @@ -1378,7 +1381,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__); } } } @@ -2320,7 +2323,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; } } @@ -2903,15 +2906,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 d0a32ee408..21c880e95b 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -62,6 +62,7 @@ #include "bgpd/bgp_errors.h" #include "lib/routing_nb.h" #include "bgpd/bgp_nb.h" +#include "bgpd/bgp_evpn_mh.h" #ifdef ENABLE_BGP_VNC #include "bgpd/rfapi/rfapi_backend.h" @@ -207,6 +208,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 959f9e51c6..03a5854d07 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -7298,7 +7298,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