summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <benjamin@sipsolutions.net>2017-05-16 11:23:12 +0200
committerJohannes Berg <johannes.berg@intel.com>2017-05-19 13:25:58 +0200
commit8d9de16f80d35f12198496640c4f09d35fd77715 (patch)
tree74992d2e7684efa2e0f8a48f4607695f7c14b09a
parentd37d49c2f18fb53c6315b2b0fd7f1fb3d8be57ac (diff)
downloadlinux-8d9de16f80d35f12198496640c4f09d35fd77715.tar.gz
wireless: Require HANDLE_DFS flag to switch channel for non-AP mode
In the case the channel should be switched to one requiring DFS we need to make sure that userspace will handle radar events when they happen. For AP mode this is assumed to be the case, as a manager like hostapd is required. However IBSS and MESH modes can work without further userspace assistance, so refuse to use DFS channels unless userspace vouches that it handles DFS. NOTE: Userspace should have already flagged support earlier during mesh or IBSS setup. However, this information is not readily accessible currently. Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net> [sw: style cleanups] Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/wireless/nl80211.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d47e55e3f445..9eb59196a378 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7501,6 +7501,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
int err;
bool need_new_beacon = false;
+ bool need_handle_dfs_flag = true;
int len, i;
u32 cs_count;
@@ -7512,6 +7513,12 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_P2P_GO:
need_new_beacon = true;
+ /* For all modes except AP the handle_dfs flag needs to be
+ * supplied to tell the kernel that userspace will handle radar
+ * events when they happen. Otherwise a switch to a channel
+ * requiring DFS will be rejected.
+ */
+ need_handle_dfs_flag = false;
/* useless if AP is not running */
if (!wdev->beacon_interval)
@@ -7634,8 +7641,13 @@ skip_beacons:
if (err < 0)
return err;
- if (err > 0)
+ if (err > 0) {
params.radar_required = true;
+ if (need_handle_dfs_flag &&
+ !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
+ return -EINVAL;
+ }
+ }
if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
params.block_tx = true;