hostapd: Basic channel check for CHAN_SWITCH parameters

Implement channel sanity check for the CHAN_SWITCH command. Verify
provided values for bandwidth, frequencies, and secondary channel
offset. Reject requested channel switch operation if basic constraints
on frequencies and bandwidth are not fulfilled.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich.os@quantenna.com>
This commit is contained in:
Sergey Matyukevich 2020-01-28 15:09:49 +00:00 committed by Jouni Malinen
parent af6a2b727c
commit 30b6d4bb7d

View file

@ -2432,6 +2432,96 @@ static int hostapd_ctrl_get_pmk(struct hostapd_data *hapd, const char *cmd,
#endif /* CONFIG_TESTING_OPTIONS */
static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
{
switch (params->bandwidth) {
case 0:
/* bandwidth not specified: use 20 MHz by default */
/* fall-through */
case 20:
if (params->center_freq1 &&
params->center_freq1 != params->freq)
return -1;
if (params->center_freq2 || params->sec_channel_offset)
return -1;
break;
case 40:
if (params->center_freq2 || !params->sec_channel_offset)
return -1;
if (!params->center_freq1)
break;
switch (params->sec_channel_offset) {
case 1:
if (params->freq + 10 != params->center_freq1)
return -1;
break;
case -1:
if (params->freq - 10 != params->center_freq1)
return -1;
break;
default:
return -1;
}
break;
case 80:
if (!params->center_freq1 || !params->sec_channel_offset)
return 1;
switch (params->sec_channel_offset) {
case 1:
if (params->freq - 10 != params->center_freq1 &&
params->freq + 30 != params->center_freq1)
return 1;
break;
case -1:
if (params->freq + 10 != params->center_freq1 &&
params->freq - 30 != params->center_freq1)
return -1;
break;
default:
return -1;
}
/* Adjacent and overlapped are not allowed for 80+80 */
if (params->center_freq2 &&
params->center_freq1 - params->center_freq2 <= 80 &&
params->center_freq2 - params->center_freq1 <= 80)
return 1;
break;
case 160:
if (!params->center_freq1 || params->center_freq2 ||
!params->sec_channel_offset)
return -1;
switch (params->sec_channel_offset) {
case 1:
if (params->freq + 70 != params->center_freq1 &&
params->freq + 30 != params->center_freq1 &&
params->freq - 10 != params->center_freq1 &&
params->freq - 50 != params->center_freq1)
return -1;
break;
case -1:
if (params->freq + 50 != params->center_freq1 &&
params->freq + 10 != params->center_freq1 &&
params->freq - 30 != params->center_freq1 &&
params->freq - 70 != params->center_freq1)
return -1;
break;
default:
return -1;
}
break;
default:
return -1;
}
return 0;
}
static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
char *pos)
{
@ -2444,6 +2534,13 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
if (ret)
return ret;
ret = hostapd_ctrl_check_freq_params(&settings.freq_params);
if (ret) {
wpa_printf(MSG_INFO,
"chanswitch: invalid frequency settings provided");
return ret;
}
for (i = 0; i < iface->num_bss; i++) {
/* Save CHAN_SWITCH VHT config */