linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Configuring iftype/cipher support
@ 2018-10-17 19:33 James Prestwood
  2018-10-17 19:33 ` [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support James Prestwood
  2018-10-17 19:33 ` [PATCH v2 2/2] mac80211_hwsim: allow configurable cipher types James Prestwood
  0 siblings, 2 replies; 10+ messages in thread
From: James Prestwood @ 2018-10-17 19:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: James Prestwood

This is V2 of my original patch, but a lot has changed:

- (extended) feature support has been completely removed due to
  (extended) features being set in core driver code. There was
  no way to set all (extended) features in JUST mac80211_hwsim.

- Iftype support was changed to a bit mask, and checks were added
  to ensure only iftypes that mac80211_hwsim already supported
  were allowed to be enabled/disabled. The interface limit rules
  are now built dynamically rather than being static structures.
  This was done because limit verification code complains if you
  have a limit rule for an iftype that you do not support.

- A new patch was added to allow supported ciphers to be configured.


James Prestwood (2):
  mac80211_hwsim: allow setting iftype support
  mac80211_hwsim: allow configurable cipher types

 drivers/net/wireless/mac80211_hwsim.c | 218 ++++++++++++++++++--------
 drivers/net/wireless/mac80211_hwsim.h |   4 +
 2 files changed, 156 insertions(+), 66 deletions(-)

-- 
2.17.1


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

* [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 19:33 [PATCH v2 0/2] Configuring iftype/cipher support James Prestwood
@ 2018-10-17 19:33 ` James Prestwood
  2018-10-17 19:43   ` James Prestwood
  2018-10-17 19:53   ` Johannes Berg
  2018-10-17 19:33 ` [PATCH v2 2/2] mac80211_hwsim: allow configurable cipher types James Prestwood
  1 sibling, 2 replies; 10+ messages in thread
From: James Prestwood @ 2018-10-17 19:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: James Prestwood

The mac80211_hwsim driver hard codes its supported interface types. For
testing purposes it would be valuable to allow changing these supported
types in order to simulate actual drivers than support a limited set of
iftypes. A new attribute was added to allow this:

- HWSIM_ATTR_IFTYPE_SUPPORT
	A u32 bit field of supported NL80211_IFTYPE_* bits

This will only enable/disable iftypes that mac80211_hwsim already
supports.

In order to accomplish this, the ieee80211_iface_limit structure needed
to be built dynamically to only include limit rules for iftypes that
the user requested to enable.

Signed-off-by: James Prestwood <james.prestwood@linux.intel.com>
---
 drivers/net/wireless/mac80211_hwsim.c | 154 +++++++++++++++-----------
 drivers/net/wireless/mac80211_hwsim.h |   2 +
 2 files changed, 90 insertions(+), 66 deletions(-)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 18e819d964f1..2e4dac2de187 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -448,48 +448,6 @@ static const struct nl80211_vendor_cmd_info mac80211_hwsim_vendor_events[] = {
 	{ .vendor_id = OUI_QCA, .subcmd = 1 },
 };
 
-static const struct ieee80211_iface_limit hwsim_if_limits[] = {
-	{ .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
-	{ .max = 2048,  .types = BIT(NL80211_IFTYPE_STATION) |
-				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
-#ifdef CONFIG_MAC80211_MESH
-				 BIT(NL80211_IFTYPE_MESH_POINT) |
-#endif
-				 BIT(NL80211_IFTYPE_AP) |
-				 BIT(NL80211_IFTYPE_P2P_GO) },
-	/* must be last, see hwsim_if_comb */
-	{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }
-};
-
-static const struct ieee80211_iface_combination hwsim_if_comb[] = {
-	{
-		.limits = hwsim_if_limits,
-		/* remove the last entry which is P2P_DEVICE */
-		.n_limits = ARRAY_SIZE(hwsim_if_limits) - 1,
-		.max_interfaces = 2048,
-		.num_different_channels = 1,
-		.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
-				       BIT(NL80211_CHAN_WIDTH_20) |
-				       BIT(NL80211_CHAN_WIDTH_40) |
-				       BIT(NL80211_CHAN_WIDTH_80) |
-				       BIT(NL80211_CHAN_WIDTH_160),
-	},
-};
-
-static const struct ieee80211_iface_combination hwsim_if_comb_p2p_dev[] = {
-	{
-		.limits = hwsim_if_limits,
-		.n_limits = ARRAY_SIZE(hwsim_if_limits),
-		.max_interfaces = 2048,
-		.num_different_channels = 1,
-		.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
-				       BIT(NL80211_CHAN_WIDTH_20) |
-				       BIT(NL80211_CHAN_WIDTH_40) |
-				       BIT(NL80211_CHAN_WIDTH_80) |
-				       BIT(NL80211_CHAN_WIDTH_160),
-	},
-};
-
 static spinlock_t hwsim_radio_lock;
 static LIST_HEAD(hwsim_radios);
 static struct workqueue_struct *hwsim_wq;
@@ -513,6 +471,8 @@ struct mac80211_hwsim_data {
 	struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
 	struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
 	struct ieee80211_iface_combination if_combination;
+	struct ieee80211_iface_limit if_limits[3];
+	int n_if_limits;
 
 	struct mac_address addresses[2];
 	int channels, idx;
@@ -641,6 +601,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
 	[HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
 	[HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
 	[HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
+	[HWSIM_ATTR_IFTYPE_SUPPORT] = { .type = NLA_U32 },
 };
 
 static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@ -2413,6 +2374,7 @@ struct hwsim_new_radio_params {
 	const char *hwname;
 	bool no_vif;
 	const u8 *perm_addr;
+	u32 iftypes;
 };
 
 static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
@@ -2517,6 +2479,29 @@ static void hwsim_mcast_new_radio(int id, struct genl_info *info,
 	nlmsg_free(mcast_skb);
 }
 
+#ifdef CONFIG_MAC80211_MESH
+#define HWSIM_MESH_BIT BIT(NL80211_IFTYPE_MESH_POINT)
+#else
+#define HWSIM_MESH_BIT 0
+#endif
+
+#define HWSIM_DEFAULT_IF_LIMIT \
+	( \
+		BIT(NL80211_IFTYPE_STATION) | \
+		BIT(NL80211_IFTYPE_P2P_CLIENT) | \
+		BIT(NL80211_IFTYPE_AP) | \
+		BIT(NL80211_IFTYPE_P2P_GO) | \
+		HWSIM_MESH_BIT \
+	)
+
+#define HWSIM_IFTYPE_SUPPORT_MASK \
+	BIT(NL80211_IFTYPE_STATION) | \
+	BIT(NL80211_IFTYPE_AP) | \
+	BIT(NL80211_IFTYPE_P2P_CLIENT) | \
+	BIT(NL80211_IFTYPE_P2P_GO) | \
+	BIT(NL80211_IFTYPE_ADHOC) | \
+	BIT(NL80211_IFTYPE_MESH_POINT)
+
 static int mac80211_hwsim_new_radio(struct genl_info *info,
 				    struct hwsim_new_radio_params *param)
 {
@@ -2528,6 +2513,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 	const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
 	struct net *net;
 	int idx;
+	int n_limits = 0;
 
 	if (WARN_ON(param->channels > 1 && !param->use_chanctx))
 		return -EINVAL;
@@ -2603,43 +2589,60 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 	if (info)
 		data->portid = info->snd_portid;
 
+	/* setup interface limits, only on interface types we support */
+	if (param->iftypes & BIT(NL80211_IFTYPE_ADHOC)) {
+		data->if_limits[n_limits].max = 1;
+		data->if_limits[n_limits].types = BIT(NL80211_IFTYPE_ADHOC);
+		n_limits++;
+	}
+
+	if (param->iftypes & HWSIM_DEFAULT_IF_LIMIT) {
+		data->if_limits[n_limits].max = 2048;
+		/*
+		 * For this case, we may only support a subset of
+		 * HWSIM_DEFAULT_IF_LIMIT, therefore we only want to add the
+		 * bits that both param->iftype & HWSIM_DEFAULT_IF_LIMIT have.
+		 */
+		data->if_limits[n_limits].types =
+					HWSIM_DEFAULT_IF_LIMIT & param->iftypes;
+		n_limits++;
+	}
+
+	if (param->iftypes & BIT(NL80211_IFTYPE_P2P_DEVICE)) {
+		data->if_limits[n_limits].max = 1;
+		data->if_limits[n_limits].types =
+						BIT(NL80211_IFTYPE_P2P_DEVICE);
+		n_limits++;
+	}
+
 	if (data->use_chanctx) {
 		hw->wiphy->max_scan_ssids = 255;
 		hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
 		hw->wiphy->max_remain_on_channel_duration = 1000;
-		hw->wiphy->iface_combinations = &data->if_combination;
-		if (param->p2p_device)
-			data->if_combination = hwsim_if_comb_p2p_dev[0];
-		else
-			data->if_combination = hwsim_if_comb[0];
-		hw->wiphy->n_iface_combinations = 1;
-		/* For channels > 1 DFS is not allowed */
 		data->if_combination.radar_detect_widths = 0;
 		data->if_combination.num_different_channels = data->channels;
-	} else if (param->p2p_device) {
-		hw->wiphy->iface_combinations = hwsim_if_comb_p2p_dev;
-		hw->wiphy->n_iface_combinations =
-			ARRAY_SIZE(hwsim_if_comb_p2p_dev);
-	} else {
-		hw->wiphy->iface_combinations = hwsim_if_comb;
-		hw->wiphy->n_iface_combinations = ARRAY_SIZE(hwsim_if_comb);
 	}
 
+	data->if_combination.n_limits = n_limits;
+	data->if_combination.max_interfaces = 2048;
+	data->if_combination.num_different_channels = 1;
+	data->if_combination.radar_detect_widths =
+					BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+					BIT(NL80211_CHAN_WIDTH_20) |
+					BIT(NL80211_CHAN_WIDTH_40) |
+					BIT(NL80211_CHAN_WIDTH_80) |
+					BIT(NL80211_CHAN_WIDTH_160);
+	data->if_combination.limits = data->if_limits;
+
+	hw->wiphy->iface_combinations = &data->if_combination;
+	hw->wiphy->n_iface_combinations = 1;
+
 	INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);
 	INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
 	INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
 
 	hw->queues = 5;
 	hw->offchannel_tx_hw_queue = 4;
-	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-				     BIT(NL80211_IFTYPE_AP) |
-				     BIT(NL80211_IFTYPE_P2P_CLIENT) |
-				     BIT(NL80211_IFTYPE_P2P_GO) |
-				     BIT(NL80211_IFTYPE_ADHOC) |
-				     BIT(NL80211_IFTYPE_MESH_POINT);
-
-	if (param->p2p_device)
-		hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
 
 	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
 	ieee80211_hw_set(hw, CHANCTX_STA_CSA);
@@ -2665,6 +2668,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 			       NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
 	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
 
+	hw->wiphy->interface_modes = param->iftypes;
+
 	/* ask mac80211 to reserve space for magic */
 	hw->vif_data_size = sizeof(struct hwsim_vif_priv);
 	hw->sta_data_size = sizeof(struct hwsim_sta_priv);
@@ -3240,10 +3245,27 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
 			return -EINVAL;
 		}
 
-
 		param.perm_addr = nla_data(info->attrs[HWSIM_ATTR_PERM_ADDR]);
 	}
 
+	if (info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]) {
+		param.iftypes = nla_get_u32(
+					info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]);
+		if (param.iftypes & ~(HWSIM_IFTYPE_SUPPORT_MASK)) {
+			NL_SET_BAD_ATTR(info->extack,
+					info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]);
+			return -EINVAL;
+		}
+	} else
+		param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
+
+	/* ensure both flag and iftype support is honored */
+	if (param.p2p_device ||
+			param.iftypes & BIT(NL80211_IFTYPE_P2P_DEVICE)) {
+		param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
+		param.p2p_device = true;
+	}
+
 	ret = mac80211_hwsim_new_radio(info, &param);
 	kfree(hwname);
 	return ret;
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index 0fe3199f8c72..3f6b670116d0 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -132,6 +132,7 @@ enum {
  * @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding
  *	rates of %HWSIM_ATTR_TX_INFO
  * @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
+ * @HWSIM_ATTR_IFTYPE_SUPPORT: u32 attribute of supported interface types bits
  * @__HWSIM_ATTR_MAX: enum limit
  */
 
@@ -160,6 +161,7 @@ enum {
 	HWSIM_ATTR_PAD,
 	HWSIM_ATTR_TX_INFO_FLAGS,
 	HWSIM_ATTR_PERM_ADDR,
+	HWSIM_ATTR_IFTYPE_SUPPORT,
 	__HWSIM_ATTR_MAX,
 };
 #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
-- 
2.17.1


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

* [PATCH v2 2/2] mac80211_hwsim: allow configurable cipher types
  2018-10-17 19:33 [PATCH v2 0/2] Configuring iftype/cipher support James Prestwood
  2018-10-17 19:33 ` [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support James Prestwood
@ 2018-10-17 19:33 ` James Prestwood
  1 sibling, 0 replies; 10+ messages in thread
From: James Prestwood @ 2018-10-17 19:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: James Prestwood

The mac80211_hwsim driver does not specify supported cipher types, which
in turn enables all ciphers to be supported in software. (see
net/mac80211/main.c:ieee80211_init_cipher_suites). Allowing ciphers
to be configurable is valuable for simulating older drivers that may
not support all ciphers.

This patch adds a new attribute:

 - HWSIM_ATTR_CIPHER_SUPPORT
	A u32 array/list of supported cipher types

This only allows enabling/disabling cipher types listed in the (new)
"hwsim_ciphers" array in mac80211_hwsim.c. Any unknown cipher type
will result in -EINVAL.

Signed-off-by: James Prestwood <james.prestwood@linux.intel.com>
---
 drivers/net/wireless/mac80211_hwsim.c | 64 +++++++++++++++++++++++++++
 drivers/net/wireless/mac80211_hwsim.h |  2 +
 2 files changed, 66 insertions(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 2e4dac2de187..b6b832a41286 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -371,6 +371,20 @@ static const struct ieee80211_rate hwsim_rates[] = {
 	{ .bitrate = 540 }
 };
 
+static const u32 hwsim_ciphers[] = {
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+	WLAN_CIPHER_SUITE_CCMP,
+	WLAN_CIPHER_SUITE_CCMP_256,
+	WLAN_CIPHER_SUITE_GCMP,
+	WLAN_CIPHER_SUITE_GCMP_256,
+	WLAN_CIPHER_SUITE_AES_CMAC,
+	WLAN_CIPHER_SUITE_BIP_CMAC_256,
+	WLAN_CIPHER_SUITE_BIP_GMAC_128,
+	WLAN_CIPHER_SUITE_BIP_GMAC_256,
+};
+
 #define OUI_QCA 0x001374
 #define QCA_NL80211_SUBCMD_TEST 1
 enum qca_nl80211_vendor_subcmds {
@@ -474,6 +488,8 @@ struct mac80211_hwsim_data {
 	struct ieee80211_iface_limit if_limits[3];
 	int n_if_limits;
 
+	u32 ciphers[ARRAY_SIZE(hwsim_ciphers)];
+
 	struct mac_address addresses[2];
 	int channels, idx;
 	bool use_chanctx;
@@ -602,6 +618,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
 	[HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
 	[HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len = ETH_ALEN },
 	[HWSIM_ATTR_IFTYPE_SUPPORT] = { .type = NLA_U32 },
+	[HWSIM_ATTR_CIPHER_SUPPORT] = { .type = NLA_BINARY },
 };
 
 static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
@@ -2375,6 +2392,8 @@ struct hwsim_new_radio_params {
 	bool no_vif;
 	const u8 *perm_addr;
 	u32 iftypes;
+	u32 *ciphers;
+	u8 n_ciphers;
 };
 
 static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
@@ -2637,6 +2656,13 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
 	hw->wiphy->iface_combinations = &data->if_combination;
 	hw->wiphy->n_iface_combinations = 1;
 
+	if (param->ciphers) {
+		memcpy(data->ciphers, param->ciphers,
+				param->n_ciphers * sizeof(u32));
+		hw->wiphy->cipher_suites = data->ciphers;
+		hw->wiphy->n_cipher_suites = param->n_ciphers;
+	}
+
 	INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);
 	INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
 	INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
@@ -3184,6 +3210,29 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2,
 	return 0;
 }
 
+/* ensures ciphers only include ciphers listed in 'hwsim_ciphers' array */
+static int hwsim_validate_ciphers(const u32 *ciphers, int n_ciphers)
+{
+	int i;
+
+	for (i = 0; i < n_ciphers; i++) {
+		int j;
+		int found = 0;
+
+		for (j = 0; j < ARRAY_SIZE(hwsim_ciphers); j++) {
+			if (ciphers[i] == hwsim_ciphers[j]) {
+				found = 1;
+				break;
+			}
+		}
+
+		if (!found)
+			return -1;
+	}
+
+	return 0;
+}
+
 static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
 {
 	struct hwsim_new_radio_params param = { 0 };
@@ -3266,6 +3315,21 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
 		param.p2p_device = true;
 	}
 
+	if (info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]) {
+		param.ciphers = nla_data(
+					info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]);
+		param.n_ciphers = nla_len(
+					info->attrs[HWSIM_ATTR_CIPHER_SUPPORT]);
+
+		if (param.n_ciphers > sizeof(hwsim_ciphers))
+			return -EINVAL;
+
+		param.n_ciphers /= sizeof(u32);
+
+		if (hwsim_validate_ciphers(param.ciphers, param.n_ciphers))
+			return -EINVAL;
+	}
+
 	ret = mac80211_hwsim_new_radio(info, &param);
 	kfree(hwname);
 	return ret;
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h
index 3f6b670116d0..a1ef8457fad4 100644
--- a/drivers/net/wireless/mac80211_hwsim.h
+++ b/drivers/net/wireless/mac80211_hwsim.h
@@ -133,6 +133,7 @@ enum {
  *	rates of %HWSIM_ATTR_TX_INFO
  * @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
  * @HWSIM_ATTR_IFTYPE_SUPPORT: u32 attribute of supported interface types bits
+ * @HWSIM_ATTR_CIPHER_SUPPORT: u32 array of supported cipher types
  * @__HWSIM_ATTR_MAX: enum limit
  */
 
@@ -162,6 +163,7 @@ enum {
 	HWSIM_ATTR_TX_INFO_FLAGS,
 	HWSIM_ATTR_PERM_ADDR,
 	HWSIM_ATTR_IFTYPE_SUPPORT,
+	HWSIM_ATTR_CIPHER_SUPPORT,
 	__HWSIM_ATTR_MAX,
 };
 #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
-- 
2.17.1


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

* Re: [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 19:33 ` [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support James Prestwood
@ 2018-10-17 19:43   ` James Prestwood
  2018-10-17 19:53   ` Johannes Berg
  1 sibling, 0 replies; 10+ messages in thread
From: James Prestwood @ 2018-10-17 19:43 UTC (permalink / raw)
  To: linux-wireless

On Wed, 2018-10-17 at 12:33 -0700, James Prestwood wrote:
> The mac80211_hwsim driver hard codes its supported interface types.
> For
> testing purposes it would be valuable to allow changing these
> supported
> types in order to simulate actual drivers than support a limited set
> of
> iftypes. A new attribute was added to allow this:
> 
> - HWSIM_ATTR_IFTYPE_SUPPORT
> 	A u32 bit field of supported NL80211_IFTYPE_* bits
> 
> This will only enable/disable iftypes that mac80211_hwsim already
> supports.
> 
> In order to accomplish this, the ieee80211_iface_limit structure
> needed
> to be built dynamically to only include limit rules for iftypes that
> the user requested to enable.
> 
> Signed-off-by: James Prestwood <james.prestwood@linux.intel.com>
> ---
>  drivers/net/wireless/mac80211_hwsim.c | 154 +++++++++++++++---------
> --
>  drivers/net/wireless/mac80211_hwsim.h |   2 +
>  2 files changed, 90 insertions(+), 66 deletions(-)
> 
> diff --git a/drivers/net/wireless/mac80211_hwsim.c
> b/drivers/net/wireless/mac80211_hwsim.c
> index 18e819d964f1..2e4dac2de187 100644
> --- a/drivers/net/wireless/mac80211_hwsim.c
> +++ b/drivers/net/wireless/mac80211_hwsim.c
> @@ -448,48 +448,6 @@ static const struct nl80211_vendor_cmd_info
> mac80211_hwsim_vendor_events[] = {
>  	{ .vendor_id = OUI_QCA, .subcmd = 1 },
>  };
>  
> -static const struct ieee80211_iface_limit hwsim_if_limits[] = {
> -	{ .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
> -	{ .max = 2048,  .types = BIT(NL80211_IFTYPE_STATION) |
> -				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
> -#ifdef CONFIG_MAC80211_MESH
> -				 BIT(NL80211_IFTYPE_MESH_POINT) |
> -#endif
> -				 BIT(NL80211_IFTYPE_AP) |
> -				 BIT(NL80211_IFTYPE_P2P_GO) },
> -	/* must be last, see hwsim_if_comb */
> -	{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }
> -};
> -
> -static const struct ieee80211_iface_combination hwsim_if_comb[] = {
> -	{
> -		.limits = hwsim_if_limits,
> -		/* remove the last entry which is P2P_DEVICE */
> -		.n_limits = ARRAY_SIZE(hwsim_if_limits) - 1,
> -		.max_interfaces = 2048,
> -		.num_different_channels = 1,
> -		.radar_detect_widths =
> BIT(NL80211_CHAN_WIDTH_20_NOHT) |
> -				       BIT(NL80211_CHAN_WIDTH_20) |
> -				       BIT(NL80211_CHAN_WIDTH_40) |
> -				       BIT(NL80211_CHAN_WIDTH_80) |
> -				       BIT(NL80211_CHAN_WIDTH_160),
> -	},
> -};
> -
> -static const struct ieee80211_iface_combination
> hwsim_if_comb_p2p_dev[] = {
> -	{
> -		.limits = hwsim_if_limits,
> -		.n_limits = ARRAY_SIZE(hwsim_if_limits),
> -		.max_interfaces = 2048,
> -		.num_different_channels = 1,
> -		.radar_detect_widths =
> BIT(NL80211_CHAN_WIDTH_20_NOHT) |
> -				       BIT(NL80211_CHAN_WIDTH_20) |
> -				       BIT(NL80211_CHAN_WIDTH_40) |
> -				       BIT(NL80211_CHAN_WIDTH_80) |
> -				       BIT(NL80211_CHAN_WIDTH_160),
> -	},
> -};
> -
>  static spinlock_t hwsim_radio_lock;
>  static LIST_HEAD(hwsim_radios);
>  static struct workqueue_struct *hwsim_wq;
> @@ -513,6 +471,8 @@ struct mac80211_hwsim_data {
>  	struct ieee80211_channel
> channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)];
>  	struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
>  	struct ieee80211_iface_combination if_combination;
> +	struct ieee80211_iface_limit if_limits[3];
> +	int n_if_limits;
>  
>  	struct mac_address addresses[2];
>  	int channels, idx;
> @@ -641,6 +601,7 @@ static const struct nla_policy
> hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = {
>  	[HWSIM_ATTR_NO_VIF] = { .type = NLA_FLAG },
>  	[HWSIM_ATTR_FREQ] = { .type = NLA_U32 },
>  	[HWSIM_ATTR_PERM_ADDR] = { .type = NLA_UNSPEC, .len =
> ETH_ALEN },
> +	[HWSIM_ATTR_IFTYPE_SUPPORT] = { .type = NLA_U32 },
>  };
>  
>  static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
> @@ -2413,6 +2374,7 @@ struct hwsim_new_radio_params {
>  	const char *hwname;
>  	bool no_vif;
>  	const u8 *perm_addr;
> +	u32 iftypes;
>  };
>  
>  static void hwsim_mcast_config_msg(struct sk_buff *mcast_skb,
> @@ -2517,6 +2479,29 @@ static void hwsim_mcast_new_radio(int id,
> struct genl_info *info,
>  	nlmsg_free(mcast_skb);
>  }
>  
> +#ifdef CONFIG_MAC80211_MESH
> +#define HWSIM_MESH_BIT BIT(NL80211_IFTYPE_MESH_POINT)
> +#else
> +#define HWSIM_MESH_BIT 0
> +#endif
> +
> +#define HWSIM_DEFAULT_IF_LIMIT \
> +	( \
> +		BIT(NL80211_IFTYPE_STATION) | \
> +		BIT(NL80211_IFTYPE_P2P_CLIENT) | \
> +		BIT(NL80211_IFTYPE_AP) | \
> +		BIT(NL80211_IFTYPE_P2P_GO) | \
> +		HWSIM_MESH_BIT \
> +	)
> +
> +#define HWSIM_IFTYPE_SUPPORT_MASK \
> +	BIT(NL80211_IFTYPE_STATION) | \
> +	BIT(NL80211_IFTYPE_AP) | \
> +	BIT(NL80211_IFTYPE_P2P_CLIENT) | \
> +	BIT(NL80211_IFTYPE_P2P_GO) | \
> +	BIT(NL80211_IFTYPE_ADHOC) | \
> +	BIT(NL80211_IFTYPE_MESH_POINT)
> +
>  static int mac80211_hwsim_new_radio(struct genl_info *info,
>  				    struct hwsim_new_radio_params
> *param)
>  {
> @@ -2528,6 +2513,7 @@ static int mac80211_hwsim_new_radio(struct
> genl_info *info,
>  	const struct ieee80211_ops *ops = &mac80211_hwsim_ops;
>  	struct net *net;
>  	int idx;
> +	int n_limits = 0;
>  
>  	if (WARN_ON(param->channels > 1 && !param->use_chanctx))
>  		return -EINVAL;
> @@ -2603,43 +2589,60 @@ static int mac80211_hwsim_new_radio(struct
> genl_info *info,
>  	if (info)
>  		data->portid = info->snd_portid;
>  
> +	/* setup interface limits, only on interface types we
> support */
> +	if (param->iftypes & BIT(NL80211_IFTYPE_ADHOC)) {
> +		data->if_limits[n_limits].max = 1;
> +		data->if_limits[n_limits].types =
> BIT(NL80211_IFTYPE_ADHOC);
> +		n_limits++;
> +	}
> +
> +	if (param->iftypes & HWSIM_DEFAULT_IF_LIMIT) {
> +		data->if_limits[n_limits].max = 2048;
> +		/*
> +		 * For this case, we may only support a subset of
> +		 * HWSIM_DEFAULT_IF_LIMIT, therefore we only want to
> add the
> +		 * bits that both param->iftype &
> HWSIM_DEFAULT_IF_LIMIT have.
> +		 */
> +		data->if_limits[n_limits].types =
> +					HWSIM_DEFAULT_IF_LIMIT &
> param->iftypes;
> +		n_limits++;
> +	}
> +
> +	if (param->iftypes & BIT(NL80211_IFTYPE_P2P_DEVICE)) {
> +		data->if_limits[n_limits].max = 1;
> +		data->if_limits[n_limits].types =
> +						BIT(NL80211_IFTYPE_P
> 2P_DEVICE);
> +		n_limits++;
> +	}
> +
>  	if (data->use_chanctx) {
>  		hw->wiphy->max_scan_ssids = 255;
>  		hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
>  		hw->wiphy->max_remain_on_channel_duration = 1000;
> -		hw->wiphy->iface_combinations = &data-
> >if_combination;
> -		if (param->p2p_device)
> -			data->if_combination =
> hwsim_if_comb_p2p_dev[0];
> -		else
> -			data->if_combination = hwsim_if_comb[0];
> -		hw->wiphy->n_iface_combinations = 1;
> -		/* For channels > 1 DFS is not allowed */
>  		data->if_combination.radar_detect_widths = 0;
>  		data->if_combination.num_different_channels = data-
> >channels;
> -	} else if (param->p2p_device) {
> -		hw->wiphy->iface_combinations =
> hwsim_if_comb_p2p_dev;
> -		hw->wiphy->n_iface_combinations =
> -			ARRAY_SIZE(hwsim_if_comb_p2p_dev);
> -	} else {
> -		hw->wiphy->iface_combinations = hwsim_if_comb;
> -		hw->wiphy->n_iface_combinations =
> ARRAY_SIZE(hwsim_if_comb);
>  	}
>  
> +	data->if_combination.n_limits = n_limits;
> +	data->if_combination.max_interfaces = 2048;
> +	data->if_combination.num_different_channels = 1;
> +	data->if_combination.radar_detect_widths =
> +					BIT(NL80211_CHAN_WIDTH_20_NO
> HT) |
> +					BIT(NL80211_CHAN_WIDTH_20) |
> +					BIT(NL80211_CHAN_WIDTH_40) |
> +					BIT(NL80211_CHAN_WIDTH_80) |
> +					BIT(NL80211_CHAN_WIDTH_160);
I just realized this changes how the old code worked. In the
use_chanctx case we want radar_detect_widths to be set to zero and
num_different_channels set to data->channels. These two lines needs to
be surrounded in an if (!data->use_chanctx) block. 
> +	data->if_combination.limits = data->if_limits;
> +
> +	hw->wiphy->iface_combinations = &data->if_combination;
> +	hw->wiphy->n_iface_combinations = 1;
> +
>  	INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);
>  	INIT_DELAYED_WORK(&data->roc_done, hw_roc_done);
>  	INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work);
>  
>  	hw->queues = 5;
>  	hw->offchannel_tx_hw_queue = 4;
> -	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
> -				     BIT(NL80211_IFTYPE_AP) |
> -				     BIT(NL80211_IFTYPE_P2P_CLIENT)
> |
> -				     BIT(NL80211_IFTYPE_P2P_GO) |
> -				     BIT(NL80211_IFTYPE_ADHOC) |
> -				     BIT(NL80211_IFTYPE_MESH_POINT);
> -
> -	if (param->p2p_device)
> -		hw->wiphy->interface_modes |=
> BIT(NL80211_IFTYPE_P2P_DEVICE);
>  
>  	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
>  	ieee80211_hw_set(hw, CHANCTX_STA_CSA);
> @@ -2665,6 +2668,8 @@ static int mac80211_hwsim_new_radio(struct
> genl_info *info,
>  			       NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
>  	wiphy_ext_feature_set(hw->wiphy,
> NL80211_EXT_FEATURE_VHT_IBSS);
>  
> +	hw->wiphy->interface_modes = param->iftypes;
> +
>  	/* ask mac80211 to reserve space for magic */
>  	hw->vif_data_size = sizeof(struct hwsim_vif_priv);
>  	hw->sta_data_size = sizeof(struct hwsim_sta_priv);
> @@ -3240,10 +3245,27 @@ static int hwsim_new_radio_nl(struct sk_buff
> *msg, struct genl_info *info)
>  			return -EINVAL;
>  		}
>  
> -
>  		param.perm_addr = nla_data(info-
> >attrs[HWSIM_ATTR_PERM_ADDR]);
>  	}
>  
> +	if (info->attrs[HWSIM_ATTR_IFTYPE_SUPPORT]) {
> +		param.iftypes = nla_get_u32(
> +					info-
> >attrs[HWSIM_ATTR_IFTYPE_SUPPORT]);
> +		if (param.iftypes & ~(HWSIM_IFTYPE_SUPPORT_MASK)) {
> +			NL_SET_BAD_ATTR(info->extack,
> +					info-
> >attrs[HWSIM_ATTR_IFTYPE_SUPPORT]);
> +			return -EINVAL;
> +		}
> +	} else
> +		param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
> +
> +	/* ensure both flag and iftype support is honored */
> +	if (param.p2p_device ||
> +			param.iftypes &
> BIT(NL80211_IFTYPE_P2P_DEVICE)) {
> +		param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
> +		param.p2p_device = true;
> +	}
> +
>  	ret = mac80211_hwsim_new_radio(info, &param);
>  	kfree(hwname);
>  	return ret;
> diff --git a/drivers/net/wireless/mac80211_hwsim.h
> b/drivers/net/wireless/mac80211_hwsim.h
> index 0fe3199f8c72..3f6b670116d0 100644
> --- a/drivers/net/wireless/mac80211_hwsim.h
> +++ b/drivers/net/wireless/mac80211_hwsim.h
> @@ -132,6 +132,7 @@ enum {
>   * @HWSIM_ATTR_TX_INFO_FLAGS: additional flags for corresponding
>   *	rates of %HWSIM_ATTR_TX_INFO
>   * @HWSIM_ATTR_PERM_ADDR: permanent mac address of new radio
> + * @HWSIM_ATTR_IFTYPE_SUPPORT: u32 attribute of supported interface
> types bits
>   * @__HWSIM_ATTR_MAX: enum limit
>   */
>  
> @@ -160,6 +161,7 @@ enum {
>  	HWSIM_ATTR_PAD,
>  	HWSIM_ATTR_TX_INFO_FLAGS,
>  	HWSIM_ATTR_PERM_ADDR,
> +	HWSIM_ATTR_IFTYPE_SUPPORT,
>  	__HWSIM_ATTR_MAX,
>  };
>  #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)

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

* Re: [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 19:33 ` [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support James Prestwood
  2018-10-17 19:43   ` James Prestwood
@ 2018-10-17 19:53   ` Johannes Berg
  2018-10-17 21:00     ` James Prestwood
  1 sibling, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2018-10-17 19:53 UTC (permalink / raw)
  To: James Prestwood, linux-wireless

On Wed, 2018-10-17 at 12:33 -0700, James Prestwood wrote:
> The mac80211_hwsim driver hard codes its supported interface types. For
> testing purposes it would be valuable to allow changing these supported
> types in order to simulate actual drivers than support a limited set of

typo: than -> that

> In order to accomplish this, the ieee80211_iface_limit structure needed
> to be built dynamically to only include limit rules for iftypes that
> the user requested to enable.

That makes me wonder if you'd also want to support limiting the # of
interfaces/channels to mimic another device?

johannes


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

* Re: [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 21:00     ` James Prestwood
@ 2018-10-17 20:58       ` Johannes Berg
  2018-10-17 21:05         ` James Prestwood
  0 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2018-10-17 20:58 UTC (permalink / raw)
  To: James Prestwood, linux-wireless

On Wed, 2018-10-17 at 14:00 -0700, James Prestwood wrote:
> 
> > That makes me wonder if you'd also want to support limiting the # of
> > interfaces/channels to mimic another device?
> 
> Yeah it seems like it would be pretty easy to add that on top of this
> change, although I don't really see us actually using it.

Sure, fair enough.

> I can add it,
> but my only concern is I would not test it up to the same level I
> tested iftype/ciphers. 

If you don't really want to use it, then I don't think you need to add
it. I was just wondering if it made a difference.

> Maybe this is also because I am not entirely
> sure what num_different_channels is doing. Is this only relevant when
> multiple interfaces exist on a radio? Like setting how many channels
> can be use simultaneously?

Correct. "Simultaneously" is a bit of an overstatement, typically today
it's implemented by TDM - if you have two interfaces with a connection
to an AP each, but on different channels, each interface would just tell
its AP that it's going to sleep, but instead hop to the other channel
and tell that AP that it woke up... etc.

johannes


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

* Re: [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 19:53   ` Johannes Berg
@ 2018-10-17 21:00     ` James Prestwood
  2018-10-17 20:58       ` Johannes Berg
  0 siblings, 1 reply; 10+ messages in thread
From: James Prestwood @ 2018-10-17 21:00 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless

On Wed, 2018-10-17 at 21:53 +0200, Johannes Berg wrote:
> On Wed, 2018-10-17 at 12:33 -0700, James Prestwood wrote:
> > The mac80211_hwsim driver hard codes its supported interface types.
> > For
> > testing purposes it would be valuable to allow changing these
> > supported
> > types in order to simulate actual drivers than support a limited
> > set of
> 
> typo: than -> that
> 
> > In order to accomplish this, the ieee80211_iface_limit structure
> > needed
> > to be built dynamically to only include limit rules for iftypes
> > that
> > the user requested to enable.
> 
> That makes me wonder if you'd also want to support limiting the # of
> interfaces/channels to mimic another device?

Yeah it seems like it would be pretty easy to add that on top of this
change, although I don't really see us actually using it. I can add it,
but my only concern is I would not test it up to the same level I
tested iftype/ciphers. Maybe this is also because I am not entirely
sure what num_different_channels is doing. Is this only relevant when
multiple interfaces exist on a radio? Like setting how many channels
can be use simultaneously?

> 
> johannes
> 

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

* Re: [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 20:58       ` Johannes Berg
@ 2018-10-17 21:05         ` James Prestwood
  2018-10-17 21:08           ` Johannes Berg
  0 siblings, 1 reply; 10+ messages in thread
From: James Prestwood @ 2018-10-17 21:05 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless

On Wed, 2018-10-17 at 22:58 +0200, Johannes Berg wrote:
> On Wed, 2018-10-17 at 14:00 -0700, James Prestwood wrote:
> > 
> > > That makes me wonder if you'd also want to support limiting the #
> > > of
> > > interfaces/channels to mimic another device?
> > 
> > Yeah it seems like it would be pretty easy to add that on top of
> > this
> > change, although I don't really see us actually using it.
> 
> Sure, fair enough.
> 
> > I can add it,
> > but my only concern is I would not test it up to the same level I
> > tested iftype/ciphers. 
> 
> If you don't really want to use it, then I don't think you need to
> add
> it. I was just wondering if it made a difference.
> 
> > Maybe this is also because I am not entirely
> > sure what num_different_channels is doing. Is this only relevant
> > when
> > multiple interfaces exist on a radio? Like setting how many
> > channels
> > can be use simultaneously?
> 
> Correct. "Simultaneously" is a bit of an overstatement, typically
> today
> it's implemented by TDM - if you have two interfaces with a
> connection
> to an AP each, but on different channels, each interface would just
> tell
> its AP that it's going to sleep, but instead hop to the other channel
> and tell that AP that it woke up... etc.

Ah ok, that makes sense. Ok, well I can fixup that typo, as well as
reordering the use_chanctx stuff I mentioned. Unless there was anything
else? If not I can submit v3.

> 
> johannes
> 

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

* Re: [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 21:05         ` James Prestwood
@ 2018-10-17 21:08           ` Johannes Berg
  2018-10-17 21:15             ` James Prestwood
  0 siblings, 1 reply; 10+ messages in thread
From: Johannes Berg @ 2018-10-17 21:08 UTC (permalink / raw)
  To: James Prestwood, linux-wireless


> Ah ok, that makes sense. Ok, well I can fixup that typo, as well as
> reordering the use_chanctx stuff I mentioned. Unless there was anything
> else? If not I can submit v3.

I haven't really looked at it much yet, it's 11pm here and I'm tired :-)

Feel free to resubmit, but I'm not going to promise I won't make you
submit v4 if you do ;-)

johannes


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

* Re: [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support
  2018-10-17 21:08           ` Johannes Berg
@ 2018-10-17 21:15             ` James Prestwood
  0 siblings, 0 replies; 10+ messages in thread
From: James Prestwood @ 2018-10-17 21:15 UTC (permalink / raw)
  To: Johannes Berg, linux-wireless

On Wed, 2018-10-17 at 23:08 +0200, Johannes Berg wrote:
> > Ah ok, that makes sense. Ok, well I can fixup that typo, as well as
> > reordering the use_chanctx stuff I mentioned. Unless there was
> > anything
> > else? If not I can submit v3.
> 
> I haven't really looked at it much yet, it's 11pm here and I'm tired
> :-)
> 
> Feel free to resubmit, but I'm not going to promise I won't make you
> submit v4 if you do ;-)

Ha, ok no problem. Ill submit v3 now.

Thanks,
james

> 
> johannes
> 

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

end of thread, other threads:[~2018-10-17 21:11 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-17 19:33 [PATCH v2 0/2] Configuring iftype/cipher support James Prestwood
2018-10-17 19:33 ` [PATCH v2 1/2] mac80211_hwsim: allow setting iftype support James Prestwood
2018-10-17 19:43   ` James Prestwood
2018-10-17 19:53   ` Johannes Berg
2018-10-17 21:00     ` James Prestwood
2018-10-17 20:58       ` Johannes Berg
2018-10-17 21:05         ` James Prestwood
2018-10-17 21:08           ` Johannes Berg
2018-10-17 21:15             ` James Prestwood
2018-10-17 19:33 ` [PATCH v2 2/2] mac80211_hwsim: allow configurable cipher types James Prestwood

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).