summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--zebra/zebra_fpm_netlink.c33
-rw-r--r--zebra/zebra_vxlan.c21
-rw-r--r--zebra/zebra_vxlan_private.h1
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));