zebra: remove FDB entries before de-activating a L2-NHG

NHG is activated i.e. programmed in the dataplane only if there
are active-VTEPs associated with it. When a NHG is de-activated
all the remote-mac entries associated with it need to be removed
before the NHG is removed.

Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
This commit is contained in:
Anuradha Karuppiah 2020-05-08 16:28:15 -07:00 committed by Anuradha Karuppiah
parent 9f3bcd52e1
commit f3722826a4
3 changed files with 33 additions and 7 deletions

View File

@ -155,7 +155,8 @@ int zebra_evpn_rem_mac_install(zebra_evpn_t *zevpn, zebra_mac_t *mac,
/* /*
* Uninstall remote MAC from the forwarding plane. * Uninstall remote MAC from the forwarding plane.
*/ */
int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevpn, zebra_mac_t *mac) int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevpn, zebra_mac_t *mac,
bool force)
{ {
const struct zebra_if *zif, *br_zif; const struct zebra_if *zif, *br_zif;
const struct zebra_l2info_vxlan *vxl; const struct zebra_l2info_vxlan *vxl;
@ -167,6 +168,10 @@ int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevpn, zebra_mac_t *mac)
if (!(mac->flags & ZEBRA_MAC_REMOTE)) if (!(mac->flags & ZEBRA_MAC_REMOTE))
return 0; return 0;
/* If the MAC was not installed there is no need to uninstall it */
if (!force && mac->es && !(mac->es->flags & ZEBRA_EVPNES_NHG_ACTIVE))
return -1;
if (!zevpn->vxlan_if) { if (!zevpn->vxlan_if) {
if (IS_ZEBRA_DEBUG_VXLAN) if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug( zlog_debug(
@ -216,7 +221,7 @@ void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevpn, zebra_mac_t *mac)
*/ */
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE) if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
&& remote_neigh_count(mac) == 0) { && remote_neigh_count(mac) == 0) {
zebra_evpn_rem_mac_uninstall(zevpn, mac); zebra_evpn_rem_mac_uninstall(zevpn, mac, false /*force*/);
zebra_evpn_es_mac_deref_entry(mac); zebra_evpn_es_mac_deref_entry(mac);
UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
} }
@ -1076,7 +1081,8 @@ static void zebra_evpn_mac_del_hash_entry(struct hash_bucket *bucket, void *arg)
__func__); __func__);
if (mac->flags & ZEBRA_MAC_REMOTE) if (mac->flags & ZEBRA_MAC_REMOTE)
zebra_evpn_rem_mac_uninstall(wctx->zevpn, mac); zebra_evpn_rem_mac_uninstall(wctx->zevpn, mac,
false /*force*/);
} }
zebra_evpn_mac_del(wctx->zevpn, mac); zebra_evpn_mac_del(wctx->zevpn, mac);
@ -1694,7 +1700,7 @@ void zebra_evpn_rem_mac_del(zebra_evpn_t *zevpn, zebra_mac_t *mac)
* go away, we need to uninstall the MAC. * go away, we need to uninstall the MAC.
*/ */
if (remote_neigh_count(mac) == 0) { if (remote_neigh_count(mac) == 0) {
zebra_evpn_rem_mac_uninstall(zevpn, mac); zebra_evpn_rem_mac_uninstall(zevpn, mac, false /*force*/);
zebra_evpn_es_mac_deref_entry(mac); zebra_evpn_es_mac_deref_entry(mac);
UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE); UNSET_FLAG(mac->flags, ZEBRA_MAC_REMOTE);
} }

View File

@ -204,7 +204,8 @@ static inline void zebra_evpn_mac_clear_sync_info(zebra_mac_t *mac)
struct hash *zebra_mac_db_create(const char *desc); struct hash *zebra_mac_db_create(const char *desc);
uint32_t num_valid_macs(zebra_evpn_t *zevi); uint32_t num_valid_macs(zebra_evpn_t *zevi);
uint32_t num_dup_detected_macs(zebra_evpn_t *zevi); uint32_t num_dup_detected_macs(zebra_evpn_t *zevi);
int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevi, zebra_mac_t *mac); int zebra_evpn_rem_mac_uninstall(zebra_evpn_t *zevi, zebra_mac_t *mac,
bool force);
int zebra_evpn_rem_mac_install(zebra_evpn_t *zevi, zebra_mac_t *mac, int zebra_evpn_rem_mac_install(zebra_evpn_t *zevi, zebra_mac_t *mac,
bool was_static); bool was_static);
void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevi, zebra_mac_t *mac); void zebra_evpn_deref_ip2mac(zebra_evpn_t *zevi, zebra_mac_t *mac);

View File

@ -989,6 +989,25 @@ static void zebra_evpn_nhid_free(uint32_t nh_id)
bf_release_index(zmh_info->nh_id_bitmap, id); bf_release_index(zmh_info->nh_id_bitmap, id);
} }
/* update remote macs associated with the ES */
static void zebra_evpn_nhg_mac_update(struct zebra_evpn_es *es)
{
zebra_mac_t *mac;
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(es->mac_list, node, mac)) {
if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE))
continue;
if (es->flags & ZEBRA_EVPNES_NHG_ACTIVE)
zebra_evpn_rem_mac_install(mac->zevpn, mac,
false /*was_static*/);
else
zebra_evpn_rem_mac_uninstall(mac->zevpn, mac,
true /*force*/);
}
}
/* The MAC ECMP group is activated on the first VTEP */ /* The MAC ECMP group is activated on the first VTEP */
static void zebra_evpn_nhg_update(struct zebra_evpn_es *es) static void zebra_evpn_nhg_update(struct zebra_evpn_es *es)
{ {
@ -1028,7 +1047,6 @@ static void zebra_evpn_nhg_update(struct zebra_evpn_es *es)
es->nhg_id, nh_str); es->nhg_id, nh_str);
} }
es->flags |= ZEBRA_EVPNES_NHG_ACTIVE;
kernel_upd_mac_nhg(es->nhg_id, nh_cnt, nh_ids); kernel_upd_mac_nhg(es->nhg_id, nh_cnt, nh_ids);
if (!(es->flags & ZEBRA_EVPNES_NHG_ACTIVE)) { if (!(es->flags & ZEBRA_EVPNES_NHG_ACTIVE)) {
es->flags |= ZEBRA_EVPNES_NHG_ACTIVE; es->flags |= ZEBRA_EVPNES_NHG_ACTIVE;
@ -1036,6 +1054,7 @@ static void zebra_evpn_nhg_update(struct zebra_evpn_es *es)
if ((es->flags & ZEBRA_EVPNES_LOCAL)) if ((es->flags & ZEBRA_EVPNES_LOCAL))
zebra_evpn_es_br_port_dplane_update(es, zebra_evpn_es_br_port_dplane_update(es,
__func__); __func__);
zebra_evpn_nhg_mac_update(es);
} }
} else { } else {
if (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) { if (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) {
@ -1047,11 +1066,11 @@ static void zebra_evpn_nhg_update(struct zebra_evpn_es *es)
if ((es->flags & ZEBRA_EVPNES_LOCAL)) if ((es->flags & ZEBRA_EVPNES_LOCAL))
zebra_evpn_es_br_port_dplane_update(es, zebra_evpn_es_br_port_dplane_update(es,
__func__); __func__);
zebra_evpn_nhg_mac_update(es);
kernel_del_mac_nhg(es->nhg_id); kernel_del_mac_nhg(es->nhg_id);
} }
} }
/* XXX - update remote macs associated with the ES */
} }
static void zebra_evpn_nh_add(struct zebra_evpn_es_vtep *es_vtep) static void zebra_evpn_nh_add(struct zebra_evpn_es_vtep *es_vtep)