[RFC 2/6] mesh: Allow CAC to be done during mesh initialization before joining
Benjamin Berg
benjamin at sipsolutions.net
Mon Nov 28 07:38:39 PST 2016
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 at sipsolutions.net>
---
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
More information about the Hostap
mailing list