summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_evpn.c11
-rw-r--r--bgpd/bgp_mplsvpn.c2
-rw-r--r--bgpd/bgp_route.c5
3 files changed, 13 insertions, 5 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index a8676ab37c..ee53beb191 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -1819,12 +1819,15 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
/* EVPN routes currently only support a IPv4 next hop which corresponds
* to the remote VTEP. When importing into a VRF, if it is IPv6 host
- * route, we have to convert the next hop to an IPv4-mapped address
- * for the rest of the code to flow through.
+ * or prefix route, we have to convert the next hop to an IPv4-mapped
+ * address for the rest of the code to flow through. In the case of IPv4,
+ * make sure to set the flag for next hop attribute.
*/
bgp_attr_dup(&attr, parent_ri->attr);
if (afi == AFI_IP6)
evpn_convert_nexthop_to_ipv6(&attr);
+ else
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
/* Check if route entry is already present. */
for (ri = rn->info; ri; ri = ri->next)
@@ -1841,7 +1844,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 +1916,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));
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 64d12cf607..55365df299 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -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;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index fd5648ac39..997d708baf 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -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--;