From f50dc5e6070383e803dc3441aedd5a435974c762 Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Sun, 8 Apr 2018 21:04:11 -0700 Subject: [PATCH] zebra: remote RMAC for EVPN ipv6 hosts should be programmed against the ipv4 nexthop For ipv6 host, the next hop is conevrted to ipv6 mapped address. However, the remote rmac should still be programmed with the ipv4 address. This is how the entries will look in the kernel for ipv6 hosts routing. vrf routing table: ipv6 -> ipv6_mapped remote vtep on l3vni SVI neigh table: ipv6_mapped remote vtep -> remote RMAC bridge fdb: remote rmac -> ipv4 vtep tunnel Signed-off-by: Mitesh Kanjariya --- lib/ipaddr.h | 10 ++++++++++ zebra/zebra_vxlan.c | 28 ++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/lib/ipaddr.h b/lib/ipaddr.h index 33591cb4e7..7f2d06548b 100644 --- a/lib/ipaddr.h +++ b/lib/ipaddr.h @@ -102,4 +102,14 @@ static inline void ipv4_to_ipv4_mapped_ipv6(struct in6_addr *in6, memcpy((char *)in6 + 12, &in, sizeof(struct in_addr)); } +/* + * convert an ipv4 mapped ipv6 address back to ipv4 address + */ +static inline void ipv4_mapped_ipv6_to_ipv4(struct in6_addr *in6, + struct in_addr *in) +{ + memset(in, 0, sizeof(struct in_addr)); + memcpy(in, (char *)in6 + 12, sizeof(struct in_addr)); +} + #endif /* __IPADDR_H__ */ diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index af01cd9c70..6f3b5d26a1 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -3943,16 +3943,36 @@ void zebra_vxlan_evpn_vrf_route_add(vrf_id_t vrf_id, struct ethaddr *rmac, struct prefix *host_prefix) { zebra_l3vni_t *zl3vni = NULL; + struct ipaddr ipv4_vtep; zl3vni = zl3vni_from_vrf(vrf_id); if (!zl3vni || !is_l3vni_oper_up(zl3vni)) return; - /* add the next hop neighbor */ - zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix); + /* + * add the next hop neighbor - + * neigh to be installed is the ipv6 nexthop neigh + */ + zl3vni_remote_nh_add(zl3vni, vtep_ip, rmac, host_prefix); - /* add the rmac */ - zl3vni_remote_rmac_add(zl3vni, rmac, vtep_ip, 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(struct ipaddr)); + 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 + * nexthop address + */ + zl3vni_remote_rmac_add(zl3vni, rmac, &ipv4_vtep, host_prefix); } /* handle evpn vrf route delete */ -- 2.39.5