linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
@ 2017-05-16  9:23 Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 1/7] mac80211: Mark channel as unusable if a regulatory MESH CSA is received Simon Wunderlich
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

This patchset adds DFS and CSA functionality:

 * Mesh CSA is handled similary to IBSS, that means CSA will mark
   channels as unusable, and require userspace to handle actual
   radar signals
 * Add VHT processing for CSA in mesh mode, and some small cleanups

We have been working on this feature set for quite some time internally,
and I believe it is time to propose it for inclusion. I'll handle
any change requests to this patchset. :)

Cheers,
     Simon

Benjamin Berg (4):
  mac80211: Mark channel as unusable if a regulatory MESH CSA is
    received
  wireless: Only join DFS channels in mesh mode if userspace flags
    support
  wireless: Require HANDLE_DFS flag to switch channel for non-AP mode
  mac80211: Allow following CSA to DFS channels if userspace handles it

Simon Wunderlich (3):
  mac80211: add wide bandwidth channel switch announcement to CSA action
    frames and mesh beacons
  mac80211: enable VHT for mesh channel processing
  mac80211: mark as action frame when parsing IEs of CSA action frames

 include/net/cfg80211.h     |  4 +++
 net/mac80211/cfg.c         |  1 +
 net/mac80211/ieee80211_i.h |  5 +++
 net/mac80211/mesh.c        | 89 ++++++++++++++++++++++++++++++++++++++++++----
 net/mac80211/spectmgmt.c   |  5 +++
 net/mac80211/util.c        | 40 +++++++++++++++++++++
 net/wireless/mesh.c        |  8 +++++
 net/wireless/nl80211.c     | 17 ++++++++-
 8 files changed, 161 insertions(+), 8 deletions(-)

-- 
2.11.0

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/7] mac80211: Mark channel as unusable if a regulatory MESH CSA is received
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
@ 2017-05-16  9:23 ` Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 2/7] wireless: Only join DFS channels in mesh mode if userspace flags support Simon Wunderlich
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

From: Benjamin Berg <benjamin@sipsolutions.net>

In the Mesh Channel Switch Parameters (8.4.2.105) the reason is specified
to WLAN_REASON_MESH_CHAN_REGULATORY in the case that a regulatory
limitation was the cause for the switch. This means another station
detected a radar event.

Mark the channel as unusable if this happens.

Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
[sw: style cleanup, rebase]
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
 net/mac80211/ieee80211_i.h |  1 +
 net/mac80211/mesh.c        | 21 +++++++++++++++++++++
 net/mac80211/spectmgmt.c   |  5 +++++
 3 files changed, 27 insertions(+)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f8f6c148f554..60bed6c69801 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1440,6 +1440,7 @@ struct ieee80211_csa_ie {
 	u8 count;
 	u8 ttl;
 	u16 pre_value;
+	u16 reason_code;
 };
 
 /* Parsed Information Elements */
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 737e1f082b0d..3702e3d9141d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -916,6 +916,21 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
 	ieee80211_configure_filter(local);
 }
 
+static void ieee80211_mesh_csa_mark_radar(struct ieee80211_sub_if_data *sdata)
+{
+	int err;
+
+	/* if the current channel is a DFS channel, mark the channel as
+	 * unavailable.
+	 */
+	err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
+					    &sdata->vif.bss_conf.chandef,
+					    NL80211_IFTYPE_MESH_POINT);
+	if (err > 0)
+		cfg80211_radar_event(sdata->local->hw.wiphy,
+				     &sdata->vif.bss_conf.chandef, GFP_ATOMIC);
+}
+
 static bool
 ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
 				 struct ieee802_11_elems *elems, bool beacon)
@@ -954,6 +969,12 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
 	if (err)
 		return false;
 
+	/* Mark the channel unavailable if the reason for the switch is
+	 * regulatory.
+	 */
+	if (csa_ie.reason_code == WLAN_REASON_MESH_CHAN_REGULATORY)
+		ieee80211_mesh_csa_mark_radar(sdata);
+
 	params.chandef = csa_ie.chandef;
 	params.count = csa_ie.count;
 
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 0782e486fe89..d2ea0017c79d 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -76,6 +76,11 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
 		csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags;
 		csa_ie->pre_value = le16_to_cpu(
 				elems->mesh_chansw_params_ie->mesh_pre_value);
+
+		if (elems->mesh_chansw_params_ie->mesh_flags &
+				WLAN_EID_CHAN_SWITCH_PARAM_REASON)
+			csa_ie->reason_code = le16_to_cpu(
+				elems->mesh_chansw_params_ie->mesh_reason);
 	}
 
 	new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/7] wireless: Only join DFS channels in mesh mode if userspace flags support
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 1/7] mac80211: Mark channel as unusable if a regulatory MESH CSA is received Simon Wunderlich
@ 2017-05-16  9:23 ` Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 3/7] wireless: Require HANDLE_DFS flag to switch channel for non-AP mode Simon Wunderlich
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

From: Benjamin Berg <benjamin@sipsolutions.net>

When joining a mesh network it is not guaranteed that userspace has a
daemon listening for radar events. This is however required for channels
requiring DFS. To flag that userspace will handle radar events, it needs
to set NL80211_ATTR_HANDLE_DFS.

This matches the current mechanism used for IBSS mode.

Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
 include/net/cfg80211.h | 4 ++++
 net/wireless/mesh.c    | 8 ++++++++
 net/wireless/nl80211.c | 3 +++
 3 files changed, 15 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index b083e6cbae8c..fa25fbb67cb6 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1441,6 +1441,9 @@ struct mesh_config {
  * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a]
  * @basic_rates: basic rates to use when creating the mesh
  * @beacon_rate: bitrate to be used for beacons
+ * @userspace_handles_dfs: whether user space controls DFS operation, i.e.
+ *	changes the channel when a radar is detected. This is required
+ *	to operate on DFS channels.
  *
  * These parameters are fixed when the mesh is created.
  */
@@ -1462,6 +1465,7 @@ struct mesh_setup {
 	int mcast_rate[NUM_NL80211_BANDS];
 	u32 basic_rates;
 	struct cfg80211_bitrate_mask beacon_rate;
+	bool userspace_handles_dfs;
 };
 
 /**
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index ec0b1c20ac99..421a6b80ec62 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -174,6 +174,14 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 							       scan_width);
 	}
 
+	err = cfg80211_chandef_dfs_required(&rdev->wiphy,
+					    &setup->chandef,
+					    NL80211_IFTYPE_MESH_POINT);
+	if (err < 0)
+		return err;
+	if (err > 0 && !setup->userspace_handles_dfs)
+		return -EINVAL;
+
 	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef,
 				     NL80211_IFTYPE_MESH_POINT))
 		return -EINVAL;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c3bc9da30cff..d47e55e3f445 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -9962,6 +9962,9 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
 			return err;
 	}
 
+	setup.userspace_handles_dfs =
+		nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
+
 	return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
 }
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/7] wireless: Require HANDLE_DFS flag to switch channel for non-AP mode
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 1/7] mac80211: Mark channel as unusable if a regulatory MESH CSA is received Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 2/7] wireless: Only join DFS channels in mesh mode if userspace flags support Simon Wunderlich
@ 2017-05-16  9:23 ` Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 4/7] mac80211: Allow following CSA to DFS channels if userspace handles it Simon Wunderlich
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

From: Benjamin Berg <benjamin@sipsolutions.net>

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>
---
 net/wireless/nl80211.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

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 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
 	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;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] mac80211: Allow following CSA to DFS channels if userspace handles it
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
                   ` (2 preceding siblings ...)
  2017-05-16  9:23 ` [PATCH 3/7] wireless: Require HANDLE_DFS flag to switch channel for non-AP mode Simon Wunderlich
@ 2017-05-16  9:23 ` Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons Simon Wunderlich
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

From: Benjamin Berg <benjamin@sipsolutions.net>

If userspace has flagged support for DFS earlier, then we can follow CSA
to DFS channels. So instead of rejecting the switch, allow it to happen
if the flag has been set during mesh setup.

Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
 net/mac80211/cfg.c         |  1 +
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/mesh.c        | 15 ++++++++++++---
 3 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6c2e6060cd54..6980a936a437 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1874,6 +1874,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
 	ifmsh->user_mpm = setup->user_mpm;
 	ifmsh->mesh_auth_id = setup->auth_id;
 	ifmsh->security = IEEE80211_MESH_SEC_NONE;
+	ifmsh->userspace_handles_dfs = setup->userspace_handles_dfs;
 	if (setup->is_authenticated)
 		ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
 	if (setup->is_secure)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 60bed6c69801..c960e4999380 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -643,6 +643,8 @@ struct ieee80211_if_mesh {
 	unsigned long wrkq_flags;
 	unsigned long mbss_changed;
 
+	bool userspace_handles_dfs;
+
 	u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
 	size_t mesh_id_len;
 	/* Active Path Selection Protocol Identifier */
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 3702e3d9141d..4807a5d77572 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -979,7 +979,9 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
 	params.count = csa_ie.count;
 
 	if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, &params.chandef,
-				     IEEE80211_CHAN_DISABLED)) {
+				     IEEE80211_CHAN_DISABLED) ||
+	    !cfg80211_reg_can_beacon(sdata->local->hw.wiphy, &params.chandef,
+				     NL80211_IFTYPE_MESH_POINT)) {
 		sdata_info(sdata,
 			   "mesh STA %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), aborting\n",
 			   sdata->vif.addr,
@@ -995,9 +997,16 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
 					    NL80211_IFTYPE_MESH_POINT);
 	if (err < 0)
 		return false;
-	if (err > 0)
-		/* TODO: DFS not (yet) supported */
+	if (err > 0 && !ifmsh->userspace_handles_dfs) {
+		sdata_info(sdata,
+			   "mesh STA %pM switches to channel requiring DFS (%d MHz, width:%d, CF1/2: %d/%d MHz), aborting\n",
+			   sdata->vif.addr,
+			   params.chandef.chan->center_freq,
+			   params.chandef.width,
+			   params.chandef.center_freq1,
+			   params.chandef.center_freq2);
 		return false;
+	}
 
 	params.radar_required = err;
 
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
                   ` (3 preceding siblings ...)
  2017-05-16  9:23 ` [PATCH 4/7] mac80211: Allow following CSA to DFS channels if userspace handles it Simon Wunderlich
@ 2017-05-16  9:23 ` Simon Wunderlich
  2017-05-19 11:33   ` Johannes Berg
  2017-05-16  9:23 ` [PATCH 6/7] mac80211: enable VHT for mesh channel processing Simon Wunderlich
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

To support HT and VHT CSA, beacons and action frames must include the
corresponding IEs.

Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
 net/mac80211/ieee80211_i.h |  2 ++
 net/mac80211/mesh.c        | 47 ++++++++++++++++++++++++++++++++++++++++++++--
 net/mac80211/util.c        | 40 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index c960e4999380..e3a0b295c5ce 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -2066,6 +2066,8 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
 u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
 			       const struct cfg80211_chan_def *chandef,
 			       u16 prot_mode, bool rifs_mode);
+u8 *ieee80211_ie_build_wide_bw_cs(u8 *pos,
+				  const struct cfg80211_chan_def *chandef);
 u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
 			       u32 cap);
 u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 4807a5d77572..7c6593c0d453 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -690,6 +690,8 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
 		   2 + sizeof(struct ieee80211_channel_sw_ie) +
 		   /* Mesh Channel Switch Parameters */
 		   2 + sizeof(struct ieee80211_mesh_chansw_params_ie) +
+		   2 + 2 + sizeof(struct ieee80211_wide_bw_chansw_ie) +
+		   2 + sizeof(struct ieee80211_sec_chan_offs_ie) +
 		   2 + 8 + /* supported rates */
 		   2 + 3; /* DS params */
 	tail_len = 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
@@ -736,8 +738,27 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
 	rcu_read_lock();
 	csa = rcu_dereference(ifmsh->csa);
 	if (csa) {
-		pos = skb_put(skb, 13);
-		memset(pos, 0, 13);
+		bool have_secondary_chan_offset = false;
+		bool have_wide_bandwidth_cs = false;
+		int ie_len = 2 + sizeof(struct ieee80211_channel_sw_ie) +
+			     2 + sizeof(struct ieee80211_mesh_chansw_params_ie);
+
+		switch (csa->settings.chandef.width) {
+		case NL80211_CHAN_WIDTH_80:
+		case NL80211_CHAN_WIDTH_80P80:
+		case NL80211_CHAN_WIDTH_160:
+			have_wide_bandwidth_cs = true;
+			ie_len += 2 + 2 +
+				  sizeof(struct ieee80211_wide_bw_chansw_ie);
+			break;
+		case NL80211_CHAN_WIDTH_40:
+			have_secondary_chan_offset = true;
+			ie_len += 2 + sizeof(struct ieee80211_sec_chan_offs_ie);
+		default:
+			break;
+		}
+		pos = skb_put(skb, ie_len);
+		memset(pos, 0, ie_len);
 		*pos++ = WLAN_EID_CHANNEL_SWITCH;
 		*pos++ = 3;
 		*pos++ = 0x0;
@@ -760,6 +781,28 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
 		pos += 2;
 		put_unaligned_le16(ifmsh->pre_value, pos);
 		pos += 2;
+
+		if (have_secondary_chan_offset) {
+			enum nl80211_channel_type ct;
+
+			*pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */
+			*pos++ = 1;				    /* len */
+			ct = cfg80211_get_chandef_type(&csa->settings.chandef);
+			if (ct == NL80211_CHAN_HT40PLUS)
+				*pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+			else
+				*pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+		}
+
+		if (have_wide_bandwidth_cs) {
+			struct cfg80211_chan_def *chandef;
+
+			*pos++ = WLAN_EID_CHANNEL_SWITCH_WRAPPER; /* EID */
+			*pos++ = 5;				  /* len */
+			/* put sub IE */
+			chandef = &csa->settings.chandef;
+			pos = ieee80211_ie_build_wide_bw_cs(pos, chandef);
+		}
 	}
 	rcu_read_unlock();
 
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ac9ac6c35594..d2e885cbfdf8 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2414,6 +2414,37 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
 	return pos + sizeof(struct ieee80211_ht_operation);
 }
 
+u8 *ieee80211_ie_build_wide_bw_cs(u8 *pos,
+				  const struct cfg80211_chan_def *chandef)
+{
+	*pos++ = WLAN_EID_WIDE_BW_CHANNEL_SWITCH;	/* EID */
+	*pos++ = 3;					/* IE length */
+	/* New channel width */
+	switch (chandef->width) {
+	case NL80211_CHAN_WIDTH_80:
+		*pos++ = IEEE80211_VHT_CHANWIDTH_80MHZ;
+		break;
+	case NL80211_CHAN_WIDTH_160:
+		*pos++ = IEEE80211_VHT_CHANWIDTH_160MHZ;
+		break;
+	case NL80211_CHAN_WIDTH_80P80:
+		*pos++ = IEEE80211_VHT_CHANWIDTH_80P80MHZ;
+		break;
+	default:
+		*pos++ = IEEE80211_VHT_CHANWIDTH_USE_HT;
+	}
+
+	/* new center frequency segment 0 */
+	*pos++ = ieee80211_frequency_to_channel(chandef->center_freq1);
+	/* new center frequency segment 1 */
+	if (chandef->center_freq2)
+		*pos++ = ieee80211_frequency_to_channel(chandef->center_freq2);
+	else
+		*pos++ = 0;
+
+	return pos;
+}
+
 u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
 				const struct cfg80211_chan_def *chandef)
 {
@@ -2964,6 +2995,7 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
 	skb = dev_alloc_skb(local->tx_headroom + hdr_len +
 			    5 + /* channel switch announcement element */
 			    3 + /* secondary channel offset element */
+			    5 + /* wide bandwidth channel switch announcement */
 			    8); /* mesh channel switch parameters element */
 	if (!skb)
 		return -ENOMEM;
@@ -3022,6 +3054,14 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
 		pos += 2;
 	}
 
+	if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_80 ||
+	    csa_settings->chandef.width == NL80211_CHAN_WIDTH_80P80 ||
+	    csa_settings->chandef.width == NL80211_CHAN_WIDTH_160) {
+		skb_put(skb, 5);
+		pos = ieee80211_ie_build_wide_bw_cs(pos,
+						    &csa_settings->chandef);
+	}
+
 	ieee80211_tx_skb(sdata, skb);
 	return 0;
 }
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/7] mac80211: enable VHT for mesh channel processing
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
                   ` (4 preceding siblings ...)
  2017-05-16  9:23 ` [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons Simon Wunderlich
@ 2017-05-16  9:23 ` Simon Wunderlich
  2017-05-16  9:23 ` [PATCH 7/7] mac80211: mark as action frame when parsing IEs of CSA action frames Simon Wunderlich
  2017-05-16  9:44 ` [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Bastian Bittorf
  7 siblings, 0 replies; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
 net/mac80211/mesh.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 7c6593c0d453..a57af5df7ee4 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -991,12 +991,14 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
 	if (!sband)
 		return false;
 
-	sta_flags = IEEE80211_STA_DISABLE_VHT;
+	sta_flags = 0;
 	switch (sdata->vif.bss_conf.chandef.width) {
 	case NL80211_CHAN_WIDTH_20_NOHT:
 		sta_flags |= IEEE80211_STA_DISABLE_HT;
 	case NL80211_CHAN_WIDTH_20:
 		sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
+	case NL80211_CHAN_WIDTH_40:
+		sta_flags |= IEEE80211_STA_DISABLE_VHT;
 		break;
 	default:
 		break;
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] mac80211: mark as action frame when parsing IEs of CSA action frames
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
                   ` (5 preceding siblings ...)
  2017-05-16  9:23 ` [PATCH 6/7] mac80211: enable VHT for mesh channel processing Simon Wunderlich
@ 2017-05-16  9:23 ` Simon Wunderlich
  2017-05-19 11:35   ` Johannes Berg
  2017-05-16  9:44 ` [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Bastian Bittorf
  7 siblings, 1 reply; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16  9:23 UTC (permalink / raw)
  To: johannes; +Cc: linux-wireless, benjamin, Simon Wunderlich

Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
---
 net/mac80211/mesh.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index a57af5df7ee4..ab07974cdcf4 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1308,7 +1308,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
 	pos = mgmt->u.action.u.chan_switch.variable;
 	baselen = offsetof(struct ieee80211_mgmt,
 			   u.action.u.chan_switch.variable);
-	ieee802_11_parse_elems(pos, len - baselen, false, &elems);
+	ieee802_11_parse_elems(pos, len - baselen, true, &elems);
 
 	ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
 	if (!--ifmsh->chsw_ttl)
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
  2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
                   ` (6 preceding siblings ...)
  2017-05-16  9:23 ` [PATCH 7/7] mac80211: mark as action frame when parsing IEs of CSA action frames Simon Wunderlich
@ 2017-05-16  9:44 ` Bastian Bittorf
  2017-05-16 10:18   ` Simon Wunderlich
  7 siblings, 1 reply; 16+ messages in thread
From: Bastian Bittorf @ 2017-05-16  9:44 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: johannes, linux-wireless, benjamin

* Simon Wunderlich <sw@simonwunderlich.de> [16.05.2017 11:35]:
> This patchset adds DFS and CSA functionality:

thanks a lot. can you give a brief 'iw event' output when applied:
for a two-node mesh, where station A detects CSA and station B
should emit an event...

question: there is no userspace part for now, or maybe planned?

bye, bastian - now it's time for battlemesh.org 8-)

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
  2017-05-16  9:44 ` [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Bastian Bittorf
@ 2017-05-16 10:18   ` Simon Wunderlich
  2017-05-16 11:55     ` Bastian Bittorf
  0 siblings, 1 reply; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16 10:18 UTC (permalink / raw)
  To: Bastian Bittorf; +Cc: johannes, linux-wireless, benjamin

[-- Attachment #1: Type: text/plain, Size: 984 bytes --]

Hi Basti,

On Tuesday, May 16, 2017 11:44:04 AM CEST Bastian Bittorf wrote:
> * Simon Wunderlich <sw@simonwunderlich.de> [16.05.2017 11:35]:
> > This patchset adds DFS and CSA functionality:
> thanks a lot. can you give a brief 'iw event' output when applied:
> for a two-node mesh, where station A detects CSA and station B
> should emit an event...

The idea would be:

 * station A detects a Radar, and informs userspace
 * userspace of station A will initiate a CSA, kernel will execute it (action 
frame, beacons)
 * station B picks up the CSA, and executes it as well
 * station B also marks the channel as unavailable
 * both station A and station B will send an event to userspace once the 
channel switch is complete
> 
> question: there is no userspace part for now, or maybe planned?

I've got some patches for wpa_supplicant here, but they are still quite dirty 
...

> 
> bye, bastian - now it's time for battlemesh.org 8-)

See you at battlemesh :)

Cheers,
     Simon


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
  2017-05-16 10:18   ` Simon Wunderlich
@ 2017-05-16 11:55     ` Bastian Bittorf
  2017-05-16 12:04       ` Simon Wunderlich
  0 siblings, 1 reply; 16+ messages in thread
From: Bastian Bittorf @ 2017-05-16 11:55 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: johannes, linux-wireless, benjamin

* Simon Wunderlich <sw@simonwunderlich.de> [16.05.2017 12:24]:
>  * station A detects a Radar, and informs userspace
>  * userspace of station A will initiate a CSA, kernel will execute it (action 
> frame, beacons)
>  * station B picks up the CSA, and executes it as well
>  * station B also marks the channel as unavailable
>  * both station A and station B will send an event to userspace once the 
> channel switch is complete

ah, I remember the slides from last battlemesh.

The "problems" in userspace are: we must maintain a global list
(so each node) which channel is the next best and we must time
the final channel switch. IMHO the specs are saying, that we must
switch within 30 secs after detecting the first radar-pattern.
Also we must mark/show the new channel somehow for new/crashed/upcoming nodes.
quite hard...

bye, bastian

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality
  2017-05-16 11:55     ` Bastian Bittorf
@ 2017-05-16 12:04       ` Simon Wunderlich
  0 siblings, 0 replies; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-16 12:04 UTC (permalink / raw)
  To: Bastian Bittorf; +Cc: johannes, linux-wireless, benjamin

[-- Attachment #1: Type: text/plain, Size: 1594 bytes --]

On Tuesday, May 16, 2017 1:55:46 PM CEST Bastian Bittorf wrote:
> * Simon Wunderlich <sw@simonwunderlich.de> [16.05.2017 12:24]:
> >  * station A detects a Radar, and informs userspace
> >  * userspace of station A will initiate a CSA, kernel will execute it
> >  (action> 
> > frame, beacons)
> > 
> >  * station B picks up the CSA, and executes it as well
> >  * station B also marks the channel as unavailable
> >  * both station A and station B will send an event to userspace once the
> > 
> > channel switch is complete
> 
> ah, I remember the slides from last battlemesh.
> 
> The "problems" in userspace are: we must maintain a global list
> (so each node) which channel is the next best and we must time
> the final channel switch. IMHO the specs are saying, that we must
> switch within 30 secs after detecting the first radar-pattern.
> Also we must mark/show the new channel somehow for new/crashed/upcoming
> nodes. quite hard...

The timing is not a big problem, since the switch does not happen immediately 
but is performed after a "countdown" which is part of the channel switch 
announcement IEs. The specific rules for the countdown depend on the regulatory 
domain, but it's usually something between 1 and 5 seconds where payload traffic 
must not be transmitted (at least for the DFS case).

The bigger problem appears when a node is missing the CSA for whatever reason, 
or is joining the network - worst case, the mesh network can split into clouds 
on different channels. This is where we need the global list, or showing the 
next channel, etc. :)

Cheers,
     Simon

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons
  2017-05-16  9:23 ` [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons Simon Wunderlich
@ 2017-05-19 11:33   ` Johannes Berg
  2017-05-19 11:45     ` Simon Wunderlich
  0 siblings, 1 reply; 16+ messages in thread
From: Johannes Berg @ 2017-05-19 11:33 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: linux-wireless, benjamin

I've applied patches 1-4 now.

The subject is a bit long - I was going to change it to

    mac80211: mesh: support sending wide bandwidth CSA
    
    To support HT and VHT channel switch announcements, both beacons
    and action frames must include the corresponding IEs.

but:

> +		   2 + 2 + sizeof(struct
> ieee80211_wide_bw_chansw_ie) +
> +		   2 + sizeof(struct ieee80211_sec_chan_offs_ie) +

The "2 + 2" should have a comment - no that I'm even really sure that
you need the wrapper?

> -		pos = skb_put(skb, 13);
> -		memset(pos, 0, 13);

Removing that is nice - but why do you do this:

> +		bool have_secondary_chan_offset = false;
> +		bool have_wide_bandwidth_cs = false;
> +		int ie_len = 2 + sizeof(struct
> ieee80211_channel_sw_ie) +
> +			     2 + sizeof(struct
> ieee80211_mesh_chansw_params_ie);
> +
> +		switch (csa->settings.chandef.width) {
> +		case NL80211_CHAN_WIDTH_80:
> +		case NL80211_CHAN_WIDTH_80P80:
> +		case NL80211_CHAN_WIDTH_160:
> +			have_wide_bandwidth_cs = true;
> +			ie_len += 2 + 2 +
> +				  sizeof(struct
> ieee80211_wide_bw_chansw_ie);
> +			break;
> +		case NL80211_CHAN_WIDTH_40:
> +			have_secondary_chan_offset = true;
> +			ie_len += 2 + sizeof(struct
> ieee80211_sec_chan_offs_ie);
> +		default:
> +			break;
> +		}
> +		pos = skb_put(skb, ie_len);
> +		memset(pos, 0, ie_len);

I think having multiple calls to skb_put() would be better.

>  		*pos++ = WLAN_EID_CHANNEL_SWITCH;
>  		*pos++ = 3;
>  		*pos++ = 0x0;
> @@ -760,6 +781,28 @@ ieee80211_mesh_build_beacon(struct
> ieee80211_if_mesh *ifmsh)
>  		pos += 2;
>  		put_unaligned_le16(ifmsh->pre_value, pos);
>  		pos += 2;
> +
> +		if (have_secondary_chan_offset) {
> +			enum nl80211_channel_type ct;

You can have one here, and re-initialize pos.

> +			*pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET;
> /* EID */
> +			*pos++ = 1;				 
>    /* len */
> +			ct = cfg80211_get_chandef_type(&csa-
> >settings.chandef);
> +			if (ct == NL80211_CHAN_HT40PLUS)
> +				*pos++ =
> IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
> +			else
> +				*pos++ =
> IEEE80211_HT_PARAM_CHA_SEC_BELOW;
> +		}
> +
> +		if (have_wide_bandwidth_cs) {
> +			struct cfg80211_chan_def *chandef;

and likewise here.

That'd also be safer in a way.

johannes

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/7] mac80211: mark as action frame when parsing IEs of CSA action frames
  2017-05-16  9:23 ` [PATCH 7/7] mac80211: mark as action frame when parsing IEs of CSA action frames Simon Wunderlich
@ 2017-05-19 11:35   ` Johannes Berg
  0 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2017-05-19 11:35 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: linux-wireless, benjamin

Applied this as well, I assume you don't want patch 6 in before 5.

johannes

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons
  2017-05-19 11:33   ` Johannes Berg
@ 2017-05-19 11:45     ` Simon Wunderlich
  2017-05-19 11:51       ` Johannes Berg
  0 siblings, 1 reply; 16+ messages in thread
From: Simon Wunderlich @ 2017-05-19 11:45 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, benjamin

[-- Attachment #1: Type: text/plain, Size: 1894 bytes --]

Hi Johannes,

On Friday, May 19, 2017 1:33:37 PM CEST Johannes Berg wrote:
> I've applied patches 1-4 now.
> 
> The subject is a bit long - I was going to change it to
> 
>     mac80211: mesh: support sending wide bandwidth CSA
>     
>     To support HT and VHT channel switch announcements, both beacons
>     and action frames must include the corresponding IEs.
> 
> but:
> > +		   2 + 2 + sizeof(struct
> > ieee80211_wide_bw_chansw_ie) +
> > +		   2 + sizeof(struct ieee80211_sec_chan_offs_ie) +
> 
> The "2 + 2" should have a comment - no that I'm even really sure that
> you need the wrapper?
> 

right, I'll add a comment. The spec says I need it, and if I understood the 
parsing function correctly it will only search for the wide bw IE when it finds 
the wrapper.

> > -		pos = skb_put(skb, 13);
> > -		memset(pos, 0, 13);
> 
> Removing that is nice - but why do you do this:
> > +		bool have_secondary_chan_offset = false;
> > +		bool have_wide_bandwidth_cs = false;
> > +		int ie_len = 2 + sizeof(struct
> > ieee80211_channel_sw_ie) +
> > +			     2 + sizeof(struct
> > ieee80211_mesh_chansw_params_ie);
> > +
> > +		switch (csa->settings.chandef.width) {
> > +		case NL80211_CHAN_WIDTH_80:
> > +		case NL80211_CHAN_WIDTH_80P80:
> > +		case NL80211_CHAN_WIDTH_160:
> > +			have_wide_bandwidth_cs = true;
> > +			ie_len += 2 + 2 +
> > +				  sizeof(struct
> > ieee80211_wide_bw_chansw_ie);
> > +			break;
> > +		case NL80211_CHAN_WIDTH_40:
> > +			have_secondary_chan_offset = true;
> > +			ie_len += 2 + sizeof(struct
> > ieee80211_sec_chan_offs_ie);
> > +		default:
> > +			break;
> > +		}
> > +		pos = skb_put(skb, ie_len);
> > +		memset(pos, 0, ie_len);
> 
> I think having multiple calls to skb_put() would be better.
> 

OK.

>[...]
> 
> and likewise here.
> 
> That'd also be safer in a way.

Understood, I can change it this way.

Thanks a lot for the feedback!
      Simon

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons
  2017-05-19 11:45     ` Simon Wunderlich
@ 2017-05-19 11:51       ` Johannes Berg
  0 siblings, 0 replies; 16+ messages in thread
From: Johannes Berg @ 2017-05-19 11:51 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: linux-wireless, benjamin

Hi,

> The spec says I need it, and if I understood the parsing function
> correctly it will only search for the wide bw IE when it finds the
> wrapper.

Yeah, I think there's some difference between action frames and beacons
though. You're only building the beacon here, so I think this is right.

johannes

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-05-19 11:51 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-16  9:23 [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Simon Wunderlich
2017-05-16  9:23 ` [PATCH 1/7] mac80211: Mark channel as unusable if a regulatory MESH CSA is received Simon Wunderlich
2017-05-16  9:23 ` [PATCH 2/7] wireless: Only join DFS channels in mesh mode if userspace flags support Simon Wunderlich
2017-05-16  9:23 ` [PATCH 3/7] wireless: Require HANDLE_DFS flag to switch channel for non-AP mode Simon Wunderlich
2017-05-16  9:23 ` [PATCH 4/7] mac80211: Allow following CSA to DFS channels if userspace handles it Simon Wunderlich
2017-05-16  9:23 ` [PATCH 5/7] mac80211: add wide bandwidth channel switch announcement to CSA action frames and mesh beacons Simon Wunderlich
2017-05-19 11:33   ` Johannes Berg
2017-05-19 11:45     ` Simon Wunderlich
2017-05-19 11:51       ` Johannes Berg
2017-05-16  9:23 ` [PATCH 6/7] mac80211: enable VHT for mesh channel processing Simon Wunderlich
2017-05-16  9:23 ` [PATCH 7/7] mac80211: mark as action frame when parsing IEs of CSA action frames Simon Wunderlich
2017-05-19 11:35   ` Johannes Berg
2017-05-16  9:44 ` [PATCH 0/7] extend mac80211 mesh DFS and CSA functionality Bastian Bittorf
2017-05-16 10:18   ` Simon Wunderlich
2017-05-16 11:55     ` Bastian Bittorf
2017-05-16 12:04       ` Simon Wunderlich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).