From e4c3ece6e0bca4ee457a19211e5f51316dea7525 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Wed, 17 Feb 2021 18:36:56 -0800 Subject: [PATCH] zebra: fix problem with SVI MAC not being sent to BGP For MH the SVI MAC is advertised to prevent flooding of ARP replies. But because of a bug the SVI MAC was being added to the zebra database but not sent to bgpd for advertising. Ticket: CM-33329 Signed-off-by: Anuradha Karuppiah --- zebra/zebra_evpn.c | 2 +- zebra/zebra_evpn_mac.c | 25 +++++++++++++++++++++---- zebra/zebra_evpn_mac.h | 3 ++- zebra/zebra_evpn_mh.c | 23 +++++++++++++++++------ zebra/zebra_evpn_mh.h | 6 ++++++ 5 files changed, 47 insertions(+), 12 deletions(-) diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index 2047c711de..d7076ccce6 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -434,7 +434,7 @@ int zebra_evpn_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, vxl = &zif->l2info.vxl; if (zebra_evpn_mac_gw_macip_add(ifp, zevpn, ip, &mac, macaddr, - vxl->access_vlan) + vxl->access_vlan, true) != 0) return -1; diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 6d7c655dcc..90227aa597 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -2382,7 +2382,8 @@ int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac) int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, struct ipaddr *ip, zebra_mac_t **macp, - struct ethaddr *macaddr, vlanid_t vlan_id) + struct ethaddr *macaddr, vlanid_t vlan_id, + bool def_gw) { char buf[ETHER_ADDR_STRLEN]; zebra_mac_t *mac; @@ -2408,7 +2409,8 @@ int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, /* Set "local" forwarding info. */ SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL); SET_FLAG(mac->flags, ZEBRA_MAC_AUTO); - SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW); + if (def_gw) + SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW); memset(&mac->fwd_info, 0, sizeof(mac->fwd_info)); mac->fwd_info.local.ifindex = ifp->ifindex; mac->fwd_info.local.ns_id = local_ns_id; @@ -2423,6 +2425,7 @@ void zebra_evpn_mac_svi_del(struct interface *ifp, zebra_evpn_t *zevpn) { zebra_mac_t *mac; struct ethaddr macaddr; + bool old_bgp_ready; if (!zebra_evpn_mh_do_adv_svi_mac()) return; @@ -2433,7 +2436,10 @@ void zebra_evpn_mac_svi_del(struct interface *ifp, zebra_evpn_t *zevpn) if (IS_ZEBRA_DEBUG_EVPN_MH_ES) zlog_debug("SVI %s mac free", ifp->name); + old_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); UNSET_FLAG(mac->flags, ZEBRA_MAC_SVI); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + false); zebra_evpn_deref_ip2mac(mac->zevpn, mac); } } @@ -2443,8 +2449,11 @@ void zebra_evpn_mac_svi_add(struct interface *ifp, zebra_evpn_t *zevpn) zebra_mac_t *mac = NULL; struct ethaddr macaddr; struct zebra_if *zif = ifp->info; + bool old_bgp_ready; + bool new_bgp_ready; - if (!zebra_evpn_mh_do_adv_svi_mac()) + if (!zebra_evpn_mh_do_adv_svi_mac() + || !zebra_evpn_send_to_client_ok(zevpn)) return; memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN); @@ -2458,8 +2467,16 @@ void zebra_evpn_mac_svi_add(struct interface *ifp, zebra_evpn_t *zevpn) if (IS_ZEBRA_DEBUG_EVPN_MH_ES) zlog_debug("SVI %s mac add", zif->ifp->name); + old_bgp_ready = (mac && zebra_evpn_mac_is_ready_for_bgp(mac->flags)) + ? true + : false; + mac = NULL; - zebra_evpn_mac_gw_macip_add(ifp, zevpn, NULL, &mac, &macaddr, 0); + zebra_evpn_mac_gw_macip_add(ifp, zevpn, NULL, &mac, &macaddr, 0, false); if (mac) SET_FLAG(mac->flags, ZEBRA_MAC_SVI); + + new_bgp_ready = zebra_evpn_mac_is_ready_for_bgp(mac->flags); + zebra_evpn_mac_send_add_del_to_client(mac, old_bgp_ready, + new_bgp_ready); } diff --git a/zebra/zebra_evpn_mac.h b/zebra/zebra_evpn_mac.h index fd6257faf0..c021765843 100644 --- a/zebra/zebra_evpn_mac.h +++ b/zebra/zebra_evpn_mac.h @@ -264,7 +264,8 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn, int zebra_evpn_del_local_mac(zebra_evpn_t *zevpn, zebra_mac_t *mac); int zebra_evpn_mac_gw_macip_add(struct interface *ifp, zebra_evpn_t *zevpn, struct ipaddr *ip, zebra_mac_t **macp, - struct ethaddr *macaddr, vlanid_t vlan_id); + struct ethaddr *macaddr, vlanid_t vlan_id, + bool def_gw); void zebra_evpn_mac_svi_add(struct interface *ifp, zebra_evpn_t *zevpn); void zebra_evpn_mac_svi_del(struct interface *ifp, zebra_evpn_t *zevpn); diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index bb109e9921..0bb1ebb564 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -130,12 +130,6 @@ static struct zebra_evpn_es_evi *zebra_evpn_es_evi_new(struct zebra_evpn_es *es, return es_evi; } -/* returns TRUE if the EVPN is ready to be sent to BGP */ -static inline bool zebra_evpn_send_to_client_ok(zebra_evpn_t *zevpn) -{ - return !!(zevpn->flags & ZEVPN_READY_FOR_BGP); -} - /* Evaluate if the es_evi is ready to be sent BGP - * 1. If it is ready an add is sent to BGP * 2. If it is not ready a del is sent (if the ES had been previously added @@ -466,6 +460,9 @@ void zebra_evpn_update_all_es(zebra_evpn_t *zevpn) { struct zebra_evpn_es_evi *es_evi; struct listnode *node; + struct interface *vlan_if; + struct interface *vxlan_if; + struct zebra_if *vxlan_zif; /* the EVPN is now elgible as a base for EVPN-MH */ if (zebra_evpn_send_to_client_ok(zevpn)) @@ -475,6 +472,20 @@ void zebra_evpn_update_all_es(zebra_evpn_t *zevpn) for (ALL_LIST_ELEMENTS_RO(zevpn->local_es_evi_list, node, es_evi)) zebra_evpn_es_evi_re_eval_send_to_client(es_evi); + + /* reinstall SVI MAC */ + vxlan_if = zevpn->vxlan_if; + if (vxlan_if) { + 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); + if (vlan_if) + zebra_evpn_acc_bd_svi_mac_add(vlan_if); + } + } } /*****************************************************************************/ diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 6d21434778..94de84ff14 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -262,6 +262,12 @@ struct zebra_evpn_mh_info { enum protodown_reasons protodown_rc; }; +/* returns TRUE if the EVPN is ready to be sent to BGP */ +static inline bool zebra_evpn_send_to_client_ok(zebra_evpn_t *zevpn) +{ + return !!(zevpn->flags & ZEVPN_READY_FOR_BGP); +} + static inline bool zebra_evpn_mac_is_es_local(zebra_mac_t *mac) { return mac->es && (mac->es->flags & ZEBRA_EVPNES_LOCAL); -- 2.39.5