DFS: Add supported channel bandwidth checking

While selecting a new channel as a reaction to radar event we need to
take into account supported bandwidth for each channel provided via
nl80211. Without this modification hostapd might select an unsupported
channel that would fail during AP startup.

Signed-off-by: Dmitry Lebed <dlebed@quantenna.com>
This commit is contained in:
Dmitry Lebed 2018-03-01 14:49:29 +03:00 committed by Jouni Malinen
parent 75ce63e063
commit 59bf0f9713

View file

@ -142,18 +142,30 @@ static int dfs_chan_range_available(struct hostapd_hw_modes *mode,
{ {
struct hostapd_channel_data *first_chan, *chan; struct hostapd_channel_data *first_chan, *chan;
int i; int i;
u32 bw = num_chan_to_bw(num_chans);
if (first_chan_idx + num_chans > mode->num_channels) if (first_chan_idx + num_chans > mode->num_channels)
return 0; return 0;
first_chan = &mode->channels[first_chan_idx]; first_chan = &mode->channels[first_chan_idx];
/* hostapd DFS implementation assumes the first channel as primary.
* If it's not allowed to use the first channel as primary, decline the
* whole channel range. */
if (!chan_pri_allowed(first_chan))
return 0;
for (i = 0; i < num_chans; i++) { for (i = 0; i < num_chans; i++) {
chan = dfs_get_chan_data(mode, first_chan->freq + i * 20, chan = dfs_get_chan_data(mode, first_chan->freq + i * 20,
first_chan_idx); first_chan_idx);
if (!chan) if (!chan)
return 0; return 0;
/* HT 40 MHz secondary channel availability checked only for
* primary channel */
if (!chan_bw_allowed(chan, bw, 1, !i))
return 0;
if (!dfs_channel_available(chan, skip_radar)) if (!dfs_channel_available(chan, skip_radar))
return 0; return 0;
} }
@ -197,7 +209,8 @@ static int dfs_find_channel(struct hostapd_iface *iface,
/* Skip HT40/VHT incompatible channels */ /* Skip HT40/VHT incompatible channels */
if (iface->conf->ieee80211n && if (iface->conf->ieee80211n &&
iface->conf->secondary_channel && iface->conf->secondary_channel &&
!dfs_is_chan_allowed(chan, n_chans)) (!dfs_is_chan_allowed(chan, n_chans) ||
!(chan->allowed_bw & HOSTAPD_CHAN_WIDTH_40P)))
continue; continue;
/* Skip incompatible chandefs */ /* Skip incompatible chandefs */