]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Update parent entry's refcount for imported routes
authorvivek <vivek@cumulusnetworks.com>
Wed, 9 May 2018 05:16:04 +0000 (22:16 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 11 May 2018 12:02:05 +0000 (08:02 -0400)
Imported routes in a VRF routing table have a reference to their parent
route entry which resides in the EVPN or IPVPN routing table. Ensure that
this reference uses appropriate locking so that the parent entry doesn't
get freed prematurely.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
(cherry picked from commit 13cb6b22ba9d558b1b4a1e8752f63f13242462a7)

Conflicts:
bgpd/bgp_mplsvpn.c

Ticket: CM-20471
Testing Done:
a) Ran vrf_route_leak tests without fix and hit crash, ran twice with fix
and did not see the crash.
b) Ran evpn-smoke and ensured there were no new failures.

bgpd/bgp_evpn.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_route.c

index ad45da84eb207d36faa26c6b5994649b6584df7c..02dd64f1a38e67923ab004e603275291120ac4e2 100644 (file)
@@ -1841,7 +1841,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                               parent_ri->peer, attr_new, rn);
                SET_FLAG(ri->flags, BGP_INFO_VALID);
                bgp_info_extra_get(ri);
-               ri->extra->parent = parent_ri;
+               ri->extra->parent = bgp_info_lock(parent_ri);
                if (parent_ri->extra) {
                        memcpy(&ri->extra->label, &parent_ri->extra->label,
                               sizeof(ri->extra->label));
@@ -1913,7 +1913,7 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                               parent_ri->peer, attr_new, rn);
                SET_FLAG(ri->flags, BGP_INFO_VALID);
                bgp_info_extra_get(ri);
-               ri->extra->parent = parent_ri;
+               ri->extra->parent = bgp_info_lock(parent_ri);
                if (parent_ri->extra) {
                        memcpy(&ri->extra->label, &parent_ri->extra->label,
                               sizeof(ri->extra->label));
index 64d12cf6078540c26bbc42938d60a5bde3a10d6b..55365df2995ffa8580d4e23ab3aae15b831842ff 100644 (file)
@@ -569,7 +569,7 @@ leak_update(
                setlabels(new, label, num_labels);
 
        bgp_info_extra_get(new);
-       new->extra->parent = parent;
+       new->extra->parent = bgp_info_lock(parent);
 
        if (bgp_orig)
                new->extra->bgp_orig = bgp_orig;
index cfaa04a8c971d01df863feac01c11d0ad105f90b..424fc4bc03fc03fd57a73de7fcae42c83cfe72da 100644 (file)
@@ -225,6 +225,11 @@ 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--;