From 1b09e77e4d0752e6e29affbd440dbb82dcee5044 Mon Sep 17 00:00:00 2001 From: Ameya Dharkar Date: Mon, 11 Jan 2021 11:08:43 -0800 Subject: [PATCH] Zebra: FPM support for gateway IP overlay Index FPM sends VNI to the data plane with the EVPN prefix. For pure type-5 EVPN route, nexthop interface of EVPN prefix is L3VNI SVI. Thus, we encode L3VNI corresponding to the nexthop vrf with rtmsg for this prefix. For EVPN type-5 route with gateway IP overlay index, we supporting asymmetric IRB. Thus, nexthop interface is L2VNI SVI. So, instead of fetching vrf VNI, fetch VNI corresponding to the nexthop SVI and encode it in the rtmsg for EVPN prefix. Signed-off-by: Ameya Dharkar --- zebra/zebra_fpm_netlink.c | 33 +++++++++++++++++++++++++++------ zebra/zebra_vxlan.c | 21 +++++++++++++++++++++ zebra/zebra_vxlan_private.h | 1 + 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index cebd576365..efbd078a52 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -42,6 +42,7 @@ #include "zebra/zebra_fpm_private.h" #include "zebra/zebra_vxlan_private.h" +#include "zebra/interface.h" /* * af_addr_size @@ -164,7 +165,10 @@ static int netlink_route_info_add_nh(struct netlink_route_info *ri, { struct netlink_nh_info nhi; union g_addr *src; - zebra_l3vni_t *zl3vni = NULL; + struct zebra_vrf *zvrf = NULL; + struct interface *ifp = NULL, *link_if = NULL; + struct zebra_if *zif = NULL; + vni_t vni = 0; memset(&nhi, 0, sizeof(nhi)); src = NULL; @@ -199,12 +203,29 @@ static int netlink_route_info_add_nh(struct netlink_route_info *ri, if (re && CHECK_FLAG(re->flags, ZEBRA_FLAG_EVPN_ROUTE)) { nhi.encap_info.encap_type = FPM_NH_ENCAP_VXLAN; - zl3vni = zl3vni_from_vrf(nexthop->vrf_id); - if (zl3vni && is_l3vni_oper_up(zl3vni)) { - - /* Add VNI to VxLAN encap info */ - nhi.encap_info.vxlan_encap.vni = zl3vni->vni; + /* Extract VNI id for the nexthop SVI interface */ + zvrf = zebra_vrf_lookup_by_id(nexthop->vrf_id); + if (zvrf) { + ifp = if_lookup_by_index_per_ns(zvrf->zns, + nexthop->ifindex); + if (ifp) { + zif = (struct zebra_if *)ifp->info; + if (zif) { + if (IS_ZEBRA_IF_BRIDGE(ifp)) + link_if = ifp; + else if (IS_ZEBRA_IF_VLAN(ifp)) + link_if = + if_lookup_by_index_per_ns( + zvrf->zns, + zif->link_ifindex); + if (link_if) + vni = vni_id_from_svi(ifp, + link_if); + } + } } + + nhi.encap_info.vxlan_encap.vni = vni; } /* diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 99df49a46b..2f3ea7475a 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1842,6 +1842,27 @@ static zebra_l3vni_t *zl3vni_from_svi(struct interface *ifp, return zl3vni; } +vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if) +{ + vni_t vni = 0; + zebra_evpn_t *zevpn = NULL; + zebra_l3vni_t *zl3vni = NULL; + + /* Check if an L3VNI belongs to this SVI interface. + * If not, check if an L2VNI belongs to this SVI interface. + */ + zl3vni = zl3vni_from_svi(ifp, br_if); + if (zl3vni) + vni = zl3vni->vni; + else { + zevpn = zebra_evpn_from_svi(ifp, br_if); + if (zevpn) + vni = zevpn->vni; + } + + return vni; +} + static inline void zl3vni_get_vrr_rmac(zebra_l3vni_t *zl3vni, struct ethaddr *rmac) { diff --git a/zebra/zebra_vxlan_private.h b/zebra/zebra_vxlan_private.h index 0556c4adce..84ac76b3b9 100644 --- a/zebra/zebra_vxlan_private.h +++ b/zebra/zebra_vxlan_private.h @@ -224,6 +224,7 @@ extern struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni); extern struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni); extern struct interface *zl3vni_map_to_mac_vlan_if(zebra_l3vni_t *zl3vni); extern zebra_l3vni_t *zl3vni_lookup(vni_t vni); +extern vni_t vni_id_from_svi(struct interface *ifp, struct interface *br_if); DECLARE_HOOK(zebra_rmac_update, (zebra_mac_t *rmac, zebra_l3vni_t *zl3vni, bool delete, const char *reason), (rmac, zl3vni, delete, reason));