]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra: data structure changes for single vxlan device
authorSharath Ramamurthy <sramamurthy@nvidia.com>
Tue, 27 Jul 2021 07:44:15 +0000 (13:14 +0530)
committerStephen Worley <sworley@nvidia.com>
Mon, 13 Feb 2023 23:12:04 +0000 (18:12 -0500)
This changeset introduces the data structure changes needed for
single vxlan device functionality. A new struct zebra_vxlan_vni_info
encodes the iftype and vni information for vxlan device.

The change addresses related access changes of the new data structure
fields from different files

zebra_vty is modified to take care of the vni dump information according
to the new vni data structure for vxlan devices.

Signed-off-by: Sharath Ramamurthy <sramamurthy@nvidia.com>
14 files changed:
zebra/dplane_fpm_nl.c
zebra/if_netlink.c
zebra/interface.c
zebra/rt_netlink.c
zebra/zebra_evpn.c
zebra/zebra_evpn.h
zebra/zebra_evpn_mac.c
zebra/zebra_evpn_mh.c
zebra/zebra_evpn_mh.h
zebra/zebra_l2.c
zebra/zebra_l2.h
zebra/zebra_nb_state.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h

index 0a9fecc9dff1b306ac2bc1688768365459db2bee..8fb230ffa746310c6a43077f3f4e515be0b6dfe9 100644 (file)
 #include "zebra/zebra_dplane.h"
 #include "zebra/zebra_mpls.h"
 #include "zebra/zebra_router.h"
+#include "zebra/interface.h"
+#include "zebra/zebra_vxlan_private.h"
 #include "zebra/zebra_evpn.h"
 #include "zebra/zebra_evpn_mac.h"
-#include "zebra/zebra_vxlan_private.h"
 #include "zebra/kernel_netlink.h"
 #include "zebra/rt_netlink.h"
 #include "zebra/debug.h"
@@ -1189,7 +1190,7 @@ static void fpm_enqueue_rmac_table(struct hash_bucket *bucket, void *arg)
        struct fpm_rmac_arg *fra = arg;
        struct zebra_mac *zrmac = bucket->data;
        struct zebra_if *zif = fra->zl3vni->vxlan_if->info;
-       const struct zebra_l2info_vxlan *vxl = &zif->l2info.vxl;
+       struct zebra_vxlan_vni *vni;
        struct zebra_if *br_zif;
        vlanid_t vid;
        bool sticky;
@@ -1201,7 +1202,8 @@ static void fpm_enqueue_rmac_table(struct hash_bucket *bucket, void *arg)
        sticky = !!CHECK_FLAG(zrmac->flags,
                              (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
        br_zif = (struct zebra_if *)(zif->brslave_info.br_if->info);
-       vid = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif) ? vxl->access_vlan : 0;
+       vni = zebra_vxlan_if_vni_find(zif, fra->zl3vni->vni);
+       vid = IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif) ? vni->access_vlan : 0;
 
        dplane_ctx_reset(fra->ctx);
        dplane_ctx_set_op(fra->ctx, DPLANE_OP_MAC_INSTALL);
index 835659332b3f9500b93594b179a6ffbd4c854f3e..6df8a4067ce77db2b3d534b6c3d4a9fbd8e90e53 100644 (file)
@@ -627,7 +627,7 @@ static int netlink_extract_vxlan_info(struct rtattr *link_data,
        }
 
        vni_in_msg = *(vni_t *)RTA_DATA(attr[IFLA_VXLAN_ID]);
-       vxl_info->vni = vni_in_msg;
+       vxl_info->vni_info.vni.vni = vni_in_msg;
        if (!attr[IFLA_VXLAN_LOCAL]) {
                if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug(
@@ -639,7 +639,7 @@ static int netlink_extract_vxlan_info(struct rtattr *link_data,
        }
 
        if (attr[IFLA_VXLAN_GROUP]) {
-               vxl_info->mcast_grp =
+               vxl_info->vni_info.vni.mcast_grp =
                        *(struct in_addr *)RTA_DATA(attr[IFLA_VXLAN_GROUP]);
        }
 
index 59563834ef9c64d2ec2035f9ad56c0d0febbfe62..81abb13b75d46b48b9acdb5ab16fd1b1ac1dd538 100644 (file)
@@ -1889,6 +1889,118 @@ static inline bool if_is_protodown_applicable(struct interface *ifp)
        return true;
 }
 
+static void zebra_vxlan_if_vni_dump_vty(struct vty *vty,
+                                       struct zebra_vxlan_vni *vni)
+{
+       vty_out(vty, "  VxLAN Id %u", vni->vni);
+       if (vni->access_vlan)
+               vty_out(vty, " Access VLAN Id %u\n", vni->access_vlan);
+
+       if (vni->mcast_grp.s_addr != INADDR_ANY)
+               vty_out(vty, "  Mcast Group %s", inet_ntoa(vni->mcast_grp));
+}
+
+static void zebra_vxlan_if_vni_dump_vty_json(struct zebra_vxlan_vni *vni,
+                                            json_object *json_if)
+{
+       json_object_int_add(json_if, "vxlanId", vni->vni);
+       if (vni->access_vlan)
+               json_object_int_add(json_if, "accessVlanId", vni->access_vlan);
+
+       if (vni->mcast_grp.s_addr != INADDR_ANY)
+               json_object_string_addf(json_if, "mcastGroup", "%pI4",
+                                       &vni->mcast_grp);
+}
+
+struct vxlan_if_dump_ctx {
+       struct vty *vty;
+       json_object *json_if;
+};
+
+static void zebra_vxlan_if_vni_hash_dump_vty(struct hash_bucket *bucket,
+                                            void *ctxt)
+{
+       struct vty *vty;
+       struct json_object *json_if;
+       struct zebra_vxlan_vni *vni;
+
+       vni = (struct zebra_vxlan_vni *)bucket->data;
+       vty = ((struct vxlan_if_dump_ctx *)ctxt)->vty;
+       json_if = ((struct vxlan_if_dump_ctx *)ctxt)->json_if;
+
+       if (json_if)
+               zebra_vxlan_if_vni_dump_vty_json(vni, json_if);
+       else
+               zebra_vxlan_if_vni_dump_vty(vty, vni);
+}
+
+static void zebra_vxlan_if_dump_vty(struct vty *vty, struct zebra_if *zebra_if)
+{
+       struct vxlan_if_dump_ctx dump_ctx;
+       struct zebra_l2info_vxlan *vxlan_info;
+       struct zebra_vxlan_vni_info *vni_info;
+
+       vxlan_info = &zebra_if->l2info.vxl;
+       vni_info = &vxlan_info->vni_info;
+
+       if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
+               vty_out(vty, " VTEP IP: %s", inet_ntoa(vxlan_info->vtep_ip));
+
+       if (vxlan_info->ifindex_link && (vxlan_info->link_nsid != NS_UNKNOWN)) {
+               struct interface *ifp;
+
+               ifp = if_lookup_by_index_per_ns(
+                       zebra_ns_lookup(vxlan_info->link_nsid),
+                       vxlan_info->ifindex_link);
+               vty_out(vty, " Link Interface %s",
+                       ifp == NULL ? "Unknown" : ifp->name);
+       }
+
+       if (IS_ZEBRA_VXLAN_IF_VNI(zebra_if)) {
+               zebra_vxlan_if_vni_dump_vty(vty, &vni_info->vni);
+       } else {
+               dump_ctx.json_if = NULL;
+               dump_ctx.vty = vty;
+               hash_iterate(vni_info->vni_table,
+                            zebra_vxlan_if_vni_hash_dump_vty, &dump_ctx);
+       }
+
+       vty_out(vty, "\n");
+}
+
+static void zebra_vxlan_if_dump_vty_json(struct zebra_if *zebra_if,
+                                        json_object *json_if)
+{
+       struct vxlan_if_dump_ctx dump_ctx;
+       struct zebra_l2info_vxlan *vxlan_info;
+       struct zebra_vxlan_vni_info *vni_info;
+
+       vxlan_info = &zebra_if->l2info.vxl;
+       vni_info = &vxlan_info->vni_info;
+
+       if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
+               json_object_string_addf(json_if, "vtepIp", "%pI4",
+                                       &vxlan_info->vtep_ip);
+
+       if (vxlan_info->ifindex_link && (vxlan_info->link_nsid != NS_UNKNOWN)) {
+               struct interface *ifp;
+
+               ifp = if_lookup_by_index_per_ns(
+                       zebra_ns_lookup(vxlan_info->link_nsid),
+                       vxlan_info->ifindex_link);
+               json_object_string_add(json_if, "linkInterface",
+                                      ifp == NULL ? "Unknown" : ifp->name);
+       }
+
+       if (IS_ZEBRA_VXLAN_IF_VNI(zebra_if)) {
+               zebra_vxlan_if_vni_dump_vty_json(&vni_info->vni, json_if);
+       } else {
+               dump_ctx.json_if = json_if;
+               hash_iterate(vni_info->vni_table,
+                            zebra_vxlan_if_vni_hash_dump_vty, &dump_ctx);
+       }
+}
+
 /* Interface's information print out to vty interface. */
 static void if_dump_vty(struct vty *vty, struct interface *ifp)
 {
@@ -1997,42 +2109,15 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
                zebra_zifslavetype_2str(zebra_if->zif_slave_type));
 
        if (IS_ZEBRA_IF_BRIDGE(ifp)) {
-               struct zebra_l2info_bridge *bridge_info;
-
-               bridge_info = &zebra_if->l2info.br;
                vty_out(vty, "  Bridge VLAN-aware: %s\n",
-                       bridge_info->vlan_aware ? "yes" : "no");
+                       IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zebra_if) ? "yes" : "no");
        } else if (IS_ZEBRA_IF_VLAN(ifp)) {
                struct zebra_l2info_vlan *vlan_info;
 
                vlan_info = &zebra_if->l2info.vl;
                vty_out(vty, "  VLAN Id %u\n", vlan_info->vid);
        } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
-               struct zebra_l2info_vxlan *vxlan_info;
-
-               vxlan_info = &zebra_if->l2info.vxl;
-               vty_out(vty, "  VxLAN Id %u", vxlan_info->vni);
-               if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
-                       vty_out(vty, " VTEP IP: %pI4",
-                               &vxlan_info->vtep_ip);
-               if (vxlan_info->access_vlan)
-                       vty_out(vty, " Access VLAN Id %u\n",
-                               vxlan_info->access_vlan);
-               if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
-                       vty_out(vty, "  Mcast Group %pI4",
-                                       &vxlan_info->mcast_grp);
-               if (vxlan_info->ifindex_link &&
-                   (vxlan_info->link_nsid != NS_UNKNOWN)) {
-                               struct interface *ifp;
-
-                               ifp = if_lookup_by_index_per_ns(
-                                       zebra_ns_lookup(vxlan_info->link_nsid),
-                                       vxlan_info->ifindex_link);
-                               vty_out(vty, " Link Interface %s",
-                                       ifp == NULL ? "Unknown" :
-                                       ifp->name);
-               }
-               vty_out(vty, "\n");
+               zebra_vxlan_if_dump_vty(vty, zebra_if);
        } else if (IS_ZEBRA_IF_GRE(ifp)) {
                struct zebra_l2info_gre *gre_info;
 
@@ -2359,30 +2444,7 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
                vlan_info = &zebra_if->l2info.vl;
                json_object_int_add(json_if, "vlanId", vlan_info->vid);
        } else if (IS_ZEBRA_IF_VXLAN(ifp)) {
-               struct zebra_l2info_vxlan *vxlan_info;
-
-               vxlan_info = &zebra_if->l2info.vxl;
-               json_object_int_add(json_if, "vxlanId", vxlan_info->vni);
-               if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
-                       json_object_string_addf(json_if, "vtepIp", "%pI4",
-                                               &vxlan_info->vtep_ip);
-               if (vxlan_info->access_vlan)
-                       json_object_int_add(json_if, "accessVlanId",
-                                           vxlan_info->access_vlan);
-               if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
-                       json_object_string_addf(json_if, "mcastGroup", "%pI4",
-                                               &vxlan_info->mcast_grp);
-               if (vxlan_info->ifindex_link
-                   && (vxlan_info->link_nsid != NS_UNKNOWN)) {
-                       struct interface *ifp;
-
-                       ifp = if_lookup_by_index_per_ns(
-                               zebra_ns_lookup(vxlan_info->link_nsid),
-                               vxlan_info->ifindex_link);
-                       json_object_string_add(json_if, "linkInterface",
-                                              ifp == NULL ? "Unknown"
-                                                          : ifp->name);
-               }
+               zebra_vxlan_if_dump_vty_json(zebra_if, json_if);
        } else if (IS_ZEBRA_IF_GRE(ifp)) {
                struct zebra_l2info_gre *gre_info;
 
index 216b719ff859526923412e83cc65155c0f41edfb..79d6af60ce1464fe2e94549922f7835f2cfe9827 100644 (file)
@@ -3702,7 +3702,7 @@ int netlink_macfdb_read_for_bridge(struct zebra_ns *zns, struct interface *ifp,
        zif = (struct zebra_if *)ifp->info;
        vxl = &zif->l2info.vxl;
        if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
-               filter_vlan = vxl->access_vlan;
+               filter_vlan = vxl->vni_info.vni.access_vlan;
 
        /* Get bridge FDB table for specific bridge - we do the VLAN filtering.
         */
index ff9ca1ac255d58afe5342e1bd6e93e341ecf8ebb..42ebedf602b8596dae1b3d0c44af8c78efb54d03 100644 (file)
@@ -455,16 +455,16 @@ int zebra_evpn_gw_macip_add(struct interface *ifp, struct zebra_evpn *zevpn,
 {
        struct zebra_mac *mac = NULL;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan *vxl = NULL;
+       struct zebra_vxlan_vni *vni;
 
        zif = zevpn->vxlan_if->info;
        if (!zif)
                return -1;
 
-       vxl = &zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
 
        zebra_evpn_mac_gw_macip_add(ifp, zevpn, ip, &mac, macaddr,
-                                   vxl->access_vlan, true);
+                                   vni->access_vlan, true);
 
        return zebra_evpn_neigh_gw_macip_add(ifp, zevpn, ip, mac);
 }
@@ -523,7 +523,7 @@ void zebra_evpn_gw_macip_del_for_evpn_hash(struct hash_bucket *bucket,
 {
        struct zebra_evpn *zevpn = NULL;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan zl2_info;
+       struct zebra_vxlan_vni *vni = NULL;
        struct interface *vlan_if = NULL;
        struct interface *vrr_if = NULL;
        struct interface *ifp;
@@ -550,10 +550,11 @@ void zebra_evpn_gw_macip_del_for_evpn_hash(struct hash_bucket *bucket,
        if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
                return;
 
-       zl2_info = zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
+       if (!vni)
+               return;
 
-       vlan_if =
-               zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
+       vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
        if (!vlan_if)
                return;
 
@@ -573,10 +574,10 @@ void zebra_evpn_gw_macip_add_for_evpn_hash(struct hash_bucket *bucket,
 {
        struct zebra_evpn *zevpn = NULL;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan zl2_info;
        struct interface *vlan_if = NULL;
        struct interface *vrr_if = NULL;
        struct interface *ifp = NULL;
+       struct zebra_vxlan_vni *vni = NULL;
 
        zevpn = (struct zebra_evpn *)bucket->data;
 
@@ -588,10 +589,11 @@ void zebra_evpn_gw_macip_add_for_evpn_hash(struct hash_bucket *bucket,
        /* If down or not mapped to a bridge, we're done. */
        if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
                return;
-       zl2_info = zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
+       if (!vni)
+               return;
 
-       vlan_if =
-               zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
+       vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
        if (!vlan_if)
                return;
 
@@ -615,8 +617,8 @@ void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
 {
        struct zebra_evpn *zevpn = NULL;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan zl2_info;
        struct interface *vlan_if = NULL;
+       struct zebra_vxlan_vni *vni = NULL;
        struct interface *ifp;
 
        /* Add primary SVI MAC*/
@@ -643,10 +645,11 @@ void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
        if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
                return;
 
-       zl2_info = zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
+       if (!vni)
+               return;
 
-       vlan_if =
-               zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
+       vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
        if (!vlan_if)
                return;
 
@@ -667,7 +670,7 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns,
        struct zebra_evpn *zevpn;
        struct interface *tmp_if = NULL;
        struct zebra_if *zif;
-       struct zebra_l2info_vxlan *vxl = NULL;
+       struct zebra_vxlan_vni *vni;
        struct zebra_from_svi_param *in_param =
                (struct zebra_from_svi_param *)_in_param;
 
@@ -689,14 +692,15 @@ static int zebra_evpn_map_vlan_ns(struct ns *ns,
                        continue;
                if (!if_is_operative(tmp_if))
                        continue;
-               vxl = &zif->l2info.vxl;
 
                if (zif->brslave_info.br_if != br_if)
                        continue;
 
-               if (!in_param->bridge_vlan_aware
-                   || vxl->access_vlan == in_param->vid) {
-                       zevpn = zebra_evpn_lookup(vxl->vni);
+               vni = zebra_vxlan_if_access_vlan_find(
+                       zif, in_param->bridge_vlan_aware, in_param->vid);
+
+               if (!in_param->bridge_vlan_aware || vni) {
+                       zevpn = zebra_evpn_lookup(vni->vni);
                        *p_zevpn = zevpn;
                        return NS_WALK_STOP;
                }
@@ -745,7 +749,7 @@ static int zebra_evpn_from_svi_ns(struct ns *ns,
        struct zebra_evpn *zevpn;
        struct interface *tmp_if = NULL;
        struct zebra_if *zif;
-       struct zebra_l2info_vxlan *vxl = NULL;
+       struct zebra_vxlan_vni *vni;
        struct zebra_from_svi_param *in_param =
                (struct zebra_from_svi_param *)_in_param;
        int found = 0;
@@ -766,13 +770,13 @@ static int zebra_evpn_from_svi_ns(struct ns *ns,
                        continue;
                if (!if_is_operative(tmp_if))
                        continue;
-               vxl = &zif->l2info.vxl;
 
                if (zif->brslave_info.br_if != br_if)
                        continue;
 
-               if (!in_param->bridge_vlan_aware
-                   || vxl->access_vlan == in_param->vid) {
+               vni = zebra_vxlan_if_access_vlan_find(
+                       zif, in_param->bridge_vlan_aware, in_param->vid);
+               if (!in_param->bridge_vlan_aware || vni) {
                        found = 1;
                        break;
                }
@@ -781,7 +785,7 @@ static int zebra_evpn_from_svi_ns(struct ns *ns,
        if (!found)
                return NS_WALK_CONTINUE;
 
-       zevpn = zebra_evpn_lookup(vxl->vni);
+       zevpn = zebra_evpn_lookup(vni->vni);
        if (p_zevpn)
                *p_zevpn = zevpn;
        return NS_WALK_STOP;
@@ -928,11 +932,11 @@ void zebra_evpn_read_mac_neigh(struct zebra_evpn *zevpn, struct interface *ifp)
        struct zebra_vrf *zvrf;
        struct zebra_if *zif;
        struct interface *vlan_if;
-       struct zebra_l2info_vxlan *vxl;
+       struct zebra_vxlan_vni *vni;
        struct interface *vrr_if;
 
        zif = ifp->info;
-       vxl = &zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
        zvrf = zebra_vrf_lookup_by_id(zevpn->vrf_id);
        if (!zvrf || !zvrf->zns)
                return;
@@ -945,7 +949,7 @@ void zebra_evpn_read_mac_neigh(struct zebra_evpn *zevpn, struct interface *ifp)
                        zif->brslave_info.bridge_ifindex);
 
        macfdb_read_for_bridge(zns, ifp, zif->brslave_info.br_if);
-       vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
+       vlan_if = zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
        if (vlan_if) {
                /* Add SVI MAC */
                zebra_evpn_acc_bd_svi_mac_add(vlan_if);
@@ -1518,7 +1522,7 @@ void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
        struct interface *ifp = NULL;
        struct zebra_if *zif = NULL;
        struct zebra_ns *zns;
-       struct zebra_l2info_vxlan *vxl;
+       struct zebra_vxlan_vni *vnip;
        struct zebra_vrf *zvrf;
        char buf1[INET6_ADDRSTRLEN];
 
@@ -1541,7 +1545,14 @@ void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
                return;
        }
        zns = zebra_ns_lookup(NS_DEFAULT);
-       vxl = &zif->l2info.vxl;
+       vnip = zebra_vxlan_if_vni_find(zif, vni);
+       if (!vnip) {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug(
+                               "VNI %u not in interface upon remote MACIP DEL",
+                               vni);
+               return;
+       }
 
        mac = zebra_evpn_mac_lookup(zevpn, macaddr);
        if (ipa_len)
@@ -1596,7 +1607,7 @@ void zebra_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
                                        "%s: MAC %pEA (flags 0x%x) is remote and duplicate, read kernel for local entry",
                                        __func__, macaddr, mac->flags);
                        macfdb_read_specific_mac(zns, zif->brslave_info.br_if,
-                                                macaddr, vxl->access_vlan);
+                                                macaddr, vnip->access_vlan);
                }
 
                if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
index 2c84d23045a47eb117cd503bcd68fbefe292a6db..5dd54a117e018e4fc06b6768f410949b11924b26 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "zebra/zebra_l2.h"
 #include "zebra/interface.h"
+#include "zebra/zebra_vxlan.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -138,7 +139,7 @@ static inline struct interface *zevpn_map_to_svi(struct zebra_evpn *zevpn)
 {
        struct interface *ifp;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan zl2_info;
+       struct zebra_vxlan_vni *vni;
 
        ifp = zevpn->vxlan_if;
        if (!ifp)
@@ -146,12 +147,15 @@ static inline struct interface *zevpn_map_to_svi(struct zebra_evpn *zevpn)
        zif = ifp->info;
        if (!zif)
                return NULL;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
+       if (!vni)
+               return NULL;
 
        /* If down or not mapped to a bridge, we're done. */
        if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
                return NULL;
-       zl2_info = zif->l2info.vxl;
-       return zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
+
+       return zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
 }
 
 int advertise_gw_macip_enabled(struct zebra_evpn *zevpn);
index 2c953eef15db361ce46091d91eee9a0008123e9a..4b30a5448854b51010e85c0da33ea504c5483455 100644 (file)
@@ -198,7 +198,7 @@ int zebra_evpn_rem_mac_install(struct zebra_evpn *zevpn, struct zebra_mac *mac,
                               bool was_static)
 {
        const struct zebra_if *zif, *br_zif;
-       const struct zebra_l2info_vxlan *vxl;
+       const struct zebra_vxlan_vni *vni;
        bool sticky;
        enum zebra_dplane_result res;
        const struct interface *br_ifp;
@@ -214,7 +214,9 @@ int zebra_evpn_rem_mac_install(struct zebra_evpn *zevpn, struct zebra_mac *mac,
        if (br_ifp == NULL)
                return -1;
 
-       vxl = &zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
+       if (!vni)
+               return -1;
 
        sticky = !!CHECK_FLAG(mac->flags,
                              (ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW));
@@ -235,7 +237,7 @@ int zebra_evpn_rem_mac_install(struct zebra_evpn *zevpn, struct zebra_mac *mac,
        br_zif = (const struct zebra_if *)(br_ifp->info);
 
        if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
-               vid = vxl->access_vlan;
+               vid = vni->access_vlan;
        else
                vid = 0;
 
@@ -254,7 +256,7 @@ int zebra_evpn_rem_mac_uninstall(struct zebra_evpn *zevpn,
                                 struct zebra_mac *mac, bool force)
 {
        const struct zebra_if *zif, *br_zif;
-       const struct zebra_l2info_vxlan *vxl;
+       struct zebra_vxlan_vni *vni;
        struct in_addr vtep_ip;
        const struct interface *ifp, *br_ifp;
        vlanid_t vid;
@@ -280,12 +282,14 @@ int zebra_evpn_rem_mac_uninstall(struct zebra_evpn *zevpn,
        if (br_ifp == NULL)
                return -1;
 
-       vxl = &zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
+       if (!vni)
+               return -1;
 
        br_zif = (const struct zebra_if *)br_ifp->info;
 
        if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
-               vid = vxl->access_vlan;
+               vid = vni->access_vlan;
        else
                vid = 0;
 
@@ -327,6 +331,8 @@ static void zebra_evpn_mac_get_access_info(struct zebra_mac *mac,
                                           struct interface **p_ifp,
                                           vlanid_t *vid)
 {
+       struct zebra_vxlan_vni *vni;
+
        /* if the mac is associated with an ES we must get the access
         * info from the ES
         */
@@ -338,7 +344,8 @@ static void zebra_evpn_mac_get_access_info(struct zebra_mac *mac,
                /* get the vlan from the EVPN */
                if (mac->zevpn->vxlan_if) {
                        zif = mac->zevpn->vxlan_if->info;
-                       *vid = zif->l2info.vxl.access_vlan;
+                       vni = zebra_vxlan_if_vni_find(zif, mac->zevpn->vni);
+                       *vid = vni->access_vlan;
                } else {
                        *vid = 0;
                }
index 01ea9c5b9c924d4af15dba0bd64f9247ad3cf2e6..642169840bd9463d20ce9f4b83fc79298c041d99 100644 (file)
@@ -481,6 +481,7 @@ void zebra_evpn_update_all_es(struct zebra_evpn *zevpn)
        struct interface *vlan_if;
        struct interface *vxlan_if;
        struct zebra_if *vxlan_zif;
+       struct zebra_vxlan_vni *vni;
 
        /* the EVPN is now elgible as a base for EVPN-MH */
        if (zebra_evpn_send_to_client_ok(zevpn))
@@ -497,9 +498,10 @@ void zebra_evpn_update_all_es(struct zebra_evpn *zevpn)
                vxlan_zif = vxlan_if->info;
                if (if_is_operative(vxlan_if)
                    && vxlan_zif->brslave_info.br_if) {
-                       vlan_if = zvni_map_to_svi(
-                               vxlan_zif->l2info.vxl.access_vlan,
-                               vxlan_zif->brslave_info.br_if);
+                       vni = zebra_vxlan_if_vni_find(vxlan_zif, zevpn->vni);
+                       vlan_if =
+                               zvni_map_to_svi(vni->access_vlan,
+                                               vxlan_zif->brslave_info.br_if);
                        if (vlan_if)
                                zebra_evpn_acc_bd_svi_mac_add(vlan_if);
                }
@@ -711,33 +713,41 @@ static void zebra_evpn_acc_bd_evpn_set(struct zebra_evpn_access_bd *acc_bd,
 }
 
 /* handle VLAN->VxLAN_IF association */
-void zebra_evpn_vl_vxl_ref(uint16_t vid, struct zebra_if *vxlan_zif)
+void zebra_evpn_vl_vxl_ref(uint16_t vid, vni_t vni_id,
+                          struct zebra_if *vxlan_zif)
 {
+       vni_t old_vni;
        struct zebra_evpn_access_bd *acc_bd;
-       struct zebra_if *old_vxlan_zif;
        struct zebra_evpn *old_zevpn;
 
        if (!vid)
                return;
 
+       if (!vni_id)
+               return;
+
        acc_bd = zebra_evpn_acc_vl_find(vid);
        if (!acc_bd)
                acc_bd = zebra_evpn_acc_vl_new(vid,
                                               vxlan_zif->brslave_info.br_if);
 
-       old_vxlan_zif = acc_bd->vxlan_zif;
-       acc_bd->vxlan_zif = vxlan_zif;
-       if (vxlan_zif == old_vxlan_zif)
+       old_vni = acc_bd->vni;
+
+       if (vni_id == old_vni)
                return;
 
+       acc_bd->vni = vni_id;
+       acc_bd->vxlan_zif = vxlan_zif;
+
        old_zevpn = acc_bd->zevpn;
-       acc_bd->zevpn = zebra_evpn_lookup(vxlan_zif->l2info.vxl.vni);
+       acc_bd->zevpn = zebra_evpn_lookup(vni_id);
        if (acc_bd->zevpn == old_zevpn)
                return;
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-               zlog_debug("access vlan %d vni %u ref",
-                               acc_bd->vid, vxlan_zif->l2info.vxl.vni);
+               zlog_debug("access vlan %d vni %u ref", acc_bd->vid, vni_id);
+
+       zlog_err("access vlan %d vni %u ref", acc_bd->vid, vni_id);
 
        if (old_zevpn)
                zebra_evpn_acc_bd_evpn_set(acc_bd, NULL, old_zevpn);
@@ -747,30 +757,34 @@ void zebra_evpn_vl_vxl_ref(uint16_t vid, struct zebra_if *vxlan_zif)
 }
 
 /* handle VLAN->VxLAN_IF deref */
-void zebra_evpn_vl_vxl_deref(uint16_t vid, struct zebra_if *vxlan_zif)
+void zebra_evpn_vl_vxl_deref(uint16_t vid, vni_t vni_id,
+                            struct zebra_if *vxlan_zif)
 {
        struct zebra_evpn_access_bd *acc_bd;
 
        if (!vid)
                return;
 
+       if (!vni_id)
+               return;
+
        acc_bd = zebra_evpn_acc_vl_find(vid);
        if (!acc_bd)
                return;
 
        /* clear vxlan_if only if it matches */
-       if (acc_bd->vxlan_zif != vxlan_zif)
+       if (acc_bd->vni != vni_id)
                return;
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-               zlog_debug("access vlan %d vni %u deref",
-                               acc_bd->vid, vxlan_zif->l2info.vxl.vni);
+               zlog_debug("access vlan %d vni %u deref", acc_bd->vid, vni_id);
 
        if (acc_bd->zevpn)
                zebra_evpn_acc_bd_evpn_set(acc_bd, NULL, acc_bd->zevpn);
 
        acc_bd->zevpn = NULL;
        acc_bd->vxlan_zif = NULL;
+       acc_bd->vni = 0;
 
        /* if there are no other references the access_bd can be freed */
        zebra_evpn_acc_bd_free_on_deref(acc_bd);
@@ -780,15 +794,18 @@ void zebra_evpn_vl_vxl_deref(uint16_t vid, struct zebra_if *vxlan_zif)
 void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, struct zebra_evpn *zevpn,
                             bool set)
 {
-       struct zebra_l2info_vxlan *vxl;
+       struct zebra_vxlan_vni *vni;
        struct zebra_evpn_access_bd *acc_bd;
 
        if (!zif)
                return;
 
        /* locate access_bd associated with the vxlan device */
-       vxl = &zif->l2info.vxl;
-       acc_bd = zebra_evpn_acc_vl_find(vxl->access_vlan);
+       vni = zebra_vxlan_if_vni_find(zif, zevpn->vni);
+       if (!vni)
+               return;
+
+       acc_bd = zebra_evpn_acc_vl_find(vni->access_vlan);
        if (!acc_bd)
                return;
 
@@ -1986,9 +2003,10 @@ static void zebra_evpn_es_setup_evis(struct zebra_evpn_es *es)
 static void zebra_evpn_flush_local_mac(struct zebra_mac *mac,
                                       struct interface *ifp)
 {
+       vlanid_t vid;
        struct zebra_if *zif;
        struct interface *br_ifp;
-       vlanid_t vid;
+       struct zebra_vxlan_vni *vni;
 
        zif = ifp->info;
        br_ifp = zif->brslave_info.br_if;
@@ -1997,7 +2015,8 @@ static void zebra_evpn_flush_local_mac(struct zebra_mac *mac,
 
        if (mac->zevpn->vxlan_if) {
                zif = mac->zevpn->vxlan_if->info;
-               vid = zif->l2info.vxl.access_vlan;
+               vni = zebra_vxlan_if_vni_find(zif, mac->zevpn->vni);
+               vid = vni->access_vlan;
        } else {
                vid = 0;
        }
index 037648311c824fc87df80b0e060a61574dc558e8..2c6e4924f654db0b68052ff4d2cf1fd30cf7202b 100644 (file)
@@ -179,6 +179,7 @@ struct zebra_evpn_es_vtep {
 struct zebra_evpn_access_bd {
        vlanid_t vid;
 
+       vni_t vni;                  /* vni associated with the vxlan device */
        struct zebra_if *vxlan_zif; /* vxlan device */
        /* list of members associated with the BD i.e. (potential) ESs */
        struct list *mbr_zifs;
@@ -319,8 +320,10 @@ extern void zebra_evpn_vxl_evpn_set(struct zebra_if *zif,
                                    struct zebra_evpn *zevpn, bool set);
 extern void zebra_evpn_es_set_base_evpn(struct zebra_evpn *zevpn);
 extern void zebra_evpn_es_clear_base_evpn(struct zebra_evpn *zevpn);
-extern void zebra_evpn_vl_vxl_ref(uint16_t vid, struct zebra_if *vxlan_zif);
-extern void zebra_evpn_vl_vxl_deref(uint16_t vid, struct zebra_if *vxlan_zif);
+extern void zebra_evpn_vl_vxl_ref(uint16_t vid, vni_t vni_id,
+                                 struct zebra_if *vxlan_zif);
+extern void zebra_evpn_vl_vxl_deref(uint16_t vid, vni_t vni_id,
+                                   struct zebra_if *vxlan_zif);
 extern void zebra_evpn_vl_mbr_ref(uint16_t vid, struct zebra_if *zif);
 extern void zebra_evpn_vl_mbr_deref(uint16_t vid, struct zebra_if *zif);
 extern void zebra_evpn_es_send_all_to_client(bool add);
index 8a9f3dffe3668ebf6590a929ab298ee22af81765..550b819428d1102e61bdcc842d5b74bcc7c3d8b0 100644 (file)
@@ -349,7 +349,8 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
 
        if (add) {
                memcpy(&zif->l2info.vxl, vxlan_info, sizeof(*vxlan_info));
-               zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
+               zebra_evpn_vl_vxl_ref(zif->l2info.vxl.vni_info.vni.access_vlan,
+                                     zif->l2info.vxl.vni_info.vni.vni, zif);
                zebra_vxlan_if_add(ifp);
                return;
        }
@@ -361,10 +362,13 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
                zif->l2info.vxl.vtep_ip = vxlan_info->vtep_ip;
        }
 
-       if (!IPV4_ADDR_SAME(&zif->l2info.vxl.mcast_grp,
-                               &vxlan_info->mcast_grp)) {
-               chgflags |= ZEBRA_VXLIF_MCAST_GRP_CHANGE;
-               zif->l2info.vxl.mcast_grp = vxlan_info->mcast_grp;
+       if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
+               if (!IPV4_ADDR_SAME(&zif->l2info.vxl.vni_info.vni.mcast_grp,
+                                   &vxlan_info->vni_info.vni.mcast_grp)) {
+                       chgflags |= ZEBRA_VXLIF_MCAST_GRP_CHANGE;
+                       zif->l2info.vxl.vni_info.vni.mcast_grp =
+                               vxlan_info->vni_info.vni.mcast_grp;
+               }
        }
 
        if (chgflags)
@@ -379,18 +383,25 @@ void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
 {
        struct zebra_if *zif;
        vlanid_t old_access_vlan;
+       struct zebra_vxlan_vni *vni;
+
 
        zif = ifp->info;
        assert(zif);
 
-       old_access_vlan = zif->l2info.vxl.access_vlan;
+       /* This would be called only in non svd case */
+       assert(IS_ZEBRA_VXLAN_IF_VNI(zif));
+
+       old_access_vlan = zif->l2info.vxl.vni_info.vni.access_vlan;
+       ;
        if (old_access_vlan == access_vlan)
                return;
 
-       zif->l2info.vxl.access_vlan = access_vlan;
+       vni = zebra_vxlan_if_vni_find(zif, 0);
+       vni->access_vlan = access_vlan;
 
-       zebra_evpn_vl_vxl_deref(old_access_vlan, zif);
-       zebra_evpn_vl_vxl_ref(zif->l2info.vxl.access_vlan, zif);
+       zebra_evpn_vl_vxl_deref(old_access_vlan, vni->vni, zif);
+       zebra_evpn_vl_vxl_ref(access_vlan, vni->vni, zif);
        zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_VLAN_CHANGE);
 }
 
@@ -404,7 +415,8 @@ void zebra_l2_vxlanif_del(struct interface *ifp)
        zif = ifp->info;
        assert(zif);
 
-       zebra_evpn_vl_vxl_deref(zif->l2info.vxl.access_vlan, zif);
+       zebra_evpn_vl_vxl_deref(zif->l2info.vxl.vni_info.vni.access_vlan,
+                               zif->l2info.vxl.vni_info.vni.vni, zif);
        zebra_vxlan_if_del(ifp);
 }
 
index 1c3e98158d4765a6bd80404306ea03e6c628792f..0df75ac07be115062e879baf09d41e0911d058c8 100644 (file)
@@ -71,12 +71,44 @@ struct zebra_l2info_gre {
        ns_id_t link_nsid;
 };
 
+struct zebra_vxlan_vni {
+       vni_t vni;          /* VNI */
+       vlanid_t access_vlan; /* Access VLAN - for VLAN-aware bridge. */
+       struct in_addr mcast_grp;
+};
+
+typedef enum {
+       ZEBRA_VXLAN_IF_VNI = 0, /* per vni vxlan if */
+       ZEBRA_VXLAN_IF_SVD      /* single vxlan device */
+} zebra_vxlan_iftype_t;
+
+struct zebra_vxlan_if_vlan_ctx {
+       vlanid_t vid;
+       struct zebra_vxlan_vni *vni;
+};
+
+struct zebra_vxlan_if_ctx {
+       /* input */
+       struct zebra_if *zif;
+       int (*func)(struct zebra_if *, struct zebra_vxlan_vni *, void *);
+
+       /* input-output */
+       void *arg;
+};
+
+struct zebra_vxlan_vni_info {
+       zebra_vxlan_iftype_t iftype;
+       union {
+               struct zebra_vxlan_vni vni; /* per vni vxlan device vni info */
+               struct hash
+                       *vni_table; /* table of vni's assocated with this if */
+       };
+};
+
 /* zebra L2 interface information - VXLAN interface */
 struct zebra_l2info_vxlan {
-       vni_t vni;              /* VNI */
+       struct zebra_vxlan_vni_info vni_info;
        struct in_addr vtep_ip; /* Local tunnel IP */
-       vlanid_t access_vlan;   /* Access VLAN - for VLAN-aware bridge. */
-       struct in_addr mcast_grp;
        ifindex_t ifindex_link; /* Interface index of interface
                                 * linked with VXLAN
                                 */
@@ -99,7 +131,11 @@ union zebra_l2if_info {
  * IOW, the macro VNI_FROM_ZEBRA_IF() will assume the interface is
  * of type ZEBRA_IF_VXLAN.
  */
-#define VNI_FROM_ZEBRA_IF(zif) (zif)->l2info.vxl.vni
+#define VNI_INFO_FROM_ZEBRA_IF(zif) (&((zif)->l2info.vxl.vni_info))
+#define IS_ZEBRA_VXLAN_IF_SVD(zif)                                             \
+       ((zif)->l2info.vxl.vni_info.iftype == ZEBRA_VXLAN_IF_SVD)
+#define IS_ZEBRA_VXLAN_IF_VNI(zif)                                             \
+       ((zif)->l2info.vxl.vni_info.iftype == ZEBRA_VXLAN_IF_VNI)
 #define VLAN_ID_FROM_ZEBRA_IF(zif) (zif)->l2info.vl.vid
 
 #define IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(zif) ((zif)->l2info.br.vlan_aware == 1)
index 0f3d56f21432003ca8bc91a2b81c1abee2271bc3..0c0bd5638318baf6ac194564a40ec51ac5cabfd3 100644 (file)
@@ -25,6 +25,7 @@
 #include "zebra/zebra_router.h"
 #include "zebra/debug.h"
 #include "printfrr.h"
+#include "zebra/zebra_vxlan.h"
 
 /*
  * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count
@@ -101,15 +102,18 @@ lib_interface_zebra_state_vni_id_get_elem(struct nb_cb_get_elem_args *args)
 {
        const struct interface *ifp = args->list_entry;
        struct zebra_if *zebra_if;
-       struct zebra_l2info_vxlan *vxlan_info;
+       struct zebra_vxlan_vni *vni;
 
        if (!IS_ZEBRA_IF_VXLAN(ifp))
                return NULL;
 
        zebra_if = ifp->info;
-       vxlan_info = &zebra_if->l2info.vxl;
 
-       return yang_data_new_uint32(args->xpath, vxlan_info->vni);
+       if (!IS_ZEBRA_VXLAN_IF_VNI(zebra_if))
+               return NULL;
+
+       vni = zebra_vxlan_if_vni_find(zebra_if, 0);
+       return yang_data_new_uint32(args->xpath, vni->vni);
 }
 
 /*
@@ -139,15 +143,18 @@ lib_interface_zebra_state_mcast_group_get_elem(struct nb_cb_get_elem_args *args)
 {
        const struct interface *ifp = args->list_entry;
        struct zebra_if *zebra_if;
-       struct zebra_l2info_vxlan *vxlan_info;
+       struct zebra_vxlan_vni *vni;
 
        if (!IS_ZEBRA_IF_VXLAN(ifp))
                return NULL;
 
        zebra_if = ifp->info;
-       vxlan_info = &zebra_if->l2info.vxl;
 
-       return yang_data_new_ipv4(args->xpath, &vxlan_info->mcast_grp);
+       if (!IS_ZEBRA_VXLAN_IF_VNI(zebra_if))
+               return NULL;
+
+       vni = zebra_vxlan_if_vni_find(zebra_if, 0);
+       return yang_data_new_ipv4(args->xpath, &vni->mcast_grp);
 }
 
 const void *lib_vrf_zebra_ribs_rib_get_next(struct nb_cb_get_next_args *args)
index 0bbc811324d65abe51b5edbdb637c7d9d7c8d3f3..3e7f56680533e9cb204f1ce5779538de26491908 100644 (file)
 #include "zebra/zebra_ns.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/zebra_vxlan.h"
+#include "zebra/zebra_vxlan_private.h"
 #include "zebra/zebra_evpn.h"
 #include "zebra/zebra_evpn_mac.h"
 #include "zebra/zebra_evpn_neigh.h"
-#include "zebra/zebra_vxlan_private.h"
 #include "zebra/zebra_evpn_mh.h"
 #include "zebra/zebra_evpn_vxlan.h"
 #include "zebra/zebra_router.h"
@@ -943,6 +943,7 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
                struct zebra_l3vni *zl3vni = NULL;
                struct zebra_if *zif;
                struct zebra_l2info_vxlan *vxl;
+               struct zebra_vxlan_vni *vnip;
 
                ifp = (struct interface *)rn->info;
                if (!ifp)
@@ -952,7 +953,8 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
                        continue;
 
                vxl = &zif->l2info.vxl;
-               vni = vxl->vni;
+               vnip = zebra_vxlan_if_vni_find(zif, 0);
+               vni = vnip->vni;
                /* link of VXLAN interface should be in zebra_evpn_vrf */
                if (zvrf->zns->ns_id != vxl->link_nsid) {
                        if (IS_ZEBRA_DEBUG_VXLAN)
@@ -1033,17 +1035,17 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
                                        return NS_WALK_CONTINUE;
                                }
 
-                               if (zevpn->local_vtep_ip.s_addr !=
-                                       vxl->vtep_ip.s_addr ||
-                                       zevpn->mcast_grp.s_addr !=
-                                       vxl->mcast_grp.s_addr) {
+                               if (zevpn->local_vtep_ip.s_addr
+                                           != vxl->vtep_ip.s_addr
+                                   || zevpn->mcast_grp.s_addr
+                                              != vnip->mcast_grp.s_addr) {
                                        zebra_vxlan_sg_deref(
                                                zevpn->local_vtep_ip,
                                                zevpn->mcast_grp);
                                        zebra_vxlan_sg_ref(vxl->vtep_ip,
-                                               vxl->mcast_grp);
+                                                          vnip->mcast_grp);
                                        zevpn->local_vtep_ip = vxl->vtep_ip;
-                                       zevpn->mcast_grp = vxl->mcast_grp;
+                                       zevpn->mcast_grp = vnip->mcast_grp;
                                        /* on local vtep-ip check if ES
                                         * orig-ip needs to be updated
                                         */
@@ -1051,7 +1053,7 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
                                }
                                zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
                                vlan_if = zvni_map_to_svi(
-                                       vxl->access_vlan,
+                                       vnip->access_vlan,
                                        zif->brslave_info.br_if);
                                if (vlan_if) {
                                        zevpn->svi_if = vlan_if;
@@ -1225,7 +1227,7 @@ static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
                               struct zebra_mac *zrmac)
 {
        const struct zebra_if *zif = NULL, *br_zif = NULL;
-       const struct zebra_l2info_vxlan *vxl = NULL;
+       const struct zebra_vxlan_vni *vni;
        const struct interface *br_ifp;
        enum zebra_dplane_result res;
        vlanid_t vid;
@@ -1242,12 +1244,12 @@ static int zl3vni_rmac_install(struct zebra_l3vni *zl3vni,
        if (br_ifp == NULL)
                return -1;
 
-       vxl = &zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
 
        br_zif = (const struct zebra_if *)br_ifp->info;
 
        if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
-               vid = vxl->access_vlan;
+               vid = vni->access_vlan;
        else
                vid = 0;
 
@@ -1267,7 +1269,7 @@ static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
                                 struct zebra_mac *zrmac)
 {
        const struct zebra_if *zif = NULL, *br_zif;
-       const struct zebra_l2info_vxlan *vxl = NULL;
+       const struct zebra_vxlan_vni *vni;
        const struct interface *br_ifp;
        vlanid_t vid;
        enum zebra_dplane_result res;
@@ -1292,11 +1294,11 @@ static int zl3vni_rmac_uninstall(struct zebra_l3vni *zl3vni,
        if (br_ifp == NULL)
                return -1;
 
-       vxl = &zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
 
        br_zif = (const struct zebra_if *)br_ifp->info;
        if (IS_ZEBRA_IF_BRIDGE_VLAN_AWARE(br_zif))
-               vid = vxl->access_vlan;
+               vid = vni->access_vlan;
        else
                vid = 0;
 
@@ -1756,7 +1758,8 @@ static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
        for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
 
                struct zebra_if *zif = NULL;
-               struct zebra_l2info_vxlan *vxl = NULL;
+               struct zebra_l2info_vxlan *vxl;
+               struct zebra_vxlan_vni *vni = NULL;
 
                ifp = (struct interface *)rn->info;
                if (!ifp)
@@ -1767,7 +1770,8 @@ static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
                        continue;
 
                vxl = &zif->l2info.vxl;
-               if (vxl->vni != zl3vni->vni)
+               vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
+               if (vni->vni != zl3vni->vni)
                        continue;
 
                /* link of VXLAN interface should be in zebra_evpn_vrf */
@@ -1776,12 +1780,12 @@ static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
                                zlog_debug(
                                        "Intf %s(%u) VNI %u, link not in same "
                                        "namespace than BGP EVPN core instance ",
-                                       ifp->name, ifp->ifindex, vxl->vni);
+                                       ifp->name, ifp->ifindex, vni->vni);
                        continue;
                }
 
 
-               zl3vni->local_vtep_ip = vxl->vtep_ip;
+               zl3vni->local_vtep_ip = zif->l2info.vxl.vtep_ip;
                *_pifp = (void *)ifp;
                return NS_WALK_STOP;
        }
@@ -1804,7 +1808,7 @@ struct interface *zl3vni_map_to_vxlan_if(struct zebra_l3vni *zl3vni)
 struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni)
 {
        struct zebra_if *zif = NULL;       /* zebra_if for vxlan_if */
-       struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
+       struct zebra_vxlan_vni *vni = NULL; /* vni info in vxlan_if */
 
        if (!zl3vni)
                return NULL;
@@ -1816,9 +1820,11 @@ struct interface *zl3vni_map_to_svi_if(struct zebra_l3vni *zl3vni)
        if (!zif)
                return NULL;
 
-       vxl = &zif->l2info.vxl;
+       vni = zebra_vxlan_if_vni_find(zif, zl3vni->vni);
+       if (!vni)
+               return NULL;
 
-       return zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
+       return zvni_map_to_svi(vni->access_vlan, zif->brslave_info.br_if);
 }
 
 struct interface *zl3vni_map_to_mac_vlan_if(struct zebra_l3vni *zl3vni)
@@ -1860,7 +1866,7 @@ static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
        struct route_node *rn = NULL;
        struct interface *tmp_if = NULL;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan *vxl = NULL;
+       struct zebra_vxlan_vni *vni = NULL;
 
        assert(in_param && p_zl3vni);
 
@@ -1874,14 +1880,14 @@ static int zl3vni_from_svi_ns(struct ns *ns, void *_in_param, void **_p_zl3vni)
                        continue;
                if (!if_is_operative(tmp_if))
                        continue;
-               vxl = &zif->l2info.vxl;
 
                if (zif->brslave_info.br_if != in_param->br_if)
                        continue;
 
-               if (!in_param->bridge_vlan_aware
-                   || vxl->access_vlan == in_param->vid) {
-                       *p_zl3vni = zl3vni_lookup(vxl->vni);
+               vni = zebra_vxlan_if_access_vlan_find(zif, in_param->bridge_vlan_aware,
+                                                     in_param->vid);
+               if (!in_param->bridge_vlan_aware || vni) {
+                       *p_zl3vni = zl3vni_lookup(vni->vni);
                        return NS_WALK_STOP;
                }
        }
@@ -2142,6 +2148,7 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
                struct route_node *rn;
                struct interface *ifp;
                struct zebra_if *zif;
+               struct zebra_vxlan_vni *vnip;
                struct zebra_l2info_vxlan *vxl;
                struct interface *vlan_if;
                bool found = false;
@@ -2161,7 +2168,8 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
                                continue;
 
                        vxl = &zif->l2info.vxl;
-                       if (vxl->vni == vni) {
+                       vnip = zebra_vxlan_if_vni_find(zif, vni);
+                       if (vnip) {
                                found = true;
                                break;
                        }
@@ -2183,7 +2191,7 @@ static int zebra_vxlan_handle_vni_transition(struct zebra_vrf *zvrf, vni_t vni,
                zevpn = zebra_evpn_add(vni);
 
                /* Find bridge interface for the VNI */
-               vlan_if = zvni_map_to_svi(vxl->access_vlan,
+               vlan_if = zvni_map_to_svi(vnip->access_vlan,
                                          zif->brslave_info.br_if);
                if (vlan_if) {
                        zevpn->vrf_id = vlan_if->vrf->vrf_id;
@@ -3966,7 +3974,7 @@ int zebra_vxlan_check_readd_vtep(struct interface *ifp,
        zif = ifp->info;
        assert(zif);
        vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vni = vxl->vni_info.vni.vni;
 
        /* If EVPN is not enabled, nothing to do. */
        if (!is_evpn_enabled())
@@ -4015,7 +4023,7 @@ static int zebra_vxlan_check_del_local_mac(struct interface *ifp,
        zif = ifp->info;
        assert(zif);
        vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vni = vxl->vni_info.vni.vni;
 
        /* Check if EVPN is enabled. */
        if (!is_evpn_enabled())
@@ -4125,7 +4133,7 @@ int zebra_vxlan_dp_network_mac_del(struct interface *ifp,
        zif = ifp->info;
        assert(zif);
        vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vni = vxl->vni_info.vni.vni;
 
        /* Check if EVPN is enabled. */
        if (!is_evpn_enabled())
@@ -4811,9 +4819,9 @@ int zebra_vxlan_if_down(struct interface *ifp)
 {
        vni_t vni;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan *vxl = NULL;
        struct zebra_l3vni *zl3vni = NULL;
        struct zebra_evpn *zevpn;
+       struct zebra_vxlan_vni *vnip;
 
        /* Check if EVPN is enabled. */
        if (!is_evpn_enabled())
@@ -4821,8 +4829,8 @@ int zebra_vxlan_if_down(struct interface *ifp)
 
        zif = ifp->info;
        assert(zif);
-       vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vnip = zebra_vxlan_if_vni_find(zif, 0);
+       vni = vnip->vni;
 
        zl3vni = zl3vni_lookup(vni);
        if (zl3vni) {
@@ -4874,9 +4882,9 @@ int zebra_vxlan_if_up(struct interface *ifp)
 {
        vni_t vni;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan *vxl = NULL;
        struct zebra_evpn *zevpn = NULL;
        struct zebra_l3vni *zl3vni = NULL;
+       struct zebra_vxlan_vni *vnip;
 
        /* Check if EVPN is enabled. */
        if (!is_evpn_enabled())
@@ -4884,8 +4892,8 @@ int zebra_vxlan_if_up(struct interface *ifp)
 
        zif = ifp->info;
        assert(zif);
-       vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vnip = zebra_vxlan_if_vni_find(zif, 0);
+       vni = vnip->vni;
 
        zl3vni = zl3vni_lookup(vni);
        if (zl3vni) {
@@ -4922,7 +4930,7 @@ int zebra_vxlan_if_up(struct interface *ifp)
                }
 
                assert(zevpn->vxlan_if == ifp);
-               vlan_if = zvni_map_to_svi(vxl->access_vlan,
+               vlan_if = zvni_map_to_svi(vnip->access_vlan,
                                          zif->brslave_info.br_if);
                if (vlan_if) {
                        zevpn->svi_if = vlan_if;
@@ -4951,9 +4959,9 @@ int zebra_vxlan_if_del(struct interface *ifp)
 {
        vni_t vni;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan *vxl = NULL;
        struct zebra_evpn *zevpn = NULL;
        struct zebra_l3vni *zl3vni = NULL;
+       struct zebra_vxlan_vni *vnip;
 
        /* Check if EVPN is enabled. */
        if (!is_evpn_enabled())
@@ -4961,8 +4969,8 @@ int zebra_vxlan_if_del(struct interface *ifp)
 
        zif = ifp->info;
        assert(zif);
-       vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vnip = zebra_vxlan_if_vni_find(zif, 0);
+       vni = vnip->vni;
 
        zl3vni = zl3vni_lookup(vni);
        if (zl3vni) {
@@ -5029,6 +5037,7 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
        struct zebra_evpn *zevpn = NULL;
        struct zebra_l3vni *zl3vni = NULL;
        struct interface *vlan_if = NULL;
+       struct zebra_vxlan_vni *vnip;
 
        /* Check if EVPN is enabled. */
        if (!is_evpn_enabled())
@@ -5036,8 +5045,8 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
 
        zif = ifp->info;
        assert(zif);
-       vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vnip = zebra_vxlan_if_vni_find(zif, 0);
+       vni = vnip->vni;
 
        zl3vni = zl3vni_lookup(vni);
        if (zl3vni) {
@@ -5045,9 +5054,9 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
                                "Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
-                               vni, ifp->name, ifp->ifindex, vxl->access_vlan,
-                               &vxl->vtep_ip,
-                               zif->brslave_info.bridge_ifindex, chgflags);
+                               vni, ifp->name, ifp->ifindex, vnip->access_vlan,
+                               &vxl->vtep_ip, zif->brslave_info.bridge_ifindex,
+                               chgflags);
 
                /* Removed from bridge? Cleanup and return */
                if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
@@ -5116,9 +5125,9 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
                                "Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
-                               vni, ifp->name, ifp->ifindex, vxl->access_vlan,
-                               &vxl->vtep_ip,
-                               zif->brslave_info.bridge_ifindex, chgflags);
+                               vni, ifp->name, ifp->ifindex, vnip->access_vlan,
+                               &vxl->vtep_ip, zif->brslave_info.bridge_ifindex,
+                               chgflags);
 
                /* Removed from bridge? Cleanup and return */
                if ((chgflags & ZEBRA_VXLIF_MASTER_CHANGE)
@@ -5142,20 +5151,20 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
                        zebra_evpn_mac_del_all(zevpn, 0, 1, DEL_LOCAL_MAC);
                }
 
-               if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
-                       zevpn->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
+               if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr
+                   || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) {
                        zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
                                zevpn->mcast_grp);
-                       zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
+                       zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp);
                        zevpn->local_vtep_ip = vxl->vtep_ip;
-                       zevpn->mcast_grp = vxl->mcast_grp;
+                       zevpn->mcast_grp = vnip->mcast_grp;
                        /* on local vtep-ip check if ES orig-ip
                         * needs to be updated
                         */
                        zebra_evpn_es_set_base_evpn(zevpn);
                }
                zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
-               vlan_if = zvni_map_to_svi(vxl->access_vlan,
+               vlan_if = zvni_map_to_svi(vnip->access_vlan,
                                          zif->brslave_info.br_if);
                if (vlan_if) {
                        zevpn->svi_if = vlan_if;
@@ -5216,6 +5225,7 @@ int zebra_vxlan_if_add(struct interface *ifp)
        struct zebra_l2info_vxlan *vxl = NULL;
        struct zebra_evpn *zevpn = NULL;
        struct zebra_l3vni *zl3vni = NULL;
+       struct zebra_vxlan_vni *vnip;
 
        /* Check if EVPN is enabled. */
        if (!is_evpn_enabled())
@@ -5223,8 +5233,8 @@ int zebra_vxlan_if_add(struct interface *ifp)
 
        zif = ifp->info;
        assert(zif);
-       vxl = &zif->l2info.vxl;
-       vni = vxl->vni;
+       vnip = zebra_vxlan_if_vni_find(zif, 0);
+       vni = vnip->vni;
 
        zl3vni = zl3vni_lookup(vni);
        if (zl3vni) {
@@ -5233,7 +5243,7 @@ int zebra_vxlan_if_add(struct interface *ifp)
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
                                "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
-                               vni, ifp->name, ifp->ifindex, vxl->access_vlan,
+                               vni, ifp->name, ifp->ifindex, vnip->access_vlan,
                                &vxl->vtep_ip,
                                zif->brslave_info.bridge_ifindex);
 
@@ -5259,20 +5269,20 @@ int zebra_vxlan_if_add(struct interface *ifp)
                if (!zevpn)
                        zevpn = zebra_evpn_add(vni);
 
-               if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr ||
-                       zevpn->mcast_grp.s_addr != vxl->mcast_grp.s_addr) {
+               if (zevpn->local_vtep_ip.s_addr != vxl->vtep_ip.s_addr
+                   || zevpn->mcast_grp.s_addr != vnip->mcast_grp.s_addr) {
                        zebra_vxlan_sg_deref(zevpn->local_vtep_ip,
                                zevpn->mcast_grp);
-                       zebra_vxlan_sg_ref(vxl->vtep_ip, vxl->mcast_grp);
+                       zebra_vxlan_sg_ref(vxl->vtep_ip, vnip->mcast_grp);
                        zevpn->local_vtep_ip = vxl->vtep_ip;
-                       zevpn->mcast_grp = vxl->mcast_grp;
+                       zevpn->mcast_grp = vnip->mcast_grp;
                        /* on local vtep-ip check if ES orig-ip
                         * needs to be updated
                         */
                        zebra_evpn_es_set_base_evpn(zevpn);
                }
                zevpn_vxlan_if_set(zevpn, ifp, true /* set */);
-               vlan_if = zvni_map_to_svi(vxl->access_vlan,
+               vlan_if = zvni_map_to_svi(vnip->access_vlan,
                                          zif->brslave_info.br_if);
                if (vlan_if) {
                        zevpn->svi_if = vlan_if;
@@ -5287,8 +5297,8 @@ int zebra_vxlan_if_add(struct interface *ifp)
                                "Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %pI4 mcast_grp %pI4 master %u",
                                vni,
                                vlan_if ? vlan_if->vrf->name : VRF_DEFAULT_NAME,
-                               ifp->name, ifp->ifindex, vxl->access_vlan,
-                               &vxl->vtep_ip, &vxl->mcast_grp,
+                               ifp->name, ifp->ifindex, vnip->access_vlan,
+                               &vxl->vtep_ip, &vnip->mcast_grp,
                                zif->brslave_info.bridge_ifindex);
 
                /* If down or not mapped to a bridge, we're done. */
@@ -5557,8 +5567,8 @@ void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
 
        } else {
                struct zebra_if *zif = NULL;
-               struct zebra_l2info_vxlan zl2_info;
                struct interface *vlan_if = NULL;
+               struct zebra_vxlan_vni *zl2_info_vni;
                int old_advertise;
 
                zevpn = zebra_evpn_lookup(vni);
@@ -5592,8 +5602,11 @@ void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS)
                if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
                        return;
 
-               zl2_info = zif->l2info.vxl;
-               vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
+               zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
+               if (!zl2_info_vni)
+                       return;
+
+               vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
                                          zif->brslave_info.br_if);
                if (!vlan_if)
                        return;
@@ -5623,8 +5636,8 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
        struct zebra_evpn *zevpn = NULL;
        struct interface *ifp = NULL;
        struct zebra_if *zif = NULL;
-       struct zebra_l2info_vxlan zl2_info;
        struct interface *vlan_if = NULL;
+       struct zebra_vxlan_vni *zl2_info_vni = NULL;
 
        if (!EVPN_ENABLED(zvrf)) {
                zlog_debug("EVPN GW-MACIP Adv for non-EVPN VRF %u",
@@ -5661,10 +5674,12 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
        if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
                return;
 
-       zl2_info = zif->l2info.vxl;
+       zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
+       if (!zl2_info_vni)
+               return;
 
-       vlan_if =
-               zvni_map_to_svi(zl2_info.access_vlan, zif->brslave_info.br_if);
+       vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
+                                 zif->brslave_info.br_if);
        if (!vlan_if)
                return;
 
@@ -5723,9 +5738,9 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
 
        } else {
                struct zebra_if *zif = NULL;
-               struct zebra_l2info_vxlan zl2_info;
                struct interface *vlan_if = NULL;
                struct interface *vrr_if = NULL;
+               struct zebra_vxlan_vni *zl2_info_vni = NULL;
                int old_advertise;
 
                zevpn = zebra_evpn_lookup(vni);
@@ -5755,9 +5770,11 @@ void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS)
                if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
                        return;
 
-               zl2_info = zif->l2info.vxl;
+               zl2_info_vni = zebra_vxlan_if_vni_find(zif, vni);
+               if (!zl2_info_vni)
+                       return;
 
-               vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
+               vlan_if = zvni_map_to_svi(zl2_info_vni->access_vlan,
                                          zif->brslave_info.br_if);
                if (!vlan_if)
                        return;
index 16c5bc0a1af5163c0636d15b5194d7dd800794be..657a0f538f7f3b6752183e74aed6f34d5e66f670 100644 (file)
@@ -36,6 +36,7 @@
 #include "zebra/zebra_vrf.h"
 #include "zebra/zserv.h"
 #include "zebra/zebra_dplane.h"
+#include "zebra/interface.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -55,6 +56,38 @@ is_vxlan_flooding_head_end(void)
        return (zvrf->vxlan_flood_ctrl == VXLAN_FLOOD_HEAD_END_REPL);
 }
 
+static inline struct zebra_vxlan_vni *
+zebra_vxlan_if_vni_find(const struct zebra_if *zif, vni_t vni)
+{
+       struct zebra_vxlan_vni *vnip = NULL;
+       const struct zebra_vxlan_vni_info *vni_info;
+
+       vni_info = VNI_INFO_FROM_ZEBRA_IF(zif);
+       if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
+               vnip = (struct zebra_vxlan_vni *)&vni_info->vni;
+               assert(vnip);
+               if (vni && (vnip->vni != vni))
+                       vnip = NULL;
+
+               return vnip;
+       }
+       return NULL;
+}
+
+static inline struct zebra_vxlan_vni *
+zebra_vxlan_if_access_vlan_find(struct zebra_if *zif, uint8_t vlan_aware,
+                               vlanid_t vid)
+{
+       struct zebra_vxlan_vni *vni = NULL;
+
+       if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
+               vni = zebra_vxlan_if_vni_find(zif, 0);
+               if (vlan_aware && vni->access_vlan != vid)
+                       vni = NULL;
+       }
+       return vni;
+}
+
 /* VxLAN interface change flags of interest. */
 #define ZEBRA_VXLIF_LOCAL_IP_CHANGE     (1 << 0)
 #define ZEBRA_VXLIF_MASTER_CHANGE       (1 << 1)
@@ -62,6 +95,10 @@ is_vxlan_flooding_head_end(void)
 #define ZEBRA_VXLIF_MCAST_GRP_CHANGE    (1 << 3)
 #define ZEBRA_VXLIF_MASTER_MAC_CHANGE (1 << 4)
 
+#define ZEBRA_VXLIF_VNI_UPDATE(__flags)                                        \
+       ((__flags) & (ZEBRA_VXLIF_VLAN_CHANGE | ZEBRA_VXLIF_MCAST_GRP_CHANGE))
+#define ZEBRA_VXLIF_UPDATE(__flags)                                            \
+       ((__flags) & (ZEBRA_VXLIF_LOCAL_IP_CHANGE | ZEBRA_VXLIF_MASTER_CHANGE))
 
 #define VNI_STR_LEN 32