]> 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)
committerIgor Ryzhov <iryzhov@nfware.com>
Wed, 28 Oct 2020 18:35:48 +0000 (21:35 +0300)
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 934c22d1687bc02f44de2e7ea0dabe4f0d1f558f..780981036388cb76a73475013a2e0b6935d368c7 100644 (file)
@@ -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);
index b082aa9c6abef3bf4cd54a064c75f28ecf43d876..fa67cfd56275314c01c945af3a321080d3abb2f4 100644 (file)
@@ -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();
 
index 3c707b41caab32c4e6217da58538c41dd4bcb8ae..cf9ff038de4adee88a3f5a02d51abc8bf880f08f 100644 (file)
@@ -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,