diff --git a/zebra/zebra_evpn_arp_nd.c b/zebra/zebra_evpn_arp_nd.c index 5e23fed5542b..30e6a52a9f85 100644 --- a/zebra/zebra_evpn_arp_nd.c +++ b/zebra/zebra_evpn_arp_nd.c @@ -377,7 +377,6 @@ static int zebra_evpn_arp_nd_recvmsg(int fd, uint8_t *buf, size_t len, static void zebra_evpn_arp_nd_read(struct event *thread); static void zebra_evpn_arp_nd_pkt_read_enable(struct zebra_if *zif) { - zif->arp_nd_info.t_pkt_read = NULL; event_add_read(zrouter.master, zebra_evpn_arp_nd_read, zif, zif->arp_nd_info.pkt_fd, &zif->arp_nd_info.t_pkt_read); } @@ -625,7 +624,7 @@ void zebra_evpn_arp_nd_udp_sock_create(void) } /* Enable ARP/NA snooping on all existing brigde members */ -static void zebra_evpn_arp_nd_if_update_all(void) +static void zebra_evpn_arp_nd_if_update_all(bool enable) { struct vrf *vrf; struct interface *ifp; @@ -636,7 +635,7 @@ static void zebra_evpn_arp_nd_if_update_all(void) continue; if (!IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) continue; - zebra_evpn_arp_nd_if_update(ifp->info, true); + zebra_evpn_arp_nd_if_update(ifp->info, enable); } } } @@ -662,5 +661,25 @@ void zebra_evpn_arp_nd_failover_enable(void) /* walkthrough existing br-ports and enable * snooping on them */ - zebra_evpn_arp_nd_if_update_all(); + zebra_evpn_arp_nd_if_update_all(true); +} + +void zebra_evpn_arp_nd_failover_disable(void) +{ + /* If fast failover is not enabled there is nothing to do */ + if (!(zevpn_arp_nd_info.flags & ZEBRA_EVPN_ARP_ND_FAILOVER)) + return; + + if (IS_ZEBRA_DEBUG_EVPN_MH_ARP_ND_EVT) + zlog_debug("Disable arp_nd failover"); + + /* walkthrough existing br-ports and disable + * snooping on them */ + zebra_evpn_arp_nd_if_update_all(false); + + /* close the UDP tx socket */ + close(zevpn_arp_nd_info.udp_fd); + zevpn_arp_nd_info.udp_fd = -1; + + zevpn_arp_nd_info.flags &= ~ZEBRA_EVPN_ARP_ND_FAILOVER; } diff --git a/zebra/zebra_evpn_arp_nd.h b/zebra/zebra_evpn_arp_nd.h index ad669082639e..552a91ca29b7 100644 --- a/zebra/zebra_evpn_arp_nd.h +++ b/zebra/zebra_evpn_arp_nd.h @@ -64,6 +64,7 @@ struct zebra_evpn_arp_nd_info { /*****************************************************************************/ extern void zebra_evpn_arp_nd_failover_enable(void); +extern void zebra_evpn_arp_nd_failover_disable(void); extern void zebra_evpn_arp_nd_udp_sock_create(void); extern void zebra_evpn_arp_nd_if_update(struct zebra_if *zif, bool enable); extern void zebra_evpn_arp_nd_print_summary(struct vty *vty, bool uj); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 5480a94d27c5..1837d0a29c1b 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -41,6 +41,7 @@ #include "zebra/zebra_evpn_mh.h" #include "zebra/zebra_evpn_vxlan.h" #include "zebra/zebra_router.h" +#include "zebra/zebra_evpn_arp_nd.h" DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix"); DEFINE_MTYPE_STATIC(ZEBRA, ZL3VNI, "L3 VNI hash"); @@ -5780,6 +5781,12 @@ void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf) { struct zebra_vrf *evpn_zvrf = zebra_vrf_get_evpn(); + if (!zvrf) + return; + + if (zvrf == evpn_zvrf) + zebra_evpn_arp_nd_failover_disable(); + hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf); zebra_vxlan_cleanup_sg_table(zvrf); @@ -5790,8 +5797,14 @@ void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf) /* Close all EVPN handling */ void zebra_vxlan_close_tables(struct zebra_vrf *zvrf) { + struct zebra_vrf *evpn_zvrf = zebra_vrf_get_evpn(); + if (!zvrf) return; + + if (zvrf == evpn_zvrf) + zebra_evpn_arp_nd_failover_disable(); + hash_iterate(zvrf->evpn_table, zebra_evpn_vxlan_cleanup_all, zvrf); hash_free(zvrf->evpn_table); if (zvrf->vxlan_sg_table) {