summaryrefslogtreecommitdiff
path: root/zebra/zebra_evpn_mh.c
diff options
context:
space:
mode:
Diffstat (limited to 'zebra/zebra_evpn_mh.c')
-rw-r--r--zebra/zebra_evpn_mh.c58
1 files changed, 34 insertions, 24 deletions
diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c
index 2567171c5e..f71065cdcf 100644
--- a/zebra/zebra_evpn_mh.c
+++ b/zebra/zebra_evpn_mh.c
@@ -60,7 +60,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, ZES_VTEP, "VTEP attached to the ES");
static void zebra_evpn_es_get_one_base_evpn(void);
static int zebra_evpn_es_evi_send_to_client(struct zebra_evpn_es *es,
zebra_evpn_t *zevpn, bool add);
-static void zebra_evpn_local_es_del(struct zebra_evpn_es *es);
+static void zebra_evpn_local_es_del(struct zebra_evpn_es **esp);
static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid,
struct ethaddr *sysmac);
@@ -820,7 +820,7 @@ void zebra_evpn_if_cleanup(struct zebra_if *zif)
/* Delete associated Ethernet Segment */
if (zif->es_info.es)
- zebra_evpn_local_es_del(zif->es_info.es);
+ zebra_evpn_local_es_del(&zif->es_info.es);
}
/*****************************************************************************
@@ -1107,15 +1107,17 @@ static struct zebra_evpn_es *zebra_evpn_es_new(esi_t *esi)
* This just frees appropriate memory, caller should have taken other
* needed actions.
*/
-static struct zebra_evpn_es *zebra_evpn_es_free(struct zebra_evpn_es *es)
+static void zebra_evpn_es_free(struct zebra_evpn_es **esp)
{
+ struct zebra_evpn_es *es = *esp;
+
/* If the ES has a local or remote reference it cannot be freed.
* Free is also prevented if there are MAC entries referencing
* it.
*/
if ((es->flags & (ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_REMOTE)) ||
listcount(es->mac_list))
- return es;
+ return;
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
zlog_debug("es %s free", es->esi_str);
@@ -1137,7 +1139,7 @@ static struct zebra_evpn_es *zebra_evpn_es_free(struct zebra_evpn_es *es)
XFREE(MTYPE_ZES, es);
- return NULL;
+ *esp = NULL;
}
/* Inform BGP about local ES addition */
@@ -1201,7 +1203,6 @@ static int zebra_evpn_es_send_del_to_client(struct zebra_evpn_es *es)
return zserv_send_message(client, s);
}
-/* XXX - call any time ZEBRA_EVPNES_LOCAL gets set or cleared */
static void zebra_evpn_es_re_eval_send_to_client(struct zebra_evpn_es *es,
bool es_evi_re_reval)
{
@@ -1349,9 +1350,10 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es,
false /* force_clear_static */);
}
-static void zebra_evpn_es_local_info_clear(struct zebra_evpn_es *es)
+static void zebra_evpn_es_local_info_clear(struct zebra_evpn_es **esp)
{
struct zebra_if *zif;
+ struct zebra_evpn_es *es = *esp;
if (!(es->flags & ZEBRA_EVPNES_LOCAL))
return;
@@ -1373,16 +1375,17 @@ static void zebra_evpn_es_local_info_clear(struct zebra_evpn_es *es)
list_delete_node(zmh_info->local_es_list, &es->local_es_listnode);
/* free up the ES if there is no remote reference */
- zebra_evpn_es_free(es);
+ zebra_evpn_es_free(esp);
}
/* Delete an ethernet segment and inform BGP */
-static void zebra_evpn_local_es_del(struct zebra_evpn_es *es)
+static void zebra_evpn_local_es_del(struct zebra_evpn_es **esp)
{
struct zebra_evpn_es_evi *es_evi;
struct listnode *node = NULL;
struct listnode *nnode = NULL;
struct zebra_if *zif;
+ struct zebra_evpn_es *es = *esp;
if (!CHECK_FLAG(es->flags, ZEBRA_EVPNES_LOCAL))
return;
@@ -1402,12 +1405,14 @@ static void zebra_evpn_local_es_del(struct zebra_evpn_es *es)
if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)
zebra_evpn_es_send_del_to_client(es);
- zebra_evpn_es_local_info_clear(es);
+ zebra_evpn_es_local_info_clear(esp);
}
/* eval remote info associated with the ES */
-static void zebra_evpn_es_remote_info_re_eval(struct zebra_evpn_es *es)
+static void zebra_evpn_es_remote_info_re_eval(struct zebra_evpn_es **esp)
{
+ struct zebra_evpn_es *es = *esp;
+
/* if there are remote VTEPs the ES-EVI is classified as "remote" */
if (listcount(es->es_vtep_list)) {
if (!(es->flags & ZEBRA_EVPNES_REMOTE)) {
@@ -1422,7 +1427,7 @@ static void zebra_evpn_es_remote_info_re_eval(struct zebra_evpn_es *es)
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
zlog_debug("remote es %s del; nhg 0x%x",
es->esi_str, es->nhg_id);
- zebra_evpn_es_free(es);
+ zebra_evpn_es_free(esp);
}
}
}
@@ -1443,7 +1448,7 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid,
if (!lid || is_zero_mac(sysmac)) {
/* if in ES is attached to zif delete it */
if (old_es)
- zebra_evpn_local_es_del(old_es);
+ zebra_evpn_local_es_del(&zif->es_info.es);
return 0;
}
@@ -1468,7 +1473,7 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid,
/* release the old_es against the zif */
if (old_es)
- zebra_evpn_local_es_del(old_es);
+ zebra_evpn_local_es_del(&zif->es_info.es);
es = zebra_evpn_es_find(&esi);
if (es) {
@@ -1497,22 +1502,24 @@ static int zebra_evpn_remote_es_del(esi_t *esi, struct in_addr vtep_ip)
es = zebra_evpn_es_find(esi);
if (!es) {
- /* XXX - error log */
+ zlog_warn("remote es %s vtep %pI4 del failed, es missing",
+ esi_to_str(esi, buf, sizeof(buf)), &vtep_ip);
return -1;
}
zebra_evpn_es_vtep_del(es, vtep_ip);
- zebra_evpn_es_remote_info_re_eval(es);
+ zebra_evpn_es_remote_info_re_eval(&es);
return 0;
}
/* force delete a remote ES on the way down */
-static void zebra_evpn_remote_es_flush(struct zebra_evpn_es *es)
+static void zebra_evpn_remote_es_flush(struct zebra_evpn_es **esp)
{
struct zebra_evpn_es_vtep *es_vtep;
struct listnode *node;
struct listnode *nnode;
+ struct zebra_evpn_es *es = *esp;
for (ALL_LIST_ELEMENTS(es->es_vtep_list, node, nnode, es_vtep)) {
if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
@@ -1520,8 +1527,8 @@ static void zebra_evpn_remote_es_flush(struct zebra_evpn_es *es)
es->esi_str,
inet_ntoa(es_vtep->vtep_ip));
zebra_evpn_es_vtep_free(es_vtep);
- zebra_evpn_es_remote_info_re_eval(es);
}
+ zebra_evpn_es_remote_info_re_eval(esp);
}
static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip)
@@ -1538,13 +1545,15 @@ static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip)
if (!es) {
es = zebra_evpn_es_new(esi);
if (!es) {
- /* XXX - error log */
+ zlog_warn(
+ "remote es %s vtep %pI4 add failed, es missing",
+ esi_to_str(esi, buf, sizeof(buf)), &vtep_ip);
return -1;
}
}
zebra_evpn_es_vtep_add(es, vtep_ip);
- zebra_evpn_es_remote_info_re_eval(es);
+ zebra_evpn_es_remote_info_re_eval(&es);
return 0;
}
@@ -1584,7 +1593,7 @@ void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac)
list_delete_node(es->mac_list, &mac->es_listnode);
if (!listcount(es->mac_list))
- zebra_evpn_es_free(es);
+ zebra_evpn_es_free(&es);
}
/* Associate a MAC entry with a local or remote ES. Returns false if there
@@ -1691,8 +1700,9 @@ void zebra_evpn_es_cleanup(void)
RB_FOREACH_SAFE(es, zebra_es_rb_head,
&zmh_info->es_rb_tree, es_next) {
- zebra_evpn_local_es_del(es);
- zebra_evpn_remote_es_flush(es);
+ zebra_evpn_local_es_del(&es);
+ if (es)
+ zebra_evpn_remote_es_flush(&es);
}
}
@@ -2099,7 +2109,7 @@ int zebra_evpn_mh_neigh_holdtime_update(struct vty *vty,
uint32_t duration, bool set_default)
{
if (set_default)
- zmh_info->neigh_hold_time = EVPN_MH_NEIGH_HOLD_TIME_DEF;
+ duration = EVPN_MH_NEIGH_HOLD_TIME_DEF;
zmh_info->neigh_hold_time = duration;