Before joining a CAC might be required. This requires changing the interface into mesh mode a bit earlier and being able to handle it correctly if hostapd_setup_interface needs to delay the interface completition until the CAC is finished. Signed-off-by: Benjamin Berg <benjamin@xxxxxxxxxxxxxxxx> --- wpa_supplicant/ap.c | 68 +++++++++++++++---------- wpa_supplicant/mesh.c | 104 ++++++++++++++++++++++---------------- wpa_supplicant/wpa_supplicant_i.h | 2 + 3 files changed, 104 insertions(+), 70 deletions(-) diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 5afb772..e538bf0 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -1443,61 +1443,77 @@ void wpas_ap_pmksa_cache_flush(struct wpa_supplicant *wpa_s) void wpas_event_dfs_radar_detected(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) - return; wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq); - hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq, - radar->ht_enabled, radar->chan_offset, - radar->chan_width, - radar->cf1, radar->cf2); + if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) + hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, + radar->cf1, radar->cf2); + if (wpa_s->ifmsh && wpa_s->ifmsh->bss[0]) + hostapd_dfs_radar_detected(wpa_s->ifmsh, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, + radar->cf1, radar->cf2); } void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) - return; wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq); - hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq, - radar->ht_enabled, radar->chan_offset, - radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) + hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ifmsh && wpa_s->ifmsh->bss[0]) + hostapd_dfs_start_cac(wpa_s->ifmsh, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); } void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) - return; wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq); - hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq, - radar->ht_enabled, radar->chan_offset, - radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) + hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ifmsh && wpa_s->ifmsh->bss[0]) + hostapd_dfs_complete_cac(wpa_s->ifmsh, 1, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); } void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) - return; wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq); - hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq, - radar->ht_enabled, radar->chan_offset, - radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) + hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ifmsh && wpa_s->ifmsh->bss[0]) + hostapd_dfs_complete_cac(wpa_s->ifmsh, 0, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); } void wpas_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s, struct dfs_event *radar) { - if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]) - return; wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq); - hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq, - radar->ht_enabled, radar->chan_offset, - radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ap_iface && wpa_s->ap_iface->bss[0]) + hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); + if (wpa_s->ifmsh && wpa_s->ifmsh->bss[0]) + hostapd_dfs_nop_finished(wpa_s->ifmsh, radar->freq, + radar->ht_enabled, radar->chan_offset, + radar->chan_width, radar->cf1, radar->cf2); } #endif /* NEED_AP_MLME */ diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c index 70069bf..116a2d6 100644 --- a/wpa_supplicant/mesh.c +++ b/wpa_supplicant/mesh.c @@ -144,6 +144,35 @@ static void wpas_mesh_copy_groups(struct hostapd_data *bss, groups_size); } +static void wpas_mesh_configured_cb(void *ctx) +{ + struct wpa_supplicant *wpa_s = ctx; + struct wpa_driver_mesh_join_params *params = &wpa_s->mesh_join_params; + int ret; + + 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(params->meshid, params->meshid_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; +} + static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) @@ -203,6 +232,10 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s, ifmsh->bss[0]->max_plinks = wpa_s->conf->max_peer_links; ifmsh->bss[0]->dot11RSNASAERetransPeriod = wpa_s->conf->dot11RSNASAERetransPeriod; + + ifmsh->bss[0]->setup_complete_cb = wpas_mesh_configured_cb; + ifmsh->bss[0]->setup_complete_cb_ctx = wpa_s; + os_strlcpy(bss->conf->iface, wpa_s->ifname, sizeof(bss->conf->iface)); mconf = mesh_config_create(wpa_s, ssid); @@ -362,7 +395,7 @@ 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 = &wpa_s->mesh_join_params; int ret = 0; if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) { @@ -376,22 +409,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; + os_memset(params, 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; 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; } @@ -405,30 +438,33 @@ 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->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; + + /* hostapd_setup_interface calls wpas_mesh_configured_cb when we are + * ready to join the mesh network. */ if (wpa_supplicant_mesh_init(wpa_s, ssid)) { wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh"); wpa_drv_leave_mesh(wpa_s); @@ -442,26 +478,6 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s, 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); - out: return ret; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index d6ff6de..efedc5c 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -770,6 +770,8 @@ 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_join_params; #endif /* CONFIG_MESH */ unsigned int off_channel_freq; -- 2.10.2 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap