[RFC 4/6] mesh: Ensure that channels are correctly configured

Benjamin Berg benjamin at sipsolutions.net
Mon Nov 28 07:38:41 PST 2016


Under some circumstances the configuration could be lost or channel
information was recalculated wrongly without any need to do so. Fix
these cases by trying to use the information from ibss_mesh_setup_freq
and preventing further HT/VHT setup breaking things again.

Signed-off-by: Benjamin Berg <benjamin at sipsolutions.net>
---
 wpa_supplicant/ap.c          |  5 +++++
 wpa_supplicant/config_ssid.h |  1 +
 wpa_supplicant/mesh.c        | 53 +++++++++++++++++++-------------------------
 3 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index e538bf0..59dc55c 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -49,6 +49,11 @@ static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
 			     struct hostapd_config *conf,
 			     struct hostapd_hw_modes *mode)
 {
+#ifdef CONFIG_MESH
+	if (wpa_s->ifmsh)
+		return;
+#endif
+
 #ifdef CONFIG_P2P
 	u8 center_chan = 0;
 	u8 channel = conf->channel;
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 010b594..0f16b8e 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -476,6 +476,7 @@ struct wpa_ssid {
 
 	u8 max_oper_chwidth;
 
+	unsigned int vht_center_freq1;
 	unsigned int vht_center_freq2;
 
 	/**
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 116a2d6..182d3ac 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -250,6 +250,8 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 		conf->country[1] = wpa_s->conf->country[1];
 	}
 
+	/* Copy the channel/bandwidth/mode information into the hostapd
+	 * interface. */
 	/* need conf->hw_mode for supported rates. */
 	conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency, &conf->channel);
 	if (conf->hw_mode == NUM_HOSTAPD_MODES) {
@@ -257,29 +259,12 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 			   ssid->frequency);
 		goto out_free;
 	}
-	if (ssid->ht40)
-		conf->secondary_channel = ssid->ht40;
-	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) {
-		conf->vht_oper_chwidth = ssid->max_oper_chwidth;
-		switch (conf->vht_oper_chwidth) {
-		case VHT_CHANWIDTH_80MHZ:
-		case VHT_CHANWIDTH_80P80MHZ:
-			ieee80211_freq_to_chan(
-				ssid->frequency,
-				&conf->vht_oper_centr_freq_seg0_idx);
-			conf->vht_oper_centr_freq_seg0_idx += ssid->ht40 * 2;
-			break;
-		case VHT_CHANWIDTH_160MHZ:
-			ieee80211_freq_to_chan(
-				ssid->frequency,
-				&conf->vht_oper_centr_freq_seg0_idx);
-			conf->vht_oper_centr_freq_seg0_idx += ssid->ht40 * 2;
-			conf->vht_oper_centr_freq_seg0_idx += 40 / 5;
-			break;
-		}
-		ieee80211_freq_to_chan(ssid->vht_center_freq2,
-				       &conf->vht_oper_centr_freq_seg1_idx);
-	}
+	conf->secondary_channel = ssid->ht40;
+	conf->vht_oper_chwidth = ssid->max_oper_chwidth;
+	ieee80211_freq_to_chan(ssid->vht_center_freq1,
+			       &conf->vht_oper_centr_freq_seg0_idx);
+	ieee80211_freq_to_chan(ssid->vht_center_freq2,
+			       &conf->vht_oper_centr_freq_seg1_idx);
 
 	if (ssid->mesh_basic_rates == NULL) {
 		/*
@@ -311,17 +296,26 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 		conf->basic_rates[rate_len] = -1;
 	}
 
-	if (hostapd_setup_interface(ifmsh)) {
-		wpa_printf(MSG_ERROR,
-			   "Failed to initialize hostapd interface for mesh");
-		return -1;
-	}
+	/* Do not allow primary/secondary channel switch as the user requested
+	 * a specific setup. Allowing this also breaks setup in case DFS is
+	 * required (effectively preventing the DFS check state to be reached).
+	 * This is probably a bug elsewhere.
+	 */
+	conf->no_pri_sec_switch = 1;
+	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
 
+	/* driver needs to be initialized for DFS operations during hostapd setup. */
 	if (wpa_drv_init_mesh(wpa_s)) {
 		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
 		return -1;
 	}
 
+	if (hostapd_setup_interface(ifmsh)) {
+		wpa_printf(MSG_ERROR,
+			   "Failed to initialize hostapd interface for mesh");
+		return -1;
+	}
+
 	if (mconf->security != MESH_CONF_SEC_NONE) {
 		if (ssid->passphrase == NULL) {
 			wpa_printf(MSG_ERROR,
@@ -353,8 +347,6 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 			goto out_free;
 	}
 
-	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
-
 	return 0;
 out_free:
 	wpa_supplicant_mesh_deinit(wpa_s);
@@ -419,6 +411,7 @@ int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
 		ssid->ht40 = params->freq.sec_channel_offset;
 	if (wpa_s->mesh_vht_enabled) {
 		ssid->vht = 1;
+		ssid->vht_center_freq1 = params->freq.center_freq1;
 		switch (params->freq.bandwidth) {
 		case 80:
 			if (params->freq.center_freq2) {
-- 
2.10.2




More information about the Hostap mailing list