summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_vxlan.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_vxlan.c')
-rw-r--r--zebra/zebra_vxlan.c78
1 files changed, 34 insertions, 44 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index b8c11e18..f1ae42e3 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -1356,6 +1356,18 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni,
{
struct zebra_mac *zrmac = NULL;
struct ipaddr *vtep = NULL;
+ struct ipaddr ipv4_vtep;
+
+ /* vtep_ip may be v4 or v6-mapped-v4. But zrmac->fwd_info
+ * can only contain v4 version. So convert if needed
+ */
+ 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
+ IPV4_ADDR_COPY(&(ipv4_vtep.ipaddr_v4), &vtep_ip->ipaddr_v4);
zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
if (!zrmac) {
@@ -1369,7 +1381,7 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni,
return -1;
}
memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
- zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
+ zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4;
vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
@@ -1383,14 +1395,14 @@ static int zl3vni_remote_rmac_add(struct zebra_l3vni *zl3vni,
/* install rmac in kernel */
zl3vni_rmac_install(zl3vni, zrmac);
} else if (!IPV4_ADDR_SAME(&zrmac->fwd_info.r_vtep_ip,
- &vtep_ip->ipaddr_v4)) {
+ &(ipv4_vtep.ipaddr_v4))) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"L3VNI %u Remote VTEP change(%pI4 -> %pIA) for RMAC %pEA",
zl3vni->vni, &zrmac->fwd_info.r_vtep_ip,
vtep_ip, rmac);
- zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
+ zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4;
vtep = XCALLOC(MTYPE_EVPN_VTEP, sizeof(struct ipaddr));
memcpy(vtep, vtep_ip, sizeof(struct ipaddr));
@@ -1410,36 +1422,29 @@ static void zl3vni_remote_rmac_del(struct zebra_l3vni *zl3vni,
struct zebra_mac *zrmac,
struct ipaddr *vtep_ip)
{
- struct ipaddr ipv4_vtep;
-
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));
-
/* remove nh from rmac's list */
- 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) &&
- listcount(zrmac->nh_list)) {
+ l3vni_rmac_nh_list_nh_delete(zl3vni, zrmac, vtep_ip);
+ /* If there are remaining entries, use IPv4 from one */
+ if (listcount(zrmac->nh_list)) {
struct ipaddr *vtep;
+ struct ipaddr ipv4_vtep;
vtep = listgetdata(listhead(zrmac->nh_list));
- zrmac->fwd_info.r_vtep_ip = vtep->ipaddr_v4;
+ memset(&ipv4_vtep, 0, sizeof(ipv4_vtep));
+ ipv4_vtep.ipa_type = IPADDR_V4;
+ if (vtep->ipa_type == IPADDR_V6)
+ ipv4_mapped_ipv6_to_ipv4(&vtep->ipaddr_v6,
+ &(ipv4_vtep.ipaddr_v4));
+ else
+ IPV4_ADDR_COPY(&(ipv4_vtep.ipaddr_v4),
+ &vtep->ipaddr_v4);
+ zrmac->fwd_info.r_vtep_ip = ipv4_vtep.ipaddr_v4;
if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA",
- zl3vni->vni, &ipv4_vtep,
- &zrmac->fwd_info.r_vtep_ip,
- &zrmac->macaddr);
+ zlog_debug("L3VNI %u Remote VTEP nh change(%pIA -> %pI4) for RMAC %pEA",
+ zl3vni->vni, vtep_ip,
+ &zrmac->fwd_info.r_vtep_ip,
+ &zrmac->macaddr);
/* install rmac in kernel */
zl3vni_rmac_install(zl3vni, zrmac);
@@ -2531,7 +2536,6 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
const struct prefix *host_prefix)
{
struct zebra_l3vni *zl3vni = NULL;
- struct ipaddr ipv4_vtep;
zl3vni = zl3vni_from_vrf(vrf_id);
if (!zl3vni || !is_l3vni_oper_up(zl3vni))
@@ -2547,24 +2551,10 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
svd_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix);
/*
- * if the remote vtep is a ipv4 mapped ipv6 address convert it to ipv4
- * address. Rmac is programmed against the ipv4 vtep because we only
- * support ipv4 tunnels in the h/w right now
- */
- 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));
-
- /*
- * add the rmac - remote rmac to be installed is against the ipv4
+ * add the rmac - remote rmac to be installed is against the
* nexthop address
*/
- zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep);
+ zl3vni_remote_rmac_add(zl3vni, rmac, vtep_ip);
}
/* handle evpn vrf route delete */