summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_l2.c
diff options
context:
space:
mode:
authorsharathr <sharathr@cumulusnetworks.com>2021-10-08 16:27:50 +0200
committerStephen Worley <sworley@nvidia.com>2023-02-14 00:12:05 +0100
commit00d30205eff94a0940e895ea0558355b48de0574 (patch)
tree20a356254f7a45a682d6bc990b88eae48e4be701 /zebra/zebra_l2.c
parentzebra: Clean remote FDB entries upon VNI removal (diff)
downloadfrr-00d30205eff94a0940e895ea0558355b48de0574.tar.xz
frr-00d30205eff94a0940e895ea0558355b48de0574.zip
zebra: fix for unexpected fdb entry showing up during ifdown/ifup events
Ticket: 2674793 Testing Done: precommit, evpn-min and evpn-smoke The problem in this case is whenever we are triggering ifdown followed by ifup of bridge, we see that remote mac entries are programmed with vlan-1 in the fdb from zebra and never cleaned up. bridge has vlan_default_pvid 1 which means any port that gets added will initially have vlan 1 which then gets deleted by ifupdown2 and the proper vlan gets added. The problem lies in zebra where we are not cleaning up the remote macs during vlan change. Fix is to uninstall the remote macs and then install them during vlan change. Signed-off-by: Stephen Worley <sworley@nvidia.com>
Diffstat (limited to 'zebra/zebra_l2.c')
-rw-r--r--zebra/zebra_l2.c43
1 files changed, 30 insertions, 13 deletions
diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c
index c43fe4902..c5d4c5885 100644
--- a/zebra/zebra_l2.c
+++ b/zebra/zebra_l2.c
@@ -347,8 +347,8 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
struct zebra_l2info_vxlan *vxlan_info, int add)
{
struct zebra_if *zif;
- struct in_addr old_vtep_ip;
uint16_t chgflags = 0;
+ struct zebra_vxlan_if_update_ctx ctx;
zif = ifp->info;
assert(zif);
@@ -359,14 +359,16 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
return;
}
- old_vtep_ip = zif->l2info.vxl.vtep_ip;
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.old_vtep_ip = zif->l2info.vxl.vtep_ip;
- if (!IPV4_ADDR_SAME(&old_vtep_ip, &vxlan_info->vtep_ip)) {
+ if (!IPV4_ADDR_SAME(&ctx.old_vtep_ip, &vxlan_info->vtep_ip)) {
chgflags |= ZEBRA_VXLIF_LOCAL_IP_CHANGE;
zif->l2info.vxl.vtep_ip = vxlan_info->vtep_ip;
}
if (IS_ZEBRA_VXLAN_IF_VNI(zif)) {
+ ctx.old_vni = vxlan_info->vni_info.vni;
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;
@@ -375,8 +377,10 @@ void zebra_l2_vxlanif_add_update(struct interface *ifp,
}
}
- if (chgflags)
- zebra_vxlan_if_update(ifp, chgflags);
+ if (chgflags) {
+ ctx.chgflags = chgflags;
+ zebra_vxlan_if_update(ifp, &ctx);
+ }
}
/*
@@ -388,6 +392,7 @@ void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
struct zebra_if *zif;
vlanid_t old_access_vlan;
struct zebra_vxlan_vni *vni;
+ struct zebra_vxlan_if_update_ctx ctx;
zif = ifp->info;
@@ -401,12 +406,15 @@ void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp,
if (old_access_vlan == access_vlan)
return;
+ memset(&ctx, 0, sizeof(ctx));
vni = zebra_vxlan_if_vni_find(zif, 0);
+ ctx.old_vni = *vni;
+ ctx.chgflags = ZEBRA_VXLIF_VLAN_CHANGE;
vni->access_vlan = access_vlan;
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);
+ zebra_vxlan_if_update(ifp, &ctx);
}
/*
@@ -435,6 +443,9 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
ifindex_t old_bridge_ifindex;
ns_id_t old_ns_id;
struct zebra_vrf *zvrf;
+ struct zebra_vxlan_if_update_ctx ctx;
+
+ memset(&ctx, 0, sizeof(ctx));
zif = ifp->info;
assert(zif);
@@ -445,11 +456,14 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
if (zif->zif_type == ZEBRA_IF_VXLAN
&& chgflags != ZEBRA_BRIDGE_NO_ACTION) {
- if (chgflags & ZEBRA_BRIDGE_MASTER_MAC_CHANGE)
- zebra_vxlan_if_update(ifp,
- ZEBRA_VXLIF_MASTER_MAC_CHANGE);
- if (chgflags & ZEBRA_BRIDGE_MASTER_UP)
- zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
+ if (chgflags & ZEBRA_BRIDGE_MASTER_MAC_CHANGE) {
+ ctx.chgflags = ZEBRA_VXLIF_MASTER_MAC_CHANGE;
+ zebra_vxlan_if_update(ifp, &ctx);
+ }
+ if (chgflags & ZEBRA_BRIDGE_MASTER_UP) {
+ ctx.chgflags = ZEBRA_VXLIF_MASTER_CHANGE;
+ zebra_vxlan_if_update(ifp, &ctx);
+ }
}
old_bridge_ifindex = zif->brslave_info.bridge_ifindex;
old_ns_id = zif->brslave_info.ns_id;
@@ -457,6 +471,9 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
old_ns_id == zif->brslave_info.ns_id)
return;
+ ctx.chgflags = ZEBRA_VXLIF_MASTER_CHANGE;
+
+
zif->brslave_info.ns_id = ns_id;
zif->brslave_info.bridge_ifindex = bridge_ifindex;
/* Set up or remove link with master */
@@ -464,7 +481,7 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
zebra_l2_map_slave_to_bridge(&zif->brslave_info, zvrf->zns);
/* In the case of VxLAN, invoke the handler for EVPN. */
if (zif->zif_type == ZEBRA_IF_VXLAN)
- zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
+ zebra_vxlan_if_update(ifp, &ctx);
if (zif->es_info.es)
zebra_evpn_es_local_br_port_update(zif);
} else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
@@ -474,7 +491,7 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
* to unmapping the interface from the bridge.
*/
if (zif->zif_type == ZEBRA_IF_VXLAN)
- zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
+ zebra_vxlan_if_update(ifp, &ctx);
if (zif->es_info.es)
zebra_evpn_es_local_br_port_update(zif);
zebra_l2_unmap_slave_from_bridge(&zif->brslave_info);