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 <anuradhak@cumulusnetworks.com>
This commit is contained in:
Anuradha Karuppiah 2020-10-20 09:26:51 -07:00
parent dad65cbe73
commit 45a859f1c3
3 changed files with 16 additions and 13 deletions

View File

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

View File

@ -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();

View File

@ -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,