Commit 14f34e36 authored by Gurumoorthi Gnanasambandhan's avatar Gurumoorthi Gnanasambandhan Committed by Johannes Berg
Browse files

cfg80211: VLAN offload support for set_key and set_sta_vlan



This provides an alternative mechanism for AP VLAN support where a
single netdev is used with VLAN tagged frames instead of separate
netdevs for each VLAN without tagged frames from the WLAN driver.

By setting NL80211_EXT_FEATURE_VLAN_OFFLOAD flag the driver indicates
support for a single netdev with VLAN tagged frames. Separate
VLAN-specific netdevs can be added using RTM_NEWLINK/IFLA_VLAN_ID
similarly to Ethernet. NL80211_CMD_NEW_KEY (for group keys),
NL80211_CMD_NEW_STATION, and NL80211_CMD_SET_STATION will optionally
specify vlan_id using NL80211_ATTR_VLAN_ID.

Signed-off-by: default avatarGurumoorthi Gnanasambandhan <gguru@codeaurora.org>
Signed-off-by: default avatarJouni Malinen <jouni@codeaurora.org>
Link: https://lore.kernel.org/r/20191031214640.5012-1-jouni@codeaurora.org


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 6912daed
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -565,6 +565,7 @@ struct vif_params {
 *	with the get_key() callback, must be in little endian,
 *	length given by @seq_len.
 * @seq_len: length of @seq.
 * @vlan_id: vlan_id for VLAN group key (if nonzero)
 * @mode: key install mode (RX_TX, NO_TX or SET_TX)
 */
struct key_params {
@@ -572,6 +573,7 @@ struct key_params {
	const u8 *seq;
	int key_len;
	int seq_len;
	u16 vlan_id;
	u32 cipher;
	enum nl80211_key_mode mode;
};
@@ -1124,6 +1126,7 @@ struct sta_txpwr {
 *	(bitmask of BIT(%NL80211_STA_FLAG_...))
 * @listen_interval: listen interval or -1 for no change
 * @aid: AID or zero for no change
 * @vlan_id: VLAN ID for station (if nonzero)
 * @peer_aid: mesh peer AID or zero for no change
 * @plink_action: plink action to take
 * @plink_state: set the peer link state for a station
@@ -1159,6 +1162,7 @@ struct station_parameters {
	u32 sta_modify_mask;
	int listen_interval;
	u16 aid;
	u16 vlan_id;
	u16 peer_aid;
	u8 supported_rates_len;
	u8 plink_action;
+26 −0
Original line number Diff line number Diff line
@@ -248,6 +248,22 @@
 * %NL80211_ATTR_SAE_PASSWORD.
 */

/**
 * DOC: VLAN offload support for setting group keys and binding STAs to VLANs
 *
 * By setting @NL80211_EXT_FEATURE_VLAN_OFFLOAD flag drivers can indicate they
 * support offloading VLAN functionality in a manner where the driver exposes a
 * single netdev that uses VLAN tagged frames and separate VLAN-specific netdevs
 * can then be added using RTM_NEWLINK/IFLA_VLAN_ID similarly to the Ethernet
 * case. Frames received from stations that are not assigned to any VLAN are
 * delivered on the main netdev and frames to such stations can be sent through
 * that main netdev.
 *
 * %NL80211_CMD_NEW_KEY (for group keys), %NL80211_CMD_NEW_STATION, and
 * %NL80211_CMD_SET_STATION will optionally specify vlan_id using
 * %NL80211_ATTR_VLAN_ID.
 */

/**
 * enum nl80211_commands - supported nl80211 commands
 *
@@ -2381,6 +2397,9 @@ enum nl80211_commands {
 *	the allowed channel bandwidth configurations. (u8 attribute)
 *	Defined by IEEE P802.11ay/D4.0 section 9.4.2.251, Table 13.
 *
 * @NL80211_ATTR_VLAN_ID: VLAN ID (1..4094) for the station and VLAN group key
 *	(u16).
 *
 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 * @NL80211_ATTR_MAX: highest attribute number currently defined
 * @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2843,6 +2862,8 @@ enum nl80211_attrs {
	NL80211_ATTR_WIPHY_EDMG_CHANNELS,
	NL80211_ATTR_WIPHY_EDMG_BW_CONFIG,

	NL80211_ATTR_VLAN_ID,

	/* add attributes here, update the policy in nl80211.c */

	__NL80211_ATTR_AFTER_LAST,
@@ -5492,6 +5513,10 @@ enum nl80211_feature_flags {
 * @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
 *	station mode (SAE password is passed as part of the connect command).
 *
 * @NL80211_EXT_FEATURE_VLAN_OFFLOAD: The driver supports a single netdev
 *	with VLAN tagged frames and separate VLAN-specific netdevs added using
 *	vconfig similarly to the Ethernet case.
 *
 * @NUM_NL80211_EXT_FEATURES: number of extended features.
 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
 */
@@ -5537,6 +5562,7 @@ enum nl80211_ext_feature_index {
	NL80211_EXT_FEATURE_EXT_KEY_ID,
	NL80211_EXT_FEATURE_STA_TX_PWR,
	NL80211_EXT_FEATURE_SAE_OFFLOAD,
	NL80211_EXT_FEATURE_VLAN_OFFLOAD,

	/* add new features before the definition below */
	NUM_NL80211_EXT_FEATURES,
+11 −0
Original line number Diff line number Diff line
@@ -624,6 +624,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
					.len = SAE_PASSWORD_MAX_LEN },
	[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
	[NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
	[NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
};

/* policy for the key attributes */
@@ -3940,6 +3941,10 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
	    key.type != NL80211_KEYTYPE_GROUP)
		return -EINVAL;

	if (key.type == NL80211_KEYTYPE_GROUP &&
	    info->attrs[NL80211_ATTR_VLAN_ID])
		key.p.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);

	if (!rdev->ops->add_key)
		return -EOPNOTSUPP;

@@ -5711,6 +5716,9 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
	if (info->attrs[NL80211_ATTR_STA_AID])
		params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);

	if (info->attrs[NL80211_ATTR_VLAN_ID])
		params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);

	if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
		params.listen_interval =
		     nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
@@ -5856,6 +5864,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
	params.listen_interval =
		nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);

	if (info->attrs[NL80211_ATTR_VLAN_ID])
		params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);

	if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
		params.support_p2p_ps =
			nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);