From 6e59c4a71dd262f47dabe8286c59536cb417c494 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Mon, 9 Aug 2021 11:50:22 -0700 Subject: [PATCH 1/3] zebra: deref the ES on interface delete even if it was not setup as a br-port This addresses deletion of ES interfaces that are were not completely configured. Ticket: #2668488 Signed-off-by: Anuradha Karuppiah --- zebra/zebra_evpn_mh.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index e03cf9db06..70382fea6a 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -1050,15 +1050,15 @@ void zebra_evpn_if_cleanup(struct zebra_if *zif) vlanid_t vid; struct zebra_evpn_es *es; - if (!bf_is_inited(zif->vlan_bitmap)) - return; + if (bf_is_inited(zif->vlan_bitmap)) { + bf_for_each_set_bit(zif->vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) + { + zebra_evpn_vl_mbr_deref(vid, zif); + } - bf_for_each_set_bit(zif->vlan_bitmap, vid, IF_VLAN_BITMAP_MAX) { - zebra_evpn_vl_mbr_deref(vid, zif); + bf_free(zif->vlan_bitmap); } - bf_free(zif->vlan_bitmap); - /* Delete associated Ethernet Segment */ es = zif->es_info.es; if (es) From 38f681e1cac07dac996ae952c99684501cf820c6 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Tue, 10 Aug 2021 08:56:55 -0700 Subject: [PATCH 2/3] zebra: ignore sync updates from bgp if the dest ES is not ready In the window immediately after an ES deletion bgpd can send MAC-IP updates using that ES. Zebra needs to ignore these updates to prevent creation of stale entries. Ticket: #2668488 Signed-off-by: Anuradha Karuppiah --- zebra/zebra_evpn.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_evpn.c b/zebra/zebra_evpn.c index d5e043eea8..4006e1fed5 100644 --- a/zebra/zebra_evpn.c +++ b/zebra/zebra_evpn.c @@ -1423,8 +1423,24 @@ void zebra_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr, * REMOTE - if ES is not local */ if (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) { - zebra_evpn_process_sync_macip_add(zevpn, macaddr, ipa_len, - ipaddr, flags, seq, esi); + struct zebra_evpn_es *es; + + es = zebra_evpn_es_find(esi); + if (es && (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)) { + zebra_evpn_process_sync_macip_add(zevpn, macaddr, + ipa_len, ipaddr, + flags, seq, esi); + } else { + if (IS_ZEBRA_DEBUG_EVPN_MH_ES) { + char esi_str[ESI_STR_LEN]; + + esi_to_str(esi, esi_str, sizeof(esi_str)); + zlog_debug( + "Ignore sync-macip add; ES %s is not ready", + esi_str); + } + } + return; } From 09de6e45505715ee85d0a4bcd47d9b03ad2b7610 Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Tue, 10 Aug 2021 14:31:34 -0700 Subject: [PATCH 3/3] zebra: defer local MAC dataplane install on an ES till the ES-EVI is created When an ES is deleted and re-added bgpd can start sending MAC-IP sync updates before the dataplane and zebra have setup the VLAN membership for the ES. Such MAC entries are not installed in the dataplane till the ES-EVI is created. Ticket: #2668488 Signed-off-by: Anuradha Karuppiah --- zebra/zebra_evpn_mac.c | 19 +++++++++++++++++++ zebra/zebra_evpn_mh.c | 34 ++++++++++++++++++++++++++++++++-- zebra/zebra_evpn_mh.h | 2 ++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_evpn_mac.c b/zebra/zebra_evpn_mac.c index 472e53b730..c1bb19d4e5 100644 --- a/zebra/zebra_evpn_mac.c +++ b/zebra/zebra_evpn_mac.c @@ -1342,6 +1342,25 @@ int zebra_evpn_sync_mac_dp_install(struct zebra_mac *mac, bool set_inactive, struct zebra_if *zif; struct interface *br_ifp; + /* If the ES-EVI doesn't exist defer install. When the ES-EVI is + * created we will attempt to install the mac entry again + */ + if (mac->es) { + struct zebra_evpn_es_evi *es_evi; + + es_evi = zebra_evpn_es_evi_find(mac->es, mac->zevpn); + if (!es_evi) { + if (IS_ZEBRA_DEBUG_EVPN_MH_MAC) + zlog_debug( + "%s: dp-install sync-mac vni %u mac %pEA es %s 0x%x %sskipped, no es-evi", + caller, zevpn->vni, &mac->macaddr, + mac->es ? mac->es->esi_str : "-", + mac->flags, + set_inactive ? "inactive " : ""); + return -1; + } + } + /* get the access vlan from the vxlan_device */ zebra_evpn_mac_get_access_info(mac, &ifp, &vid); diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c index 70382fea6a..3f7e6256fc 100644 --- a/zebra/zebra_evpn_mh.c +++ b/zebra/zebra_evpn_mh.c @@ -186,8 +186,8 @@ static void zebra_evpn_es_evi_free(struct zebra_evpn_es_evi *es_evi) } /* find the ES-EVI in the per-L2-VNI RB tree */ -static struct zebra_evpn_es_evi * -zebra_evpn_es_evi_find(struct zebra_evpn_es *es, struct zebra_evpn *zevpn) +struct zebra_evpn_es_evi *zebra_evpn_es_evi_find(struct zebra_evpn_es *es, + struct zebra_evpn *zevpn) { struct zebra_evpn_es_evi es_evi; @@ -229,6 +229,34 @@ static void zebra_evpn_local_es_evi_del(struct zebra_evpn_es *es, zebra_evpn_local_es_evi_do_del(es_evi); } +/* If there are any existing MAC entries for this es/zevpn we need + * to install it in the dataplane. + * + * Note: primary purpose of this is to handle es del/re-add windows where + * sync MAC entries may be added by bgpd before the es-evi membership is + * created in the dataplane and in zebra + */ +static void zebra_evpn_es_evi_mac_install(struct zebra_evpn_es_evi *es_evi) +{ + struct zebra_mac *mac; + struct listnode *node; + struct zebra_evpn_es *es = es_evi->es; + + if (listcount(es->mac_list) && IS_ZEBRA_DEBUG_EVPN_MH_ES) + zlog_debug("dp-mac install on es %s evi %d add", es->esi_str, + es_evi->zevpn->vni); + + for (ALL_LIST_ELEMENTS_RO(es->mac_list, node, mac)) { + if (mac->zevpn != es_evi->zevpn) + continue; + + if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) + continue; + + zebra_evpn_sync_mac_dp_install(mac, false, false, __func__); + } +} + /* Create an ES-EVI if it doesn't already exist and tell BGP */ static void zebra_evpn_local_es_evi_add(struct zebra_evpn_es *es, struct zebra_evpn *zevpn) @@ -250,6 +278,8 @@ static void zebra_evpn_local_es_evi_add(struct zebra_evpn_es *es, listnode_add(zevpn->local_es_evi_list, &es_evi->l2vni_listnode); zebra_evpn_es_evi_re_eval_send_to_client(es_evi); + + zebra_evpn_es_evi_mac_install(es_evi); } } diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h index 853af7c4bc..af6832092b 100644 --- a/zebra/zebra_evpn_mh.h +++ b/zebra/zebra_evpn_mh.h @@ -387,5 +387,7 @@ extern void zebra_evpn_acc_bd_svi_mac_add(struct interface *vlan_if); extern void zebra_evpn_es_bypass_update(struct zebra_evpn_es *es, struct interface *ifp, bool bypass); extern void zebra_evpn_proc_remote_nh(ZAPI_HANDLER_ARGS); +extern struct zebra_evpn_es_evi * +zebra_evpn_es_evi_find(struct zebra_evpn_es *es, struct zebra_evpn *zevpn); #endif /* _ZEBRA_EVPN_MH_H */