From 0daa7b75facd6fd36564911b2b0dc79cf48bd84d Mon Sep 17 00:00:00 2001 From: Peter Oh Date: Mon, 27 Aug 2018 14:28:34 -0700 Subject: [PATCH] mesh: Factor out mesh join function Mesh join function consists of two parts which are preparing configurations and sending join event to the driver. Since physical mesh join event could happen either right after mesh configuration is done or after CAC is done in case of DFS channel is used, factor out the function into two parts to reduce redundant calls. Signed-off-by: Peter Oh --- wpa_supplicant/mesh.c | 132 ++++++++++++++++++------------ wpa_supplicant/wpa_supplicant_i.h | 1 + 2 files changed, 79 insertions(+), 54 deletions(-) diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index cb995a56f..b559aafb4 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -34,6 +34,8 @@ static void wpa_supplicant_mesh_deinit(struct wpa_supplicant *wpa_s) wpa_s->current_ssid = NULL; os_free(wpa_s->mesh_rsn); wpa_s->mesh_rsn = NULL; + os_free(wpa_s->mesh_params); + wpa_s->mesh_params = NULL; /* TODO: leave mesh (stop beacon). This will happen on link down * anyway, so it's not urgent */ } @@ -188,6 +190,49 @@ static int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s) } +static int wpas_mesh_complete(struct wpa_supplicant *wpa_s) +{ + struct hostapd_iface *ifmsh = wpa_s->ifmsh; + struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params; + struct wpa_ssid *ssid = wpa_s->current_ssid; + int ret; + + if (!params || !ssid) { + wpa_printf(MSG_ERROR, "mesh: %s called without active mesh", + __func__); + return -1; + } + + if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { + wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher; + wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher; + wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher; + } + + if (ifmsh) { + params->ies = ifmsh->mconf->rsn_ie; + params->ie_len = ifmsh->mconf->rsn_ie_len; + params->basic_rates = ifmsh->basic_rates; + params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE; + params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode; + } + + wpa_msg(wpa_s, MSG_INFO, "joining mesh %s", + wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); + ret = wpa_drv_join_mesh(wpa_s, params); + if (ret) + wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret); + + /* hostapd sets the interface down until we associate */ + wpa_drv_set_operstate(wpa_s, 1); + + if (!ret) + wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); + + return ret; +} + + static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, struct hostapd_freq_params *freq) @@ -375,11 +420,13 @@ void wpa_supplicant_mesh_add_scan_ie(struct wpa_supplicant *wpa_s, int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) { - struct wpa_driver_mesh_join_params params; + struct wpa_driver_mesh_join_params *params = os_zalloc(sizeof(*params)); int ret = 0; - if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) { + if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency || + !params) { ret = -ENOENT; + os_free(params); goto out; } @@ -389,22 +436,22 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, wpa_s->group_cipher = WPA_CIPHER_NONE; wpa_s->mgmt_group_cipher = 0; - os_memset(¶ms, 0, sizeof(params)); - params.meshid = ssid->ssid; - params.meshid_len = ssid->ssid_len; - ibss_mesh_setup_freq(wpa_s, ssid, ¶ms.freq); - wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled; - wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled; - if (params.freq.ht_enabled && params.freq.sec_channel_offset) - ssid->ht40 = params.freq.sec_channel_offset; + params->meshid = ssid->ssid; + params->meshid_len = ssid->ssid_len; + ibss_mesh_setup_freq(wpa_s, ssid, ¶ms->freq); + wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled; + wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled; + if (params->freq.ht_enabled && params->freq.sec_channel_offset) + ssid->ht40 = params->freq.sec_channel_offset; + if (wpa_s->mesh_vht_enabled) { ssid->vht = 1; - switch (params.freq.bandwidth) { + switch (params->freq.bandwidth) { case 80: - if (params.freq.center_freq2) { + if (params->freq.center_freq2) { ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ; ssid->vht_center_freq2 = - params.freq.center_freq2; + params->freq.center_freq2; } else { ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ; } @@ -418,67 +465,44 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, } } if (ssid->beacon_int > 0) - params.beacon_int = ssid->beacon_int; + params->beacon_int = ssid->beacon_int; else if (wpa_s->conf->beacon_int > 0) - params.beacon_int = wpa_s->conf->beacon_int; + params->beacon_int = wpa_s->conf->beacon_int; if (ssid->dtim_period > 0) - params.dtim_period = ssid->dtim_period; + params->dtim_period = ssid->dtim_period; else if (wpa_s->conf->dtim_period > 0) - params.dtim_period = wpa_s->conf->dtim_period; - params.conf.max_peer_links = wpa_s->conf->max_peer_links; + params->dtim_period = wpa_s->conf->dtim_period; + params->conf.max_peer_links = wpa_s->conf->max_peer_links; if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) { - params.conf.rssi_threshold = ssid->mesh_rssi_threshold; - params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD; + params->conf.rssi_threshold = ssid->mesh_rssi_threshold; + params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD; } if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { - params.flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH; - params.flags |= WPA_DRIVER_MESH_FLAG_AMPE; + params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH; + params->flags |= WPA_DRIVER_MESH_FLAG_AMPE; wpa_s->conf->user_mpm = 1; } if (wpa_s->conf->user_mpm) { - params.flags |= WPA_DRIVER_MESH_FLAG_USER_MPM; - params.conf.auto_plinks = 0; + params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM; + params->conf.auto_plinks = 0; } else { - params.flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM; - params.conf.auto_plinks = 1; + params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM; + params->conf.auto_plinks = 1; } - params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity; + params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity; - if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms.freq)) { + os_free(wpa_s->mesh_params); + wpa_s->mesh_params = params; + if (wpa_supplicant_mesh_init(wpa_s, ssid, ¶ms->freq)) { wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh"); wpa_drv_leave_mesh(wpa_s); ret = -1; goto out; } - if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) { - wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher; - wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher; - wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher; - } - - if (wpa_s->ifmsh) { - params.ies = wpa_s->ifmsh->mconf->rsn_ie; - params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len; - params.basic_rates = wpa_s->ifmsh->basic_rates; - params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE; - params.conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode; - } - - wpa_msg(wpa_s, MSG_INFO, "joining mesh %s", - wpa_ssid_txt(ssid->ssid, ssid->ssid_len)); - ret = wpa_drv_join_mesh(wpa_s, ¶ms); - if (ret) - wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret); - - /* hostapd sets the interface down until we associate */ - wpa_drv_set_operstate(wpa_s, 1); - - if (!ret) - wpa_supplicant_set_state(wpa_s, WPA_COMPLETED); - + ret = wpas_mesh_complete(wpa_s); out: return ret; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 46c4715df..d5ce1fb17 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -820,6 +820,7 @@ struct wpa_supplicant { unsigned int mesh_if_created:1; unsigned int mesh_ht_enabled:1; unsigned int mesh_vht_enabled:1; + struct wpa_driver_mesh_join_params *mesh_params; #ifdef CONFIG_PMKSA_CACHE_EXTERNAL /* struct external_pmksa_cache::list */ struct dl_list mesh_external_pmksa_cache;