summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_evpn.c
diff options
context:
space:
mode:
authorStephen Worley <sworley@nvidia.com>2021-07-23 19:35:14 +0200
committerStephen Worley <sworley@nvidia.com>2022-10-11 21:18:39 +0200
commit34c7f35f0217e16447ca0bc6aedd8aba2e51f877 (patch)
tree0ec904baf275d59ae7ecdd758e5f38e727f87d34 /bgpd/bgp_evpn.c
parentzebra: add knob to accept lower seq in evpn (diff)
downloadfrr-34c7f35f0217e16447ca0bc6aedd8aba2e51f877.tar.xz
frr-34c7f35f0217e16447ca0bc6aedd8aba2e51f877.zip
bgpd: rework VNI table for type2/macip routes
Use the IP addr of type2/macip routes only for the hash/key of the VNI table and carry the MAC in a path_info_extra attribute. There is exists situations that can be hit during extended MAC mobility events where two MACs could be pointing to the same IP in our global table. It is requires very specific timings. When that happens, BPG would (because we key'd on both MAC and IP) install both into it's VNI table as separate entries, but zebra only knows/needs to know about a single IP -> MAC relationship for it's VNI table's type2 routes. So it was compleletly undeterministic which one zebra would end up with in these timing situations. With these changes, we move BGP's VNI table to key'd the same as Zebra's and now a single IP will have multiple path_info's with a path_info_extra that is carrying the MAC info for each path. BGP will then run best path to deterministically decide which one to send to zebra during the occasions where there exist's two possible MACs. Signed-off-by: Stephen Worley <sworley@nvidia.com>
Diffstat (limited to 'bgpd/bgp_evpn.c')
-rw-r--r--bgpd/bgp_evpn.c284
1 files changed, 198 insertions, 86 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 58f5e9a22..4e5a62ce4 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -552,10 +552,14 @@ static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
}
-struct bgp_dest *bgp_global_evpn_node_get(struct bgp_table *table, afi_t afi,
+/*
+ * Wrapper for node get in global table.
+ */
+struct bgp_dest *bgp_evpn_global_node_get(struct bgp_table *table, afi_t afi,
safi_t safi,
const struct prefix_evpn *evp,
- struct prefix_rd *prd)
+ struct prefix_rd *prd,
+ const struct bgp_path_info *local_pi)
{
struct prefix_evpn global_p;
@@ -565,14 +569,28 @@ struct bgp_dest *bgp_global_evpn_node_get(struct bgp_table *table, afi_t afi,
*/
evpn_type1_prefix_global_copy(&global_p, evp);
evp = &global_p;
+ } else if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
+ local_pi) {
+ /*
+ * prefix in the global table needs MAC, ensure it's present,
+ * using one from local table's path_info.
+ */
+ evpn_type2_prefix_global_copy(
+ &global_p, evp,
+ *evpn_type2_path_info_get_mac(local_pi));
+ evp = &global_p;
}
return bgp_afi_node_get(table, afi, safi, (struct prefix *)evp, prd);
}
-struct bgp_dest *bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi,
- safi_t safi,
- const struct prefix_evpn *evp,
- struct prefix_rd *prd)
+/*
+ * Wrapper for node lookup in global table.
+ */
+struct bgp_dest *
+bgp_evpn_global_node_lookup(struct bgp_table *table, afi_t afi, safi_t safi,
+ const struct prefix_evpn *evp,
+ struct prefix_rd *prd,
+ const struct bgp_path_info *local_pi)
{
struct prefix_evpn global_p;
@@ -582,15 +600,86 @@ struct bgp_dest *bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi,
*/
evpn_type1_prefix_global_copy(&global_p, evp);
evp = &global_p;
+ } else if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
+ local_pi) {
+ /*
+ * prefix in the global table needs MAC, ensure it's present,
+ * using one from local table's path_info.
+ */
+ evpn_type2_prefix_global_copy(
+ &global_p, evp,
+ *evpn_type2_path_info_get_mac(local_pi));
+ evp = &global_p;
}
return bgp_afi_node_lookup(table, afi, safi, (struct prefix *)evp, prd);
}
/*
+ * Wrapper for node get in VNI table.
+ */
+struct bgp_dest *bgp_evpn_vni_node_get(struct bgp_table *const table,
+ const struct prefix_evpn *evp,
+ const struct bgp_path_info *parent_pi)
+{
+ struct prefix_evpn vni_p;
+
+ if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE && parent_pi) {
+ /* prefix in the global table doesn't include the VTEP-IP so
+ * we need to create a different copy for the VNI
+ */
+ evpn_type1_prefix_vni_copy(&vni_p, evp,
+ parent_pi->attr->nexthop);
+ evp = &vni_p;
+ } else if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
+ !is_evpn_prefix_ipaddr_none(evp)) {
+ /*
+ * IP prefix in the vni table doesn't include MAC so
+ * we need to create a different copy of the prefix.
+ *
+ * However, if it's MAC-only, keep it.
+ */
+ evpn_type2_prefix_vni_copy(&vni_p, evp);
+ evp = &vni_p;
+ }
+ return bgp_node_get(table, (struct prefix *)evp);
+}
+
+/*
+ * Wrapper for node lookup in VNI table.
+ */
+struct bgp_dest *bgp_evpn_vni_node_lookup(const struct bgp_table *const table,
+ const struct prefix_evpn *evp,
+ const struct bgp_path_info *parent_pi)
+{
+ struct prefix_evpn vni_p;
+
+ if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE && parent_pi) {
+ /* prefix in the global table doesn't include the VTEP-IP so
+ * we need to create a different copy for the VNI
+ */
+ evpn_type1_prefix_vni_copy(&vni_p, evp,
+ parent_pi->attr->nexthop);
+ evp = &vni_p;
+ } else if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
+ !is_evpn_prefix_ipaddr_none(evp)) {
+ /*
+ * IP prefix in the vni table doesn't include MAC so
+ * we need to create a different copy of the prefix.
+ *
+ * However, if it's MAC-only, keep it.
+ */
+ evpn_type2_prefix_vni_copy(&vni_p, evp);
+ evp = &vni_p;
+ }
+ return bgp_node_lookup(table, (struct prefix *)evp);
+}
+
+/*
* Add (update) or delete MACIP from zebra.
*/
static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
const struct prefix_evpn *p,
+ const struct ethaddr *mac,
struct in_addr remote_vtep_ip, int add,
uint8_t flags, uint32_t seq, esi_t *esi)
{
@@ -620,7 +709,12 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
s, add ? ZEBRA_REMOTE_MACIP_ADD : ZEBRA_REMOTE_MACIP_DEL,
bgp->vrf_id);
stream_putl(s, vpn->vni);
- stream_put(s, &p->prefix.macip_addr.mac.octet, ETH_ALEN); /* Mac Addr */
+
+ if (mac) /* Mac Addr */
+ stream_put(s, &mac->octet, ETH_ALEN);
+ else
+ stream_put(s, &p->prefix.macip_addr.mac.octet, ETH_ALEN);
+
/* IP address length and IP address, if any. */
if (is_evpn_prefix_ipaddr_none(p))
stream_putw(s, 0);
@@ -985,8 +1079,9 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
}
ret = bgp_zebra_send_remote_macip(
- bgp, vpn, p, pi->attr->nexthop, 1, flags,
- seq, bgp_evpn_attr_get_esi(pi->attr));
+ bgp, vpn, p, evpn_type2_path_info_get_mac(pi),
+ pi->attr->nexthop, 1, flags, seq,
+ bgp_evpn_attr_get_esi(pi->attr));
} else if (p->prefix.route_type == BGP_EVPN_AD_ROUTE) {
ret = bgp_evpn_remote_es_evi_add(bgp, vpn, p);
} else {
@@ -1012,13 +1107,15 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
/* Uninstall EVPN route from zebra. */
static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
const struct prefix_evpn *p,
- struct in_addr remote_vtep_ip)
+ struct bgp_path_info *pi, bool is_sync)
{
int ret;
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
- ret = bgp_zebra_send_remote_macip(bgp, vpn, p, remote_vtep_ip,
- 0, 0, 0, NULL);
+ ret = bgp_zebra_send_remote_macip(
+ bgp, vpn, p, evpn_type2_path_info_get_mac(pi),
+ (is_sync ? zero_vtep_ip : pi->attr->nexthop), 0, 0, 0,
+ NULL);
else if (p->prefix.route_type == BGP_EVPN_AD_ROUTE)
ret = bgp_evpn_remote_es_evi_del(bgp, vpn, p);
else
@@ -1061,9 +1158,10 @@ static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn,
* this table is a 2-level tree (RD-level + Prefix-level) similar to
* L3VPN routes.
*/
- global_dest = bgp_global_evpn_node_lookup(bgp->rib[afi][safi], afi, safi,
- (const struct prefix_evpn *)bgp_dest_get_prefix(dest),
- &vpn->prd);
+ global_dest = bgp_evpn_global_node_lookup(
+ bgp->rib[afi][safi], afi, safi,
+ (const struct prefix_evpn *)bgp_dest_get_prefix(dest),
+ &vpn->prd, old_local);
if (global_dest) {
/* Delete route entry in the global EVPN table. */
delete_evpn_route_entry(bgp, afi, safi, global_dest, &pi);
@@ -1176,7 +1274,7 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
bgp, vpn,
(const struct prefix_evpn *)bgp_dest_get_prefix(
dest),
- old_select->attr->nexthop);
+ old_select, false);
}
/* Clear any route change flags. */
@@ -1362,9 +1460,8 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
build_evpn_type5_route_extcomm(bgp_vrf, &attr);
/* get the route node in global table */
- dest = bgp_global_evpn_node_get(bgp_evpn->rib[afi][safi], afi, safi,
- (const struct prefix_evpn *)evp,
- &bgp_vrf->vrf_prd);
+ dest = bgp_evpn_global_node_get(bgp_evpn->rib[afi][safi], afi, safi,
+ evp, &bgp_vrf->vrf_prd, NULL);
assert(dest);
/* create or update the route entry within the route node */
@@ -1515,9 +1612,9 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp,
static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
afi_t afi, safi_t safi,
struct bgp_dest *dest, struct attr *attr,
- int add, struct bgp_path_info **pi,
- uint8_t flags, uint32_t seq, bool vpn_rt,
- bool *old_is_sync)
+ const struct ethaddr *mac, int add,
+ struct bgp_path_info **pi, uint8_t flags,
+ uint32_t seq, bool vpn_rt, bool *old_is_sync)
{
struct bgp_path_info *tmp_pi;
struct bgp_path_info *local_pi;
@@ -1589,6 +1686,11 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
memcpy(&tmp_pi->extra->label, label, sizeof(label));
tmp_pi->extra->num_labels = num_labels;
+
+ if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && mac)
+ evpn_type2_path_info_set_mac(tmp_pi, *mac);
+
+
/* Mark route as self type-2 route */
if (flags && CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_SVI_IP))
tmp_pi->extra->af_flags = BGP_EVPN_MACIP_TYPE_SVI_IP;
@@ -1618,6 +1720,10 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
memcpy(&tmp_pi->extra->label, label, sizeof(label));
tmp_pi->extra->num_labels = num_labels;
+ if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE &&
+ mac)
+ evpn_type2_path_info_set_mac(tmp_pi, *mac);
+
/* The attribute has changed. */
/* Add (or update) attribute to hash. */
attr_new = bgp_attr_intern(attr);
@@ -1798,12 +1904,12 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
/* First, create (or fetch) route node within the VNI. */
/* NOTE: There is no RD here. */
- dest = bgp_node_get(vpn->route_table, (struct prefix *)p);
+ dest = bgp_evpn_vni_node_get(vpn->route_table, p, NULL);
/* Create or update route entry. */
- route_change = update_evpn_route_entry(bgp, vpn, afi, safi, dest, &attr,
- 1, &pi, flags, seq,
- true /* setup_sync */, &old_is_sync);
+ route_change = update_evpn_route_entry(
+ bgp, vpn, afi, safi, dest, &attr, &p->prefix.macip_addr.mac, 1,
+ &pi, flags, seq, true /* setup_sync */, &old_is_sync);
assert(pi);
attr_new = pi->attr;
@@ -1841,7 +1947,7 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
*/
new_is_sync = bgp_evpn_attr_is_sync(pi->attr);
if (!new_is_sync && old_is_sync)
- evpn_zebra_uninstall(bgp, vpn, p, zero_vtep_ip);
+ evpn_zebra_uninstall(bgp, vpn, p, pi, true);
}
}
bgp_path_info_unlock(pi);
@@ -1856,12 +1962,12 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
if (route_change) {
struct bgp_path_info *global_pi;
- dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi,
- (const struct prefix_evpn *)p,
- &vpn->prd);
- update_evpn_route_entry(bgp, vpn, afi, safi, dest, attr_new, 1,
- &global_pi, flags, seq,
- false /* setup_sync */, NULL /* old_is_sync */);
+ dest = bgp_evpn_global_node_get(bgp->rib[afi][safi], afi, safi,
+ p, &vpn->prd, NULL);
+ update_evpn_route_entry(bgp, vpn, afi, safi, dest, attr_new,
+ NULL /* mac */, 1, &global_pi, flags,
+ seq, false /* setup_sync */,
+ NULL /* old_is_sync */);
/* Schedule for processing and unlock node. */
bgp_process(bgp, dest, afi, safi);
@@ -1915,8 +2021,8 @@ static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp)
return 0;
/* locate the global route entry for this type-5 prefix */
- dest = bgp_global_evpn_node_lookup(bgp_evpn->rib[afi][safi], afi, safi,
- (const struct prefix_evpn *)evp, &bgp_vrf->vrf_prd);
+ dest = bgp_evpn_global_node_lookup(bgp_evpn->rib[afi][safi], afi, safi,
+ evp, &bgp_vrf->vrf_prd, NULL);
if (!dest)
return 0;
@@ -1944,7 +2050,7 @@ static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
* is nothing further to do.
*/
/* NOTE: There is no RD here. */
- dest = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
+ dest = bgp_evpn_vni_node_lookup(vpn->route_table, p, NULL);
if (!dest)
return 0;
@@ -1952,8 +2058,8 @@ static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
* this table is a 2-level tree (RD-level + Prefix-level) similar to
* L3VPN routes.
*/
- global_dest = bgp_global_evpn_node_lookup(bgp->rib[afi][safi], afi, safi,
- (const struct prefix_evpn *)p, &vpn->prd);
+ global_dest = bgp_evpn_global_node_lookup(bgp->rib[afi][safi], afi,
+ safi, p, &vpn->prd, NULL);
if (global_dest) {
/* Delete route entry in the global EVPN table. */
delete_evpn_route_entry(bgp, afi, safi, global_dest, &pi);
@@ -1992,8 +2098,7 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
int add_l3_ecomm = 0;
struct bgp_dest *global_dest;
struct bgp_path_info *global_pi;
- struct prefix_evpn *evp =
- (struct prefix_evpn *)bgp_dest_get_prefix(dest);
+ struct prefix_evpn evp;
int route_change;
bool old_is_sync = false;
@@ -2001,6 +2106,13 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
return;
/*
+ * VNI table MAC-IP prefixes don't have MAC so make sure it's set from
+ * path info here.
+ */
+ evpn_type2_prefix_global_copy(&evp, (struct prefix_evpn *)&dest->p,
+ *evpn_type2_path_info_get_mac(local_pi));
+
+ /*
* Build attribute per local route as the MAC mobility and
* some other values could differ for different routes. The
* attributes will be shared in the hash table.
@@ -2014,18 +2126,17 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
attr.es_flags = local_pi->attr->es_flags;
if (local_pi->attr->default_gw) {
attr.default_gw = 1;
- if (is_evpn_prefix_ipaddr_v6(evp))
+ if (is_evpn_prefix_ipaddr_v6(&evp))
attr.router_flag = 1;
}
memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t));
- bgp_evpn_get_rmac_nexthop(vpn, evp, &attr,
- local_pi->extra->af_flags);
+ bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr, local_pi->extra->af_flags);
vni2label(vpn->vni, &(attr.label));
/* Add L3 VNI RTs and RMAC for non IPv6 link-local if
* using L3 VNI for type-2 routes also.
*/
add_l3_ecomm = bgp_evpn_route_add_l3_ecomm_ok(
- vpn, evp,
+ vpn, &evp,
(attr.es_flags & ATTR_ES_IS_LOCAL) ? &attr.esi : NULL);
/* Set up extended community. */
@@ -2039,15 +2150,15 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
"VRF %s vni %u evp %pFX RMAC %pEA nexthop %pI4 esi %s esf 0x%x from %s",
vpn->bgp_vrf ? vrf_id_to_name(vpn->bgp_vrf->vrf_id)
: " ",
- vpn->vni, evp, &attr.rmac, &attr.mp_nexthop_global_in,
+ vpn->vni, &evp, &attr.rmac, &attr.mp_nexthop_global_in,
esi_to_str(&attr.esi, buf3, sizeof(buf3)),
attr.es_flags, caller);
}
/* Update the route entry. */
route_change = update_evpn_route_entry(
- bgp, vpn, afi, safi, dest, &attr, 0, &pi, 0, seq,
- true /* setup_sync */, &old_is_sync);
+ bgp, vpn, afi, safi, dest, &attr, NULL /* mac */, 0, &pi, 0,
+ seq, true /* setup_sync */, &old_is_sync);
assert(pi);
attr_new = pi->attr;
@@ -2082,8 +2193,7 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
*/
new_is_sync = bgp_evpn_attr_is_sync(pi->attr);
if (!new_is_sync && old_is_sync)
- evpn_zebra_uninstall(bgp, vpn,
- evp, zero_vtep_ip);
+ evpn_zebra_uninstall(bgp, vpn, &evp, pi, true);
}
}
@@ -2093,13 +2203,14 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
if (route_change) {
/* Update route in global routing table. */
- global_dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi,
- safi, evp, &vpn->prd);
+ global_dest = bgp_evpn_global_node_get(
+ bgp->rib[afi][safi], afi, safi, &evp, &vpn->prd, NULL);
assert(global_dest);
- update_evpn_route_entry(
- bgp, vpn, afi, safi, global_dest, attr_new, 0,
- &global_pi, 0, mac_mobility_seqnum(attr_new),
- false /* setup_sync */, NULL /* old_is_sync */);
+ update_evpn_route_entry(bgp, vpn, afi, safi, global_dest,
+ attr_new, NULL /* mac */, 0, &global_pi,
+ 0, mac_mobility_seqnum(attr_new),
+ false /* setup_sync */,
+ NULL /* old_is_sync */);
/* Schedule for processing and unlock node. */
bgp_process(bgp, global_dest, afi, safi);
@@ -2400,6 +2511,7 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi,
pi->extra->num_labels = parent_pi->extra->num_labels;
pi->extra->igpmetric = parent_pi->extra->igpmetric;
}
+
bgp_path_info_add(dest, pi);
return pi;
@@ -2589,20 +2701,12 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
struct bgp_path_info *local_pi;
struct attr *attr_new;
int ret;
- struct prefix_evpn ad_evp;
bool old_local_es = false;
bool new_local_es;
- /* EAD prefix in the global table doesn't include the VTEP-IP so
- * we need to create a different copy for the VNI
- */
- if (p->prefix.route_type == BGP_EVPN_AD_ROUTE)
- p = evpn_type1_prefix_vni_copy(&ad_evp, p,
- parent_pi->attr->nexthop);
-
/* Create (or fetch) route within the VNI. */
/* NOTE: There is no RD here. */
- dest = bgp_node_get(vpn->route_table, (struct prefix *)p);
+ dest = bgp_evpn_vni_node_get(vpn->route_table, p, parent_pi);
/* Check if route entry is already present. */
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
@@ -2614,6 +2718,11 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
/* Create an info */
pi = bgp_create_evpn_bgp_path_info(parent_pi, dest,
parent_pi->attr);
+
+ if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
+ evpn_type2_path_info_set_mac(pi,
+ p->prefix.macip_addr.mac);
+
new_local_es = bgp_evpn_attr_is_local_es(pi->attr);
} else {
if (attrhash_cmp(pi->attr, parent_pi->attr)
@@ -2765,18 +2874,10 @@ static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
struct bgp_path_info *pi;
struct bgp_path_info *local_pi;
int ret;
- struct prefix_evpn ad_evp;
-
- /* EAD prefix in the global table doesn't include the VTEP-IP so
- * we need to create a different copy for the VNI
- */
- if (p->prefix.route_type == BGP_EVPN_AD_ROUTE)
- p = evpn_type1_prefix_vni_copy(&ad_evp, p,
- parent_pi->attr->nexthop);
/* Locate route within the VNI. */
/* NOTE: There is no RD here. */
- dest = bgp_node_lookup(vpn->route_table, (struct prefix *)p);
+ dest = bgp_evpn_vni_node_lookup(vpn->route_table, p, parent_pi);
if (!dest)
return 0;
@@ -3623,7 +3724,7 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
if (bgp_evpn_vni_flood_mode_get(bgp, vpn)
== VXLAN_FLOOD_HEAD_END_REPL) {
build_evpn_type3_prefix(&p, vpn->originator_ip);
- dest = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
+ dest = bgp_evpn_vni_node_lookup(vpn->route_table, &p, NULL);
if (!dest) /* unexpected */
return 0;
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
@@ -3637,11 +3738,12 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
}
attr = pi->attr;
- global_dest = bgp_global_evpn_node_get(bgp->rib[afi][safi],
- afi, safi, &p, &vpn->prd);
- update_evpn_route_entry(bgp, vpn, afi, safi, global_dest, attr,
- 1, &pi, 0, mac_mobility_seqnum(attr),
- false /* setup_sync */, NULL /* old_is_sync */);
+ global_dest = bgp_evpn_global_node_get(
+ bgp->rib[afi][safi], afi, safi, &p, &vpn->prd, NULL);
+ update_evpn_route_entry(
+ bgp, vpn, afi, safi, global_dest, attr, NULL /* mac */,
+ 1, &pi, 0, mac_mobility_seqnum(attr),
+ false /* setup_sync */, NULL /* old_is_sync */);
/* Schedule for processing and unlock node. */
bgp_process(bgp, global_dest, afi, safi);
@@ -3653,6 +3755,7 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
*/
for (dest = bgp_table_top(vpn->route_table); dest;
dest = bgp_route_next(dest)) {
+ struct prefix_evpn tmp_evp;
const struct prefix_evpn *evp =
(const struct prefix_evpn *)bgp_dest_get_prefix(dest);
@@ -3672,19 +3775,28 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
if (!pi)
continue;
+ /*
+ * VNI table MAC-IP prefixes don't have MAC so make sure it's
+ * set from path info here.
+ */
+ evpn_type2_prefix_global_copy(
+ &tmp_evp, evp, *evpn_type2_path_info_get_mac(pi));
+
/* Create route in global routing table using this route entry's
* attribute.
*/
attr = pi->attr;
- global_dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi,
- evp, &vpn->prd);
+ global_dest =
+ bgp_evpn_global_node_get(bgp->rib[afi][safi], afi, safi,
+ &tmp_evp, &vpn->prd, NULL);
assert(global_dest);
if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
/* Type-2 route */
update_evpn_route_entry(
- bgp, vpn, afi, safi, global_dest, attr, 1,
- &global_pi, 0, mac_mobility_seqnum(attr),
+ bgp, vpn, afi, safi, global_dest, attr,
+ NULL /* mac */, 1, &global_pi, 0,
+ mac_mobility_seqnum(attr),
false /* setup_sync */, NULL /* old_is_sync */);
} else {
/* Type-1 route */
@@ -3724,8 +3836,8 @@ static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
/* Remove type-3 route for this VNI from global table. */
build_evpn_type3_prefix(&p, vpn->originator_ip);
- global_dest = bgp_global_evpn_node_lookup(bgp->rib[afi][safi], afi, safi,
- (const struct prefix_evpn *)&p, &vpn->prd);
+ global_dest = bgp_evpn_global_node_lookup(bgp->rib[afi][safi], afi,
+ safi, &p, &vpn->prd, NULL);
if (global_dest) {
/* Delete route entry in the global EVPN table. */
delete_evpn_route_entry(bgp, afi, safi, global_dest, &pi);
@@ -5482,7 +5594,7 @@ int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
delete_evpn_route(bgp, vpn, &p);
} else {
/* Re-instate the current remote best path if any */
- dest = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
+ dest = bgp_evpn_vni_node_lookup(vpn->route_table, &p, NULL);
if (dest) {
evpn_zebra_reinstall_best_route(bgp, vpn, dest);
bgp_dest_unlock_node(dest);