diff options
author | sharathr <sharathr@cumulusnetworks.com> | 2021-10-08 16:27:50 +0200 |
---|---|---|
committer | Stephen Worley <sworley@nvidia.com> | 2023-02-14 00:12:05 +0100 |
commit | 00d30205eff94a0940e895ea0558355b48de0574 (patch) | |
tree | 20a356254f7a45a682d6bc990b88eae48e4be701 /zebra/zebra_l2.c | |
parent | zebra: Clean remote FDB entries upon VNI removal (diff) | |
download | frr-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.c | 43 |
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); |