DFS: Sanitize channel availability checks

Fixes corner case of holes in channel list and simplifies availability
checks.

Signed-hostap: Michal Kazior <michal.kazior@tieto.com>
This commit is contained in:
Michal Kazior 2013-10-31 14:48:34 +02:00 committed by Jouni Malinen
parent 32595da608
commit 6a398ddc9a

View file

@ -94,6 +94,31 @@ static int dfs_is_chan_allowed(struct hostapd_channel_data *chan, int n_chans)
}
static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
int first_chan_idx, int num_chans)
{
struct hostapd_channel_data *first_chan, *chan;
int i;
if (first_chan_idx + num_chans >= mode->num_channels)
return 0;
first_chan = &mode->channels[first_chan_idx];
for (i = 0; i < num_chans; i++) {
chan = &mode->channels[first_chan_idx + i];
if (first_chan->freq + i * 20 != chan->freq)
return 0;
if (!dfs_channel_available(chan))
return 0;
}
return 1;
}
/*
* The function assumes HT40+ operation.
* Make sure to adjust the following variables after calling this:
@ -106,8 +131,8 @@ static int dfs_find_channel(struct hostapd_data *hapd,
int idx)
{
struct hostapd_hw_modes *mode;
struct hostapd_channel_data *chan, *next_chan;
int i, j, channel_idx = 0, n_chans;
struct hostapd_channel_data *chan;
int i, channel_idx = 0, n_chans;
mode = hapd->iface->current_mode;
n_chans = dfs_get_used_n_chans(hapd);
@ -116,24 +141,15 @@ static int dfs_find_channel(struct hostapd_data *hapd,
for (i = 0; i < mode->num_channels; i++) {
chan = &mode->channels[i];
/* Skip not available channels */
if (!dfs_channel_available(chan))
/* Skip HT40/VHT incompatible channels */
if (hapd->iconf->ieee80211n &&
hapd->iconf->secondary_channel &&
!dfs_is_chan_allowed(chan, n_chans))
continue;
/* Skip HT40/VHT uncompatible channels */
if (hapd->iconf->ieee80211n &&
hapd->iconf->secondary_channel) {
if (!dfs_is_chan_allowed(chan, n_chans))
continue;
for (j = 1; j < n_chans; j++) {
next_chan = &mode->channels[i + j];
if (!dfs_channel_available(next_chan))
break;
}
if (j != n_chans)
continue;
}
/* Skip incompatible chandefs */
if (!dfs_chan_range_available(mode, i, n_chans))
continue;
if (ret_chan && idx == channel_idx) {
wpa_printf(MSG_DEBUG, "Selected ch. #%d", chan->chan);