cfg80211: validate scan channels
Currently it is possible to request a scan on only disabled channels, which could be problematic for some drivers. Reject such scans, and also ignore disabled channels that are given. This resuls in the scan begin/end event only including channels that are actually used. This makes the mac80211 check for disabled channels superfluous. At the same time, remove the no-IBSS check from mac80211 -- nothing says that we should not find any networks on channels that cannot be used for an IBSS, even when operating in IBSS mode. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
6c085227bd
Коммит
584991dccf
|
@ -614,22 +614,13 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
|
||||||
{
|
{
|
||||||
int skip;
|
int skip;
|
||||||
struct ieee80211_channel *chan;
|
struct ieee80211_channel *chan;
|
||||||
struct ieee80211_sub_if_data *sdata = local->scan_sdata;
|
|
||||||
|
|
||||||
skip = 0;
|
skip = 0;
|
||||||
chan = local->scan_req->channels[local->scan_channel_idx];
|
chan = local->scan_req->channels[local->scan_channel_idx];
|
||||||
|
|
||||||
if (chan->flags & IEEE80211_CHAN_DISABLED ||
|
|
||||||
(sdata->vif.type == NL80211_IFTYPE_ADHOC &&
|
|
||||||
chan->flags & IEEE80211_CHAN_NO_IBSS))
|
|
||||||
skip = 1;
|
|
||||||
|
|
||||||
if (!skip) {
|
|
||||||
local->scan_channel = chan;
|
local->scan_channel = chan;
|
||||||
if (ieee80211_hw_config(local,
|
if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL))
|
||||||
IEEE80211_CONF_CHANGE_CHANNEL))
|
|
||||||
skip = 1;
|
skip = 1;
|
||||||
}
|
|
||||||
|
|
||||||
/* advance state machine to next channel/band */
|
/* advance state machine to next channel/band */
|
||||||
local->scan_channel_idx++;
|
local->scan_channel_idx++;
|
||||||
|
|
|
@ -2988,7 +2988,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
request->n_channels = n_channels;
|
|
||||||
if (n_ssids)
|
if (n_ssids)
|
||||||
request->ssids = (void *)&request->channels[n_channels];
|
request->ssids = (void *)&request->channels[n_channels];
|
||||||
request->n_ssids = n_ssids;
|
request->n_ssids = n_ssids;
|
||||||
|
@ -2999,32 +2998,53 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
||||||
request->ie = (void *)(request->channels + n_channels);
|
request->ie = (void *)(request->channels + n_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
|
if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
|
||||||
/* user specified, bail out if channel not found */
|
/* user specified, bail out if channel not found */
|
||||||
request->n_channels = n_channels;
|
|
||||||
i = 0;
|
|
||||||
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
|
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
|
||||||
request->channels[i] = ieee80211_get_channel(wiphy, nla_get_u32(attr));
|
struct ieee80211_channel *chan;
|
||||||
if (!request->channels[i]) {
|
|
||||||
|
chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
|
||||||
|
|
||||||
|
if (!chan) {
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ignore disabled channels */
|
||||||
|
if (chan->flags & IEEE80211_CHAN_DISABLED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
request->channels[i] = chan;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* all channels */
|
/* all channels */
|
||||||
i = 0;
|
|
||||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||||
int j;
|
int j;
|
||||||
if (!wiphy->bands[band])
|
if (!wiphy->bands[band])
|
||||||
continue;
|
continue;
|
||||||
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
|
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
|
||||||
request->channels[i] = &wiphy->bands[band]->channels[j];
|
struct ieee80211_channel *chan;
|
||||||
|
|
||||||
|
chan = &wiphy->bands[band]->channels[j];
|
||||||
|
|
||||||
|
if (chan->flags & IEEE80211_CHAN_DISABLED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
request->channels[i] = chan;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!i) {
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
request->n_channels = i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
|
if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
|
||||||
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
|
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
|
||||||
|
|
|
@ -650,9 +650,15 @@ int cfg80211_wext_siwscan(struct net_device *dev,
|
||||||
i = 0;
|
i = 0;
|
||||||
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
if (!wiphy->bands[band])
|
if (!wiphy->bands[band])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
|
for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
|
||||||
|
/* ignore disabled channels */
|
||||||
|
if (wiphy->bands[band]->channels[j].flags &
|
||||||
|
IEEE80211_CHAN_DISABLED)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* If we have a wireless request structure and the
|
/* If we have a wireless request structure and the
|
||||||
* wireless request specifies frequencies, then search
|
* wireless request specifies frequencies, then search
|
||||||
|
|
Загрузка…
Ссылка в новой задаче