Commit be038b37 authored by Assaf Krauss's avatar Assaf Krauss Committed by John W. Linville

mac80211: Checking IBSS support while changing channel in ad-hoc mode

This patch adds a check to the set_channel flow. When attempting to change
the channel while in IBSS mode, and the new channel does not support IBSS
mode, the flow return with an error value with no consequences on the
mac80211 and driver state.
Signed-off-by: default avatarAssaf Krauss <assaf.krauss@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 872ba533
...@@ -899,7 +899,7 @@ extern const struct iw_handler_def ieee80211_iw_handler_def; ...@@ -899,7 +899,7 @@ extern const struct iw_handler_def ieee80211_iw_handler_def;
/* ieee80211_ioctl.c */ /* ieee80211_ioctl.c */
int ieee80211_set_freq(struct ieee80211_local *local, int freq); int ieee80211_set_freq(struct net_device *dev, int freq);
/* ieee80211_sta.c */ /* ieee80211_sta.c */
void ieee80211_sta_timer(unsigned long data); void ieee80211_sta_timer(unsigned long data);
void ieee80211_sta_work(struct work_struct *work); void ieee80211_sta_work(struct work_struct *work);
......
...@@ -2359,13 +2359,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, ...@@ -2359,13 +2359,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
sdata->drop_unencrypted = bss->capability & sdata->drop_unencrypted = bss->capability &
WLAN_CAPABILITY_PRIVACY ? 1 : 0; WLAN_CAPABILITY_PRIVACY ? 1 : 0;
res = ieee80211_set_freq(local, bss->freq); res = ieee80211_set_freq(dev, bss->freq);
if (local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS) { if (res)
printk(KERN_DEBUG "%s: IBSS not allowed on frequency " return res;
"%d MHz\n", dev->name, local->oper_channel->center_freq);
return -1;
}
/* Set beacon template */ /* Set beacon template */
skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
...@@ -3491,7 +3488,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev, ...@@ -3491,7 +3488,7 @@ static int ieee80211_sta_config_auth(struct net_device *dev,
spin_unlock_bh(&local->sta_bss_lock); spin_unlock_bh(&local->sta_bss_lock);
if (selected) { if (selected) {
ieee80211_set_freq(local, selected->freq); ieee80211_set_freq(dev, selected->freq);
if (!(ifsta->flags & IEEE80211_STA_SSID_SET)) if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
ieee80211_sta_set_ssid(dev, selected->ssid, ieee80211_sta_set_ssid(dev, selected->ssid,
selected->ssid_len); selected->ssid_len);
......
...@@ -290,14 +290,22 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev, ...@@ -290,14 +290,22 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev,
return 0; return 0;
} }
int ieee80211_set_freq(struct ieee80211_local *local, int freqMHz) int ieee80211_set_freq(struct net_device *dev, int freqMHz)
{ {
int ret = -EINVAL; int ret = -EINVAL;
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
chan = ieee80211_get_channel(local->hw.wiphy, freqMHz); chan = ieee80211_get_channel(local->hw.wiphy, freqMHz);
if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) { if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
chan->flags & IEEE80211_CHAN_NO_IBSS) {
printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
"%d MHz\n", dev->name, chan->center_freq);
return ret;
}
local->oper_channel = chan; local->oper_channel = chan;
if (local->sta_sw_scanning || local->sta_hw_scanning) if (local->sta_sw_scanning || local->sta_hw_scanning)
...@@ -315,7 +323,6 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, ...@@ -315,7 +323,6 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
struct iw_request_info *info, struct iw_request_info *info,
struct iw_freq *freq, char *extra) struct iw_freq *freq, char *extra)
{ {
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
if (sdata->vif.type == IEEE80211_IF_TYPE_STA) if (sdata->vif.type == IEEE80211_IF_TYPE_STA)
...@@ -329,14 +336,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev, ...@@ -329,14 +336,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
IEEE80211_STA_AUTO_CHANNEL_SEL; IEEE80211_STA_AUTO_CHANNEL_SEL;
return 0; return 0;
} else } else
return ieee80211_set_freq(local, return ieee80211_set_freq(dev,
ieee80211_channel_to_frequency(freq->m)); ieee80211_channel_to_frequency(freq->m));
} else { } else {
int i, div = 1000000; int i, div = 1000000;
for (i = 0; i < freq->e; i++) for (i = 0; i < freq->e; i++)
div /= 10; div /= 10;
if (div > 0) if (div > 0)
return ieee80211_set_freq(local, freq->m / div); return ieee80211_set_freq(dev, freq->m / div);
else else
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment