All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 2/2] mac80211_hwsim: allow configurable cipher types
       [not found] <20181017211624.7338-1-james.prestwood@linux.intel.com>
@ 2018-10-17 21:16 ` James Prestwood
  2018-10-25 17:50 ` [PATCH v3 1/2] mac80211_hwsim: allow setting iftype support James Prestwood
  1 sibling, 0 replies; 2+ messages in thread
From: James Prestwood @ 2018-10-17 21:16 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 2799eb247b7e..69596eb255d7 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,
@@ -2638,6 +2657,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);
@@ -3185,6 +3211,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 };
@@ -3267,6 +3316,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] 2+ messages in thread

* Re: [PATCH v3 1/2] mac80211_hwsim: allow setting iftype support
       [not found] <20181017211624.7338-1-james.prestwood@linux.intel.com>
  2018-10-17 21:16 ` [PATCH v3 2/2] mac80211_hwsim: allow configurable cipher types James Prestwood
@ 2018-10-25 17:50 ` James Prestwood
  1 sibling, 0 replies; 2+ messages in thread
From: James Prestwood @ 2018-10-25 17:50 UTC (permalink / raw)
  To: linux-wireless

Johannes,

Ping

On Wed, 2018-10-17 at 14:16 -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 that 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 | 153 +++++++++++++++---------
> --
>  drivers/net/wireless/mac80211_hwsim.h |   2 +
>  2 files changed, 90 insertions(+), 65 deletions(-)
> 
> diff --git a/drivers/net/wireless/mac80211_hwsim.c
> b/drivers/net/wireless/mac80211_hwsim.c
> index 18e819d964f1..2799eb247b7e 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,61 @@ 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.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.n_limits = n_limits;
> +	data->if_combination.max_interfaces = 2048;
> +	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 +2669,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 +3246,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] 2+ messages in thread

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

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20181017211624.7338-1-james.prestwood@linux.intel.com>
2018-10-17 21:16 ` [PATCH v3 2/2] mac80211_hwsim: allow configurable cipher types James Prestwood
2018-10-25 17:50 ` [PATCH v3 1/2] mac80211_hwsim: allow setting iftype support James Prestwood

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.