Skip to content

Commit

Permalink
zebra: Check both IPv4 and IPv6 NH before removing RMAC
Browse files Browse the repository at this point in the history
IPv4 and IPv4-mapped IPv6 address of a VTEP is used as nexthops of EVPN
routes. Thus should check for both IPv4 and IPv6 before removing RMAC.
Otherwise, withdrawing the last route in one address family breaks
the other.

Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
  • Loading branch information
leonshaw committed Nov 17, 2023
1 parent 93379c0 commit dbf7836
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions zebra/zebra_vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1413,25 +1413,43 @@ static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni,
struct zebra_mac *zrmac,
struct ipaddr *vtep_ip)
{
struct ipaddr ipv4_vtep;
struct ipaddr tmp_ip;
struct ipaddr *ipv4_vtep, *ipv6_nh;

if (!zl3vni_nh_lookup(zl3vni, vtep_ip)) {
memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
ipv4_vtep.ipa_type = IPADDR_V4;
if (vtep_ip->ipa_type == IPADDR_V6)
ipv4_mapped_ipv6_to_ipv4(&vtep_ip->ipaddr_v6,
&ipv4_vtep.ipaddr_v4);
else
memcpy(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4,
sizeof(struct in_addr));
memset(&tmp_ip, 0, sizeof(tmp_ip));
if (vtep_ip->ipa_type == IPADDR_V6) {
if (!IS_MAPPED_IPV6(&vtep_ip->ipaddr_v6)) {
zlog_warn("Unsupported IPv6 EVPN nexthop %pIA", vtep_ip);
return;
}
ipv4_vtep = &tmp_ip;
ipv6_nh = vtep_ip;
ipv4_vtep->ipa_type = IPADDR_V4;
ipv4_mapped_ipv6_to_ipv4(&ipv6_nh->ipaddr_v6,
&ipv4_vtep->ipaddr_v4);
} else {
ipv4_vtep = vtep_ip;
ipv6_nh = &tmp_ip;
ipv6_nh->ipa_type = IPADDR_V6;
ipv4_to_ipv4_mapped_ipv6(&ipv6_nh->ipaddr_v6,
ipv4_vtep->ipaddr_v4);
}

/*
* We may have IPv4 and IPv4-mapped IPv6 address of the VTEP as
* nexthops, but only IPv4 is inserted to rmac nh_list. Check for both
* before deleting from rmac.
*/
if (!zl3vni_nh_lookup(zl3vni, ipv4_vtep) &&
!zl3vni_nh_lookup(zl3vni, ipv6_nh)) {

/* remove nh from rmac's list */
l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, &ipv4_vtep);
l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, ipv4_vtep);
/* delete nh is same as current selected, fall back to
* one present in the list
*/
if (IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
&ipv4_vtep.ipaddr_v4) &&
&ipv4_vtep->ipaddr_v4) &&
listcount(zrmac->nh_list)) {
struct ipaddr *vtep;

Expand All @@ -1440,7 +1458,7 @@ static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni,
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA",
zl3vni->vni, &ipv4_vtep,
zl3vni->vni, ipv4_vtep,
&zrmac->fwd_info.r_vtep_ip,
&zrmac->macaddr);

Expand Down

0 comments on commit dbf7836

Please sign in to comment.