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
|
#ifndef NO_CONFIG_WRITE
|
||||||
|
|
||||||
static char * wpa_config_write_mesh_ht_mode(const struct parse_data *data,
|
static char * wpa_config_write_mesh_ht_mode(const struct parse_data *data,
|
||||||
struct wpa_ssid *ssid)
|
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;
|
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 /* NO_CONFIG_WRITE */
|
||||||
|
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
|
@ -1819,6 +1850,7 @@ static const struct parse_data ssid_fields[] = {
|
||||||
{ INT_RANGE(frequency, 0, 65000) },
|
{ INT_RANGE(frequency, 0, 65000) },
|
||||||
#ifdef CONFIG_MESH
|
#ifdef CONFIG_MESH
|
||||||
{ FUNC(mesh_ht_mode) },
|
{ FUNC(mesh_ht_mode) },
|
||||||
|
{ FUNC(mesh_basic_rates) },
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
{ INT(wpa_ptk_rekey) },
|
{ INT(wpa_ptk_rekey) },
|
||||||
{ STR(bgscan) },
|
{ STR(bgscan) },
|
||||||
|
@ -2049,6 +2081,9 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
|
||||||
#ifdef CONFIG_HT_OVERRIDES
|
#ifdef CONFIG_HT_OVERRIDES
|
||||||
os_free(ssid->ht_mcs);
|
os_free(ssid->ht_mcs);
|
||||||
#endif /* CONFIG_HT_OVERRIDES */
|
#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,
|
while ((psk = dl_list_first(&ssid->psk_list, struct psk_list_entry,
|
||||||
list))) {
|
list))) {
|
||||||
dl_list_del(&psk->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);
|
INT(update_identifier);
|
||||||
#endif /* CONFIG_HS20 */
|
#endif /* CONFIG_HS20 */
|
||||||
write_int(f, "mac_addr", ssid->mac_addr, -1);
|
write_int(f, "mac_addr", ssid->mac_addr, -1);
|
||||||
|
#ifdef CONFIG_MESH
|
||||||
STR(mesh_ht_mode);
|
STR(mesh_ht_mode);
|
||||||
|
STR(mesh_basic_rates);
|
||||||
|
#endif /* CONFIG_MESH */
|
||||||
|
|
||||||
#undef STR
|
#undef STR
|
||||||
#undef INT
|
#undef INT
|
||||||
|
|
|
@ -413,6 +413,12 @@ struct wpa_ssid {
|
||||||
*/
|
*/
|
||||||
int mesh_ht_mode;
|
int mesh_ht_mode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mesh_basic_rates - BSS Basic rate set for mesh network
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int *mesh_basic_rates;
|
||||||
|
|
||||||
int ht40;
|
int ht40;
|
||||||
|
|
||||||
int vht;
|
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 };
|
int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
|
||||||
static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
|
static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
|
||||||
size_t len;
|
size_t len;
|
||||||
|
int rate_len;
|
||||||
|
|
||||||
if (!wpa_s->conf->user_mpm) {
|
if (!wpa_s->conf->user_mpm) {
|
||||||
/* not much for us to do here */
|
/* not much for us to do here */
|
||||||
|
@ -186,12 +187,13 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ssid->mesh_basic_rates == NULL) {
|
||||||
/*
|
/*
|
||||||
* XXX: Hack! This is so an MPM which correctly sets the ERP mandatory
|
* XXX: Hack! This is so an MPM which correctly sets the ERP
|
||||||
* rates as BSSBasicRateSet doesn't reject us. We could add a new
|
* mandatory rates as BSSBasicRateSet doesn't reject us. We
|
||||||
* hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but this is way easier. This
|
* could add a new hw_mode HOSTAPD_MODE_IEEE80211G_ERP, but
|
||||||
* also makes our BSSBasicRateSet advertised in Beacon frames match the
|
* this is way easier. This also makes our BSSBasicRateSet
|
||||||
* one in peering frames, sigh.
|
* advertised in beacons match the one in peering frames, sigh.
|
||||||
*/
|
*/
|
||||||
if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
|
if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
|
||||||
conf->basic_rates = os_malloc(sizeof(basic_rates_erp));
|
conf->basic_rates = os_malloc(sizeof(basic_rates_erp));
|
||||||
|
@ -200,6 +202,20 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
|
||||||
os_memcpy(conf->basic_rates, basic_rates_erp,
|
os_memcpy(conf->basic_rates, basic_rates_erp,
|
||||||
sizeof(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, ssid->mesh_basic_rates,
|
||||||
|
rate_len * sizeof(int));
|
||||||
|
conf->basic_rates[rate_len] = -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (hostapd_setup_interface(ifmsh)) {
|
if (hostapd_setup_interface(ifmsh)) {
|
||||||
wpa_printf(MSG_ERROR,
|
wpa_printf(MSG_ERROR,
|
||||||
|
|
Loading…
Reference in a new issue