Commit 34373d12 authored by Vasanthakumar Thiagarajan's avatar Vasanthakumar Thiagarajan Committed by Johannes Berg

cfg80211: Disallow moving out of operating DFS channel in non-ETSI

For non-ETSI regulatory domain, CAC result on DFS channel
may not be valid once moving out of that channel (as done
during remain-on-channel, scannning and off-channel tx).
Running CAC on an operating DFS channel after every off-channel
operation will only add complexity and disturb the current
link. Better do not allow any off-channel switch from a DFS
operating channel in non-ETSI domain.
Signed-off-by: default avatarVasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent b35a51c7
...@@ -6556,6 +6556,19 @@ static int nl80211_parse_random_mac(struct nlattr **attrs, ...@@ -6556,6 +6556,19 @@ static int nl80211_parse_random_mac(struct nlattr **attrs,
return 0; return 0;
} }
static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
{
ASSERT_WDEV_LOCK(wdev);
if (!cfg80211_beaconing_iface_active(wdev))
return true;
if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
return true;
return regulatory_pre_cac_allowed(wdev->wiphy);
}
static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{ {
struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_registered_device *rdev = info->user_ptr[0];
...@@ -6681,6 +6694,25 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) ...@@ -6681,6 +6694,25 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
request->n_channels = i; request->n_channels = i;
wdev_lock(wdev);
if (!cfg80211_off_channel_oper_allowed(wdev)) {
struct ieee80211_channel *chan;
if (request->n_channels != 1) {
wdev_unlock(wdev);
err = -EBUSY;
goto out_free;
}
chan = request->channels[0];
if (chan->center_freq != wdev->chandef.chan->center_freq) {
wdev_unlock(wdev);
err = -EBUSY;
goto out_free;
}
}
wdev_unlock(wdev);
i = 0; i = 0;
if (n_ssids) { if (n_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) {
...@@ -9103,6 +9135,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, ...@@ -9103,6 +9135,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1]; struct wireless_dev *wdev = info->user_ptr[1];
struct cfg80211_chan_def chandef; struct cfg80211_chan_def chandef;
const struct cfg80211_chan_def *compat_chandef;
struct sk_buff *msg; struct sk_buff *msg;
void *hdr; void *hdr;
u64 cookie; u64 cookie;
...@@ -9131,6 +9164,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, ...@@ -9131,6 +9164,18 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
if (err) if (err)
return err; return err;
wdev_lock(wdev);
if (!cfg80211_off_channel_oper_allowed(wdev) &&
!cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
&chandef);
if (compat_chandef != &chandef) {
wdev_unlock(wdev);
return -EBUSY;
}
}
wdev_unlock(wdev);
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
if (!msg) if (!msg)
return -ENOMEM; return -ENOMEM;
...@@ -9306,6 +9351,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) ...@@ -9306,6 +9351,13 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
if (!chandef.chan && params.offchan) if (!chandef.chan && params.offchan)
return -EINVAL; return -EINVAL;
wdev_lock(wdev);
if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
wdev_unlock(wdev);
return -EBUSY;
}
wdev_unlock(wdev);
params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
......
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