diff options
author | Sharath Ramamurthy <sramamurthy@nvidia.com> | 2021-07-27 09:44:15 +0200 |
---|---|---|
committer | Stephen Worley <sworley@nvidia.com> | 2023-02-14 00:12:04 +0100 |
commit | 8d30ff3b5ef815ad5cab092f2ce6dc28ab5e3421 (patch) | |
tree | dba0c94cddbbb5cf0303e16e5a8fa208ba20feea | |
parent | Merge pull request #12776 from patrasar/Issue_12755 (diff) | |
download | frr-8d30ff3b5ef815ad5cab092f2ce6dc28ab5e3421.tar.xz frr-8d30ff3b5ef815ad5cab092f2ce6dc28ab5e3421.zip |
zebra: data structure changes for single vxlan device
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>
-rw-r--r-- | zebra/dplane_fpm_nl.c | 8 | ||||
-rw-r--r-- | zebra/if_netlink.c | 4 | ||||
-rw-r--r-- | zebra/interface.c | 168 | ||||
-rw-r--r-- | zebra/rt_netlink.c | 2 | ||||
-rw-r--r-- | zebra/zebra_evpn.c | 73 | ||||
-rw-r--r-- | zebra/zebra_evpn.h | 10 | ||||
-rw-r--r-- | zebra/zebra_evpn_mac.c | 21 | ||||
-rw-r--r-- | zebra/zebra_evpn_mh.c | 59 | ||||
-rw-r--r-- | zebra/zebra_evpn_mh.h | 7 | ||||
-rw-r--r-- | zebra/zebra_l2.c | 32 | ||||
-rw-r--r-- | zebra/zebra_l2.h | 44 | ||||
-rw-r--r-- | zebra/zebra_nb_state.c | 19 | ||||
-rw-r--r-- | zebra/zebra_vxlan.c | 167 | ||||
-rw-r--r-- | zebra/zebra_vxlan.h | 37 |
14 files changed, 434 insertions, 217 deletions
diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index 0a9fecc9d..8fb230ffa 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -45,9 +45,10 @@ #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); diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c index 835659332..6df8a4067 100644 --- a/zebra/if_netlink.c +++ b/zebra/if_netlink.c @@ -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]); } diff --git a/zebra/interface.c b/zebra/interface.c index 59563834e..81abb13b7 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -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; diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 216b719ff..79d6af60c 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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. */ diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index ff9ca1ac2..42ebedf60 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -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)) { diff --git a/zebra/zebra_evpn.h b/zebra/zebra_evpn.h index 2c84d2304..5dd54a117 100644 --- a/zebra/zebra_evpn.h +++ b/zebra/zebra_evpn.h @@ -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); diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 2c953eef1..4b30a5448 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -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; } diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 01ea9c5b9..642169840 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -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; } diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 037648311..2c6e4924f 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -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); diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c index 8a9f3dffe..550b81942 100644 --- a/zebra/zebra_l2.c +++ b/zebra/zebra_l2.c @@ -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); } diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h index 1c3e98158..0df75ac07 100644 --- a/zebra/zebra_l2.h +++ b/zebra/zebra_l2.h @@ -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) diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c index 0f3d56f21..0c0bd5638 100644 --- a/zebra/zebra_nb_state.c +++ b/zebra/zebra_nb_state.c @@ -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) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 0bbc81132..3e7f56680 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -49,10 +49,10 @@ #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; diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index 16c5bc0a1..657a0f538 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -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 |