[PATCH] mesh: Make BSSBasicRateSet configurable

Masashi Honma masashi.honma
Tue Aug 26 00:31:09 PDT 2014


The mesh STAs have different BSSBasicRateSet could not connect to each other
because of the specification.
[1] 9.6.0c1 Basic Rate Set and Basic MCS Set for mesh STA
"A mesh STA shall not establish a mesh peering with a mesh STA using a
different BSSBasicRateSet."

So I made BSSBasicRateSet configurable.
You can configure BSSBasicRateSet by config file like this
        mesh_basic_rates=10 20 55
or wpa_cli command like this.
        set_network 0 mesh_basic_rates 10 20 55

[1] IEEE Std 802.11s-2011

Signed-off-by: Masashi Honma <masashi.honma at gmail.com>
---
 wpa_supplicant/config.c      |   34 ++++++++++++++++++++++++++++++++++
 wpa_supplicant/config_file.c |    4 +++-
 wpa_supplicant/config_ssid.h |    6 ++++++
 wpa_supplicant/mesh.c        |   36 ++++++++++++++++++++++++++----------
 4 files changed, 69 insertions(+), 11 deletions(-)

diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index efc0a96..7e8e567 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -1579,6 +1579,29 @@ static int wpa_config_parse_mesh_ht_mode(const struct parse_data *data,
 	return 0;
 }
 
+
+static int wpa_config_parse_mesh_basic_rates(const struct parse_data *data,
+					 struct wpa_ssid *ssid, int line,
+					 const char *value)
+{
+	int *rates = wpa_config_parse_int_array(value);
+
+	if (rates == NULL) {
+		wpa_printf(MSG_ERROR, "Line %d: Invalid mesh_basic_rates '%s'",
+			   line, value);
+		return -1;
+	}
+	if (rates[0] == 0) {
+		os_free(rates);
+		rates = NULL;
+	}
+
+	os_free(ssid->mesh_basic_rates);
+	ssid->mesh_basic_rates = rates;
+
+	return 0;
+}
+
 #ifndef NO_CONFIG_WRITE
 static char *wpa_config_write_mesh_ht_mode(const struct parse_data *data,
 					   struct wpa_ssid *ssid)
@@ -1603,6 +1626,13 @@ static char *wpa_config_write_mesh_ht_mode(const struct parse_data *data,
 	}
 	return val ? os_strdup(val) : NULL;
 }
+
+
+static char * wpa_config_write_mesh_basic_rates(const struct parse_data *data,
+						struct wpa_ssid *ssid)
+{
+	return wpa_config_write_freqs(data, ssid->mesh_basic_rates);
+}
 #endif /* NO_CONFIG_WRITE */
 
 #endif /* CONFIG_MESH */
@@ -1777,6 +1807,7 @@ static const struct parse_data ssid_fields[] = {
 	{ INT_RANGE(frequency, 0, 65000) },
 #ifdef CONFIG_MESH
 	{ FUNC(mesh_ht_mode) },
+	{ FUNC(mesh_basic_rates) },
 #endif
 	{ INT(wpa_ptk_rekey) },
 	{ STR(bgscan) },
@@ -2005,6 +2036,9 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
 #ifdef CONFIG_HT_OVERRIDES
 	os_free(ssid->ht_mcs);
 #endif /* CONFIG_HT_OVERRIDES */
+#ifdef CONFIG_MESH
+	os_free(ssid->mesh_basic_rates);
+#endif /* CONFIG_MESH */
 	while ((psk = dl_list_first(&ssid->psk_list, struct psk_list_entry,
 				    list))) {
 		dl_list_del(&psk->list);
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 4376412..8e2b381 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -742,8 +742,10 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
 #ifdef CONFIG_HS20
 	INT(update_identifier);
 #endif /* CONFIG_HS20 */
-
+#ifdef CONFIG_MESH
 	STR(mesh_ht_mode);
+	STR(mesh_basic_rates);
+#endif /* CONFIG_MESH */
 
 #undef STR
 #undef INT
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
index 6234f71..aef9128 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -413,6 +413,12 @@ struct wpa_ssid {
 	 */
 	int mesh_ht_mode;
 
+	/**
+	 * mesh_basic_rates - BSS Basic rate set for mesh network
+	 *
+	 */
+	int *mesh_basic_rates;
+
 	int ht40;
 
 	int vht;
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 25b0eb6..0592d51 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -94,6 +94,7 @@ wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 	int basic_rates_erp[] = {10, 20, 55, 60, 110, 120, 240, -1 };
 	static int default_groups[] = { 19, 20, 21, 25, 26 };
 	size_t len;
+	int rate_len;
 
 	if (!wpa_s->conf->user_mpm) {
 		/* not much for us to do here */
@@ -164,18 +165,33 @@ wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 		goto out_free;
 	}
 
-	/* XXX: hack! this is so an MPM which correctly sets the ERP
-	 * mandatory rates as BSSBasicRateSet doesn't reject us. We
-	 * could add a new hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but
-	 * this is way easier. This also makes our BSSBasicRateSet
-	 * advertised in beacons match the one in peering frames, sigh.
-	 * */
-	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
-		conf->basic_rates = os_zalloc(sizeof(basic_rates_erp));
-		if (!conf->basic_rates)
+	if (ssid->mesh_basic_rates == NULL) {
+		/* XXX: hack! this is so an MPM which correctly sets the ERP
+		 * mandatory rates as BSSBasicRateSet doesn't reject us. We
+		 * could add a new hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but
+		 * this is way easier. This also makes our BSSBasicRateSet
+		 * advertised in beacons match the one in peering frames, sigh.
+		 * */
+		if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
+			conf->basic_rates = os_zalloc(sizeof(basic_rates_erp));
+			if (!conf->basic_rates)
+				goto out_free;
+			os_memcpy(conf->basic_rates,
+				  basic_rates_erp, sizeof(basic_rates_erp));
+		}
+	} else {
+		rate_len = 0;
+		while (1) {
+			if (ssid->mesh_basic_rates[rate_len] < 1)
+				break;
+			rate_len++;
+		}
+		conf->basic_rates = os_zalloc((rate_len + 1) * sizeof(int));
+		if (conf->basic_rates == NULL)
 			goto out_free;
 		os_memcpy(conf->basic_rates,
-			  basic_rates_erp, sizeof(basic_rates_erp));
+			  ssid->mesh_basic_rates, (rate_len + 1) * sizeof(int));
+		conf->basic_rates[rate_len] = -1;
 	}
 
 	hostapd_setup_interface(ifmsh);
-- 
1.7.9.5




More information about the Hostap mailing list