]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: fix crash in the MH cleanup handling
authorAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Tue, 20 Oct 2020 16:26:51 +0000 (09:26 -0700)
committerAnuradha Karuppiah <anuradhak@cumulusnetworks.com>
Wed, 21 Oct 2020 16:09:21 +0000 (09:09 -0700)
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>
bgpd/bgp_evpn_mh.c
bgpd/bgp_main.c
bgpd/bgpd.c

index f064f8783020875d380365c9f127535ba0f0128b..b7b25148389f7e93963bbc438003582546fbdcb8 100644 (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);
index d0a32ee408199c8aa2a4af9f144e79d5a9624452..21c880e95b2b79133f1130f588b87981373b9844 100644 (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();
 
index 959f9e51c6eeb2896c7c0842e2dc7f03d3b26a4e..03a5854d07a652683973641bf76b3eb5ffa609fb 100644 (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,