mesh: Make BSSBasicRateSet configurable
STAs that have different BSSBasicRateSet cannot connect to each other as per IEEE 802.11s-2011 9.6.0c1: "A mesh STA shall not establish a mesh peering with a mesh STA using a different BSSBasicRateSet." Make BSSBasicRateSet configurable to improve interoperability with other stations. Signed-off-by: Masashi Honma <masashi.honma@gmail.com>
This commit is contained in:
parent
603a3f34c4
commit
2b2bb5a8b9
4 changed files with 72 additions and 12 deletions
|
@ -1617,7 +1617,31 @@ static int wpa_config_parse_mesh_ht_mode(const struct parse_data *data,
|
|||
}
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -1643,6 +1667,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 */
|
||||
|
@ -1819,6 +1850,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 /* CONFIG_MESH */
|
||||
{ INT(wpa_ptk_rekey) },
|
||||
{ STR(bgscan) },
|
||||
|
@ -2049,6 +2081,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);
|
||||
|
|
|
@ -743,7 +743,10 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
|
|||
INT(update_identifier);
|
||||
#endif /* CONFIG_HS20 */
|
||||
write_int(f, "mac_addr", ssid->mac_addr, -1);
|
||||
#ifdef CONFIG_MESH
|
||||
STR(mesh_ht_mode);
|
||||
STR(mesh_basic_rates);
|
||||
#endif /* CONFIG_MESH */
|
||||
|
||||
#undef STR
|
||||
#undef INT
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -122,6 +122,7 @@ static int 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, -1 };
|
||||
size_t len;
|
||||
int rate_len;
|
||||
|
||||
if (!wpa_s->conf->user_mpm) {
|
||||
/* not much for us to do here */
|
||||
|
@ -186,19 +187,34 @@ static int 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 Beacon frames match the
|
||||
* one in peering frames, sigh.
|
||||
*/
|
||||
if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
|
||||
conf->basic_rates = os_malloc(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_malloc(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_calloc(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));
|
||||
os_memcpy(conf->basic_rates, ssid->mesh_basic_rates,
|
||||
rate_len * sizeof(int));
|
||||
conf->basic_rates[rate_len] = -1;
|
||||
}
|
||||
|
||||
if (hostapd_setup_interface(ifmsh)) {
|
||||
|
|
Loading…
Reference in a new issue