]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_evpn_mh.c
Merge pull request #11843 from ARShreenidhi/ecmp_testcase
[mirror_frr.git] / zebra / zebra_evpn_mh.c
index 50eecd31d5404574af9352f8f6fb1232868d37c4..043ea0f248e63f8f1a1266801918e55d8384c789 100644 (file)
@@ -113,10 +113,7 @@ static struct zebra_evpn_es_evi *zebra_evpn_es_evi_new(struct zebra_evpn_es *es,
        es_evi->zevpn = zevpn;
 
        /* insert into the EVPN-ESI rb tree */
-       if (RB_INSERT(zebra_es_evi_rb_head, &zevpn->es_evi_rb_tree, es_evi)) {
-               XFREE(MTYPE_ZES_EVI, es_evi);
-               return NULL;
-       }
+       RB_INSERT(zebra_es_evi_rb_head, &zevpn->es_evi_rb_tree, es_evi);
 
        /* add to the ES's VNI list */
        listnode_init(&es_evi->es_listnode, es_evi);
@@ -573,10 +570,7 @@ zebra_evpn_acc_vl_new(vlanid_t vid, struct interface *br_if)
        acc_bd->mbr_zifs = list_new();
 
        /* Add to hash */
-       if (!hash_get(zmh_info->evpn_vlan_table, acc_bd, hash_alloc_intern)) {
-               XFREE(MTYPE_ZACC_BD, acc_bd);
-               return NULL;
-       }
+       (void)hash_get(zmh_info->evpn_vlan_table, acc_bd, hash_alloc_intern);
 
        /* check if an svi exists for the vlan */
        if (br_if) {
@@ -1094,10 +1088,7 @@ static uint32_t zebra_evpn_nhid_alloc(struct zebra_evpn_es *es)
                nh_id = id | EVPN_NHG_ID_TYPE_BIT;
                /* Add to NHG hash */
                es->nhg_id = nh_id;
-               if (!hash_get(zmh_info->nhg_table, es, hash_alloc_intern)) {
-                       bf_release_index(zmh_info->nh_id_bitmap, id);
-                       return 0;
-               }
+               (void)hash_get(zmh_info->nhg_table, es, hash_alloc_intern);
        } else {
                nh_id = id | EVPN_NH_ID_TYPE_BIT;
        }
@@ -1364,10 +1355,7 @@ static struct zebra_evpn_l2_nh *zebra_evpn_l2_nh_alloc(struct in_addr vtep_ip)
 
        nh = XCALLOC(MTYPE_L2_NH, sizeof(*nh));
        nh->vtep_ip = vtep_ip;
-       if (!hash_get(zmh_info->nh_ip_table, nh, hash_alloc_intern)) {
-               XFREE(MTYPE_L2_NH, nh);
-               return NULL;
-       }
+       (void)hash_get(zmh_info->nh_ip_table, nh, hash_alloc_intern);
 
        nh->nh_id = zebra_evpn_nhid_alloc(NULL);
        if (!nh->nh_id) {
@@ -1776,10 +1764,7 @@ static struct zebra_evpn_es *zebra_evpn_es_new(const esi_t *esi)
        esi_to_str(&es->esi, es->esi_str, sizeof(es->esi_str));
 
        /* Add to rb_tree */
-       if (RB_INSERT(zebra_es_rb_head, &zmh_info->es_rb_tree, es)) {
-               XFREE(MTYPE_ZES, es);
-               return NULL;
-       }
+       RB_INSERT(zebra_es_rb_head, &zmh_info->es_rb_tree, es);
 
        /* Initialise the ES-EVI list */
        es->es_evi_list = list_new();
@@ -2081,11 +2066,6 @@ static void zebra_evpn_mh_dup_addr_detect_off(void)
                return;
 
        zvrf = zebra_vrf_get_evpn();
-       if (!zvrf) {
-               zmh_info->flags |= ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF;
-               return;
-       }
-
        old_detect = zebra_evpn_do_dup_addr_detect(zvrf);
        zmh_info->flags |= ZEBRA_EVPN_MH_DUP_ADDR_DETECT_OFF;
        new_detect = zebra_evpn_do_dup_addr_detect(zvrf);
@@ -2332,7 +2312,6 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, esi_t *esi)
        struct zebra_evpn_es *old_es = zif->es_info.es;
        struct zebra_evpn_es *es;
 
-       memcpy(&zif->es_info.esi, esi, sizeof(*esi));
        if (old_es && !memcmp(&old_es->esi, esi, sizeof(*esi)))
                /* dup - nothing to be done */
                return 0;
@@ -2344,15 +2323,14 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, esi_t *esi)
        es = zebra_evpn_es_find(esi);
        if (es) {
                /* if it exists against another interface flag an error */
-               if (es->zif && es->zif != zif) {
-                       memset(&zif->es_info.esi, 0, sizeof(*esi));
+               if (es->zif && es->zif != zif)
                        return -1;
-               }
        } else {
                /* create new es */
                es = zebra_evpn_es_new(esi);
        }
 
+       memcpy(&zif->es_info.esi, esi, sizeof(*esi));
        if (es)
                zebra_evpn_es_local_info_set(es, zif);
 
@@ -3292,7 +3270,7 @@ DEFPY_HIDDEN(zebra_evpn_es_bypass, zebra_evpn_es_bypass_cmd,
        } else {
                if (!zebra_evpn_is_if_es_capable(zif)) {
                        vty_out(vty,
-                               "%%DF bypass cannot be associated with this interface type\n");
+                               "%% DF bypass cannot be associated with this interface type\n");
                        return CMD_WARNING;
                }
                zebra_evpn_es_bypass_cfg_update(zif, true);
@@ -3317,7 +3295,7 @@ DEFPY(zebra_evpn_es_pref, zebra_evpn_es_pref_cmd,
        } else {
                if (!zebra_evpn_is_if_es_capable(zif)) {
                        vty_out(vty,
-                               "%%DF preference cannot be associated with this interface type\n");
+                               "%% DF preference cannot be associated with this interface type\n");
                        return CMD_WARNING;
                }
                zebra_evpn_es_df_pref_update(zif, df_pref);
@@ -3347,25 +3325,26 @@ DEFPY(zebra_evpn_es_sys_mac,
 
                ret = zebra_evpn_es_sys_mac_update(zif, &zero_mac);
                if (ret == -1) {
-                       vty_out(vty, "%%Failed to clear ES sysmac\n");
+                       vty_out(vty, "%% Failed to clear ES sysmac\n");
                        return CMD_WARNING;
                }
        } else {
 
                if (!zebra_evpn_is_if_es_capable(zif)) {
                        vty_out(vty,
-                               "%%ESI cannot be associated with this interface type\n");
+                               "%% ESI cannot be associated with this interface type\n");
                        return CMD_WARNING;
                }
 
                if  (!mac || is_zero_mac(&mac->eth_addr)) {
-                       vty_out(vty, "%%ES sysmac value is invalid\n");
+                       vty_out(vty, "%% ES sysmac value is invalid\n");
                        return CMD_WARNING;
                }
 
                ret = zebra_evpn_es_sys_mac_update(zif, &mac->eth_addr);
                if (ret == -1) {
-                       vty_out(vty, "%%ESI already exists on a different interface\n");
+                       vty_out(vty,
+                               "%% ESI already exists on a different interface\n");
                        return CMD_WARNING;
                }
        }
@@ -3398,25 +3377,27 @@ DEFPY(zebra_evpn_es_id,
                        ret = zebra_evpn_es_type0_esi_update(zif, zero_esi);
 
                if (ret == -1) {
-                       vty_out(vty, "%%Failed to clear ES local id\n");
+                       vty_out(vty,
+                               "%% Failed to clear ES local id or ESI name\n");
                        return CMD_WARNING;
                }
        } else {
                if (!zebra_evpn_is_if_es_capable(zif)) {
                        vty_out(vty,
-                               "%%ESI cannot be associated with this interface type\n");
+                               "%% ESI cannot be associated with this interface type\n");
                        return CMD_WARNING;
                }
 
                if (esi_str) {
                        if (!str_to_esi(esi_str, &esi)) {
-                               vty_out(vty, "%% Malformed ESI\n");
+                               vty_out(vty, "%% Malformed ESI name\n");
                                return CMD_WARNING;
                        }
                        ret = zebra_evpn_es_type0_esi_update(zif, &esi);
                } else {
                        if (!es_lid) {
-                               vty_out(vty, "%%Specify local ES ID\n");
+                               vty_out(vty,
+                                       "%% Specify ES local id or ESI name\n");
                                return CMD_WARNING;
                        }
                        ret = zebra_evpn_es_lid_update(zif, es_lid);
@@ -3424,7 +3405,7 @@ DEFPY(zebra_evpn_es_id,
 
                if (ret == -1) {
                        vty_out(vty,
-                                       "%%ESI already exists on a different interface\n");
+                               "%% ESI already exists on a different interface\n");
                        return CMD_WARNING;
                }
        }
@@ -3463,11 +3444,13 @@ void zebra_evpn_mh_json(json_object *json)
 
        if (zmh_info->protodown_rc) {
                json_array = json_object_new_array();
-               if (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY)
+               if (CHECK_FLAG(zmh_info->protodown_rc,
+                              ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY))
                        json_object_array_add(
                                json_array,
                                json_object_new_string("startupDelay"));
-               if (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN)
+               if (CHECK_FLAG(zmh_info->protodown_rc,
+                              ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN))
                        json_object_array_add(
                                json_array,
                                json_object_new_string("uplinkDown"));
@@ -3623,10 +3606,10 @@ bool zebra_evpn_is_es_bond_member(struct interface *ifp)
 void zebra_evpn_mh_update_protodown_bond_mbr(struct zebra_if *zif, bool clear,
                                             const char *caller)
 {
-       bool old_protodown;
        bool new_protodown;
-       enum protodown_reasons old_protodown_rc = 0;
-       enum protodown_reasons protodown_rc = 0;
+       uint32_t old_protodown_rc = 0;
+       uint32_t new_protodown_rc = 0;
+       uint32_t protodown_rc = 0;
 
        if (!clear) {
                struct zebra_if *bond_zif;
@@ -3635,32 +3618,23 @@ void zebra_evpn_mh_update_protodown_bond_mbr(struct zebra_if *zif, bool clear,
                protodown_rc = bond_zif->protodown_rc;
        }
 
-       old_protodown = !!(zif->flags & ZIF_FLAG_PROTODOWN);
        old_protodown_rc = zif->protodown_rc;
-       zif->protodown_rc &= ~ZEBRA_PROTODOWN_EVPN_ALL;
-       zif->protodown_rc |= (protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL);
-       new_protodown = !!zif->protodown_rc;
+       new_protodown_rc = (old_protodown_rc & ~ZEBRA_PROTODOWN_EVPN_ALL);
+       new_protodown_rc |= (protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL);
+       new_protodown = !!new_protodown_rc;
 
-       if (IS_ZEBRA_DEBUG_EVPN_MH_ES
-           && (zif->protodown_rc != old_protodown_rc))
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES && (new_protodown_rc != old_protodown_rc))
                zlog_debug(
                        "%s bond mbr %s protodown_rc changed; old 0x%x new 0x%x",
                        caller, zif->ifp->name, old_protodown_rc,
-                       zif->protodown_rc);
-
-       if (old_protodown == new_protodown)
-               return;
-
-       if (new_protodown)
-               zif->flags |= ZIF_FLAG_PROTODOWN;
-       else
-               zif->flags &= ~ZIF_FLAG_PROTODOWN;
+                       new_protodown_rc);
 
-       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-               zlog_debug("%s protodown %s", zif->ifp->name,
-                          new_protodown ? "on" : "off");
-
-       zebra_if_set_protodown(zif->ifp, new_protodown);
+       if (zebra_if_update_protodown_rc(zif->ifp, new_protodown,
+                                        new_protodown_rc) == 0) {
+               if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+                       zlog_debug("%s protodown %s", zif->ifp->name,
+                                  new_protodown ? "on" : "off");
+       }
 }
 
 /* The bond members inherit the protodown reason code from the bond */
@@ -3683,7 +3657,7 @@ static void zebra_evpn_mh_update_protodown_es(struct zebra_evpn_es *es,
                                              bool resync_dplane)
 {
        struct zebra_if *zif;
-       enum protodown_reasons old_protodown_rc;
+       uint32_t old_protodown_rc;
 
        zif = es->zif;
        /* if the reason code is the same bail unless it is a new
@@ -3714,7 +3688,7 @@ static void zebra_evpn_mh_update_protodown_es(struct zebra_evpn_es *es,
 static void zebra_evpn_mh_clear_protodown_es(struct zebra_evpn_es *es)
 {
        struct zebra_if *zif;
-       enum protodown_reasons old_protodown_rc;
+       uint32_t old_protodown_rc;
 
        zif = es->zif;
        if (!(zif->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL))
@@ -3742,10 +3716,9 @@ static void zebra_evpn_mh_update_protodown_es_all(void)
                zebra_evpn_mh_update_protodown_es(es, false /*resync_dplane*/);
 }
 
-static void zebra_evpn_mh_update_protodown(enum protodown_reasons protodown_rc,
-                                          bool set)
+static void zebra_evpn_mh_update_protodown(uint32_t protodown_rc, bool set)
 {
-       enum protodown_reasons old_protodown_rc = zmh_info->protodown_rc;
+       uint32_t old_protodown_rc = zmh_info->protodown_rc;
 
        if (set) {
                if ((protodown_rc & zmh_info->protodown_rc) == protodown_rc)
@@ -3772,18 +3745,10 @@ static inline bool zebra_evpn_mh_is_all_uplinks_down(void)
 static void zebra_evpn_mh_uplink_oper_flags_update(struct zebra_if *zif,
                                                   bool set)
 {
-       if (set) {
-               if (if_is_operative(zif->ifp)) {
-                       if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP)) {
-                               zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP;
-                               ++zmh_info->uplink_oper_up_cnt;
-                       }
-               } else {
-                       if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) {
-                               zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP;
-                               if (zmh_info->uplink_oper_up_cnt)
-                                       --zmh_info->uplink_oper_up_cnt;
-                       }
+       if (set && if_is_operative(zif->ifp)) {
+               if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP)) {
+                       zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP;
+                       ++zmh_info->uplink_oper_up_cnt;
                }
        } else {
                if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) {