From 7c82b3120ee18e50ca0689ac6717e94f2067b7ac Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 17 May 2018 21:32:21 -0400 Subject: [PATCH] bgpd: Fix crash on shutdown 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 --- bgpd/bgp_evpn.c | 4 +++- bgpd/bgp_mplsvpn.c | 2 +- bgpd/bgp_route.c | 13 ++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 8394c3a7b7..b924562bd5 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -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) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index bcc448119c..b58e9da6f4 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -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) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7bfeee9669..004bdb2ef4 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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--; -- 2.39.5