]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Fix crash on shutdown 2257/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 18 May 2018 01:32:21 +0000 (21:32 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Sat, 19 May 2018 00:40:24 +0000 (20:40 -0400)
There exists code paths where the rn was being used after free.
This eliminates these code paths.

Fixes: CM-21019
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_route.c

index 8394c3a7b7dcb62b9d51c1fe7c195a89e0b4ca62..b924562bd55540507b1ad6405e7b8deb2299f494 100644 (file)
@@ -1853,6 +1853,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                SET_FLAG(ri->flags, BGP_INFO_VALID);
                bgp_info_extra_get(ri);
                ri->extra->parent = bgp_info_lock(parent_ri);
+               bgp_lock_node((struct bgp_node *)parent_ri->net);
                if (parent_ri->extra) {
                        memcpy(&ri->extra->label, &parent_ri->extra->label,
                               sizeof(ri->extra->label));
@@ -1925,6 +1926,7 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                SET_FLAG(ri->flags, BGP_INFO_VALID);
                bgp_info_extra_get(ri);
                ri->extra->parent = bgp_info_lock(parent_ri);
+               bgp_lock_node((struct bgp_node *)parent_ri->net);
                if (parent_ri->extra) {
                        memcpy(&ri->extra->label, &parent_ri->extra->label,
                               sizeof(ri->extra->label));
@@ -3326,7 +3328,7 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p,
        int ret = 0;
        struct prefix_evpn evp;
        char buf[PREFIX_STRLEN];
-  
+
        build_type5_prefix_from_ip_prefix(&evp, p);
        ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
        if (ret)
index bcc448119c169b4dedae419e53c479b72336634d..b58e9da6f41042aec42f763b6042b80be3be12e5 100644 (file)
@@ -571,7 +571,7 @@ leak_update(
                setlabels(new, label, num_labels);
 
        new->extra->parent = bgp_info_lock(parent);
-
+       bgp_lock_node((struct bgp_node *)((struct bgp_info *)parent)->net);
        if (bgp_orig)
                new->extra->bgp_orig = bgp_orig;
        if (nexthop_orig)
index 7bfeee9669a00e37fe1dd6dd228c9f1c9eca3c61..004bdb2ef498c7b18a7bd0c197280e02e04b4884 100644 (file)
@@ -205,6 +205,14 @@ struct bgp_info *bgp_info_new(void)
 /* Free bgp route information. */
 static void bgp_info_free(struct bgp_info *binfo)
 {
+       /* unlink reference to parent, if any. */
+       if (binfo->extra && binfo->extra->parent) {
+               bgp_info_unlock((struct bgp_info *)binfo->extra->parent);
+               bgp_unlock_node((struct bgp_node *)((struct bgp_info *)binfo
+                                                   ->extra->parent)->net);
+               binfo->extra->parent = NULL;
+       }
+
        if (binfo->attr)
                bgp_attr_unintern(&binfo->attr);
 
@@ -225,11 +233,6 @@ struct bgp_info *bgp_info_lock(struct bgp_info *binfo)
 
 struct bgp_info *bgp_info_unlock(struct bgp_info *binfo)
 {
-       /* unlink reference to parent, if any. */
-       if (binfo->extra && binfo->extra->parent) {
-               bgp_info_unlock((struct bgp_info *)binfo->extra->parent);
-               binfo->extra->parent = NULL;
-       }
        assert(binfo && binfo->lock > 0);
        binfo->lock--;