Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a0e1059 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cfg80211: indicate support for DH IE update"

parents eed7e23f 1806f9fa
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -67,6 +67,12 @@
/* Indicate backport support for processing user cell base hint */
#define CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED 1

/* Indicate backport support for external authentication in AP mode */
#define CFG80211_EXTERNAL_AUTH_AP_SUPPORT 1

/* Indicate backport support for DH IE creation/update*/
#define CFG80211_EXTERNAL_DH_UPDATE_SUPPORT 1

/**
 * DOC: Introduction
 *
@@ -738,6 +744,17 @@ struct cfg80211_bitrate_mask {
	} control[NUM_NL80211_BANDS];
};

/**
 * enum cfg80211_ap_settings_flags - AP settings flags
 *
 * Used by cfg80211_ap_settings
 *
 * @AP_SETTINGS_EXTERNAL_AUTH_SUPPORT: AP supports external authentication
 */
enum cfg80211_ap_settings_flags {
	AP_SETTINGS_EXTERNAL_AUTH_SUPPORT = BIT(0),
};

/**
 * struct cfg80211_ap_settings - AP configuration
 *
@@ -763,6 +780,7 @@ struct cfg80211_bitrate_mask {
 * @pbss: If set, start as a PCP instead of AP. Relevant for DMG
 *	networks.
 * @beacon_rate: bitrate to be used for beacons
 * @flags: flags, as defined in enum cfg80211_ap_settings_flags
 */
struct cfg80211_ap_settings {
	struct cfg80211_chan_def chandef;
@@ -783,6 +801,7 @@ struct cfg80211_ap_settings {
	const struct cfg80211_acl_data *acl;
	bool pbss;
	struct cfg80211_bitrate_mask beacon_rate;
	u32 flags;
};

/**
@@ -2582,6 +2601,7 @@ struct cfg80211_nan_func {
 *	use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space cannot give you
 *	the real status code for failures. Used only for the authentication
 *	response command interface (user space to driver).
 * @pmkid: The identifier to refer a PMKSA.
 */
struct cfg80211_external_auth_params {
	enum nl80211_external_auth_action action;
@@ -2589,6 +2609,33 @@ struct cfg80211_external_auth_params {
	struct cfg80211_ssid ssid;
	unsigned int key_mgmt_suite;
	u16 status;
	const u8 *pmkid;
};

/**
 * struct cfg80211_update_owe_info - OWE Information
 *
 * This structure provides information needed for the drivers to offload OWE
 * (Opportunistic Wireless Encryption) processing to the user space.
 *
 * Commonly used across update_owe_info request and event interfaces.
 *
 * @peer: MAC address of the peer device for which the OWE processing
 *	has to be done.
 * @status: status code, %WLAN_STATUS_SUCCESS for successful OWE info
 *	processing, use %WLAN_STATUS_UNSPECIFIED_FAILURE if user space
 *	cannot give you the real status code for failures. Used only for
 *	OWE update request command interface (user space to driver).
 * @ie: IEs obtained from the peer or constructed by the user space. These are
 *	the IEs of the remote peer in the event from the host driver and
 *	the constructed IEs by the user space in the request interface.
 * @ie_len: Length of IEs in octets.
 */
struct cfg80211_update_owe_info {
	u8 peer[ETH_ALEN] __aligned(2);
	u16 status;
	const u8 *ie;
	size_t ie_len;
};

/**
@@ -2903,6 +2950,10 @@ struct cfg80211_external_auth_params {
 *
 * @external_auth: indicates result of offloaded authentication processing from
 *     user space
 *
 * @update_owe_info: Provide updated OWE info to driver. Driver implementing SME
 *	but offloading OWE processing to the user space will get the updated
 *	DH IE through this interface.
 */
struct cfg80211_ops {
	int	(*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -3189,6 +3240,8 @@ struct cfg80211_ops {
					    const bool enabled);
	int     (*external_auth)(struct wiphy *wiphy, struct net_device *dev,
				 struct cfg80211_external_auth_params *params);
	int	(*update_owe_info)(struct wiphy *wiphy, struct net_device *dev,
				   struct cfg80211_update_owe_info *owe_info);
};

/*
@@ -6185,4 +6238,14 @@ int cfg80211_external_auth_request(struct net_device *netdev,
#define wiphy_WARN(wiphy, format, args...)			\
	WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args);

/**
 * cfg80211_update_owe_info_event - Notify the peer's OWE info to user space
 * @netdev: network device
 * @owe_info: peer's owe info
 * @gfp: allocation flags
 */
void cfg80211_update_owe_info_event(struct net_device *netdev,
				    struct cfg80211_update_owe_info *owe_info,
				    gfp_t gfp);

#endif /* __NET_CFG80211_H */
+16 −4
Original line number Diff line number Diff line
@@ -1018,6 +1018,11 @@
 *	indicated by %NL80211_ATTR_WIPHY_FREQ and other attributes
 *	determining the width and type.
 *
 * @NL80211_CMD_UPDATE_OWE_INFO: This interface allows the host driver to
 *	offload OWE processing to user space. This intends to support
 *	OWE AKM by the host drivers that implement SME but rely
 *	on the user space for the cryptographic/DH IE processing in AP mode.
 *
 * @NL80211_CMD_MAX: highest used command number
 * @__NL80211_CMD_AFTER_LAST: internal use
 */
@@ -1238,6 +1243,8 @@ enum nl80211_commands {

	NL80211_CMD_NOTIFY_RADAR,

	NL80211_CMD_UPDATE_OWE_INFO,

	/* add new commands above here */

	/* used to define NL80211_CMD_MAX below */
@@ -2180,9 +2187,9 @@ enum nl80211_commands {
 *     &NL80211_CMD_EXTERNAL_AUTH request event.
 * @NL80211_ATTR_EXTERNAL_AUTH_SUPPORT: Flag attribute indicating that the user
 *	space supports external authentication. This attribute shall be used
 *     only with %NL80211_CMD_CONNECT request. The driver may offload
 *     authentication processing to user space if this capability is indicated
 *     in NL80211_CMD_CONNECT requests from the user space.
 *	with %NL80211_CMD_CONNECT and %NL80211_CMD_START_AP request. The driver
 *	may offload authentication processing to user space if this capability
 *	is indicated in the respective requests from the user space.
 *
 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
 * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -5264,9 +5271,14 @@ enum nl80211_crit_proto_id {
 * Used by cfg80211_rx_mgmt()
 *
 * @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver.
 * @NL80211_RXMGMT_FLAG_EXTERNAL_AUTH: Host driver intends to offload
 *	the authentication. Exclusively defined for host drivers that
 *	advertises the SME functionality but would like the userspace
 *	to handle certain authentication algorithms (e.g. SAE).
 */
enum nl80211_rxmgmt_flags {
	NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0,
	NL80211_RXMGMT_FLAG_EXTERNAL_AUTH = 1 << 1,
};

/*
+90 −7
Original line number Diff line number Diff line
@@ -3989,6 +3989,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
			return PTR_ERR(params.acl);
	}

	if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
		params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;

	wdev_lock(wdev);
	err = rdev_start_ap(rdev, dev, &params);
	if (!err) {
@@ -12055,7 +12058,9 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
	if (!rdev->ops->external_auth)
		return -EOPNOTSUPP;

	if (!info->attrs[NL80211_ATTR_SSID])
	if (!info->attrs[NL80211_ATTR_SSID] &&
	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
	    dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
		return -EINVAL;

	if (!info->attrs[NL80211_ATTR_BSSID])
@@ -12066,21 +12071,52 @@ static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)

	memset(&params, 0, sizeof(params));

	if (info->attrs[NL80211_ATTR_SSID]) {
		params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
		if (params.ssid.ssid_len == 0 ||
		    params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
			return -EINVAL;
	memcpy(params.ssid.ssid, nla_data(info->attrs[NL80211_ATTR_SSID]),
		memcpy(params.ssid.ssid,
		       nla_data(info->attrs[NL80211_ATTR_SSID]),
		       params.ssid.ssid_len);
	}

	memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
	       ETH_ALEN);

	params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);

	if (info->attrs[NL80211_ATTR_PMKID])
		params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);

	return rdev_external_auth(rdev, dev, &params);
}

static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
{
	struct cfg80211_registered_device *rdev = info->user_ptr[0];
	struct cfg80211_update_owe_info owe_info;
	struct net_device *dev = info->user_ptr[1];

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

	if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
	    !info->attrs[NL80211_ATTR_MAC])
		return -EINVAL;

	memset(&owe_info, 0, sizeof(owe_info));
	owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
	nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);

	if (info->attrs[NL80211_ATTR_IE]) {
		owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
		owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
	}

	return rdev_update_owe_info(rdev, dev, &owe_info);
}

#define NL80211_FLAG_NEED_WIPHY		0x01
#define NL80211_FLAG_NEED_NETDEV	0x02
#define NL80211_FLAG_NEED_RTNL		0x04
@@ -12978,6 +13014,13 @@ static const struct genl_ops nl80211_ops[] = {
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
	{
		.cmd = NL80211_CMD_UPDATE_OWE_INFO,
		.doit = nl80211_update_owe_info,
		.flags = GENL_ADMIN_PERM,
		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
				  NL80211_FLAG_NEED_RTNL,
	},
};

/* notification functions */
@@ -15018,6 +15061,46 @@ int cfg80211_external_auth_request(struct net_device *dev,
}
EXPORT_SYMBOL(cfg80211_external_auth_request);

void cfg80211_update_owe_info_event(struct net_device *netdev,
				    struct cfg80211_update_owe_info *owe_info,
				    gfp_t gfp)
{
	struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
	struct sk_buff *msg;
	void *hdr;

	trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);

	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
	if (!msg)
		return;

	hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
	if (!hdr)
		goto nla_put_failure;

	if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
	    nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
	    nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
		goto nla_put_failure;

	if (!owe_info->ie_len ||
	    nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
		goto nla_put_failure;

	genlmsg_end(msg, hdr);

	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
				NL80211_MCGRP_MLME, gfp);
	return;

nla_put_failure:
	genlmsg_cancel(msg, hdr);
	nlmsg_free(msg);
}
EXPORT_SYMBOL(cfg80211_update_owe_info_event);

/* initialisation/exit functions */

int nl80211_init(void)
+13 −0
Original line number Diff line number Diff line
@@ -1168,4 +1168,17 @@ rdev_external_auth(struct cfg80211_registered_device *rdev,
	return ret;
}

static inline int rdev_update_owe_info(struct cfg80211_registered_device *rdev,
				       struct net_device *dev,
				       struct cfg80211_update_owe_info *oweinfo)
{
	int ret = -EOPNOTSUPP;

	trace_rdev_update_owe_info(&rdev->wiphy, dev, oweinfo);
	if (rdev->ops->update_owe_info)
		ret = rdev->ops->update_owe_info(&rdev->wiphy, dev, oweinfo);
	trace_rdev_return_int(&rdev->wiphy, ret);
	return ret;
}

#endif /* __CFG80211_RDEV_OPS */
+38 −0
Original line number Diff line number Diff line
@@ -3090,6 +3090,44 @@ TRACE_EVENT(rdev_set_multicast_to_unicast,
		  WIPHY_PR_ARG, NETDEV_PR_ARG,
		  BOOL_TO_STR(__entry->enabled))
);

TRACE_EVENT(rdev_update_owe_info,
	    TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
		     struct cfg80211_update_owe_info *owe_info),
	    TP_ARGS(wiphy, netdev, owe_info),
	    TP_STRUCT__entry(WIPHY_ENTRY
			     NETDEV_ENTRY
			     MAC_ENTRY(peer)
			     __field(u16, status)
			     __dynamic_array(u8, ie, owe_info->ie_len)),
	    TP_fast_assign(WIPHY_ASSIGN;
			   NETDEV_ASSIGN;
			   MAC_ASSIGN(peer, owe_info->peer);
			   __entry->status = owe_info->status;
			   memcpy(__get_dynamic_array(ie),
				  owe_info->ie, owe_info->ie_len);),
	    TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT
		  " status %d", WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
		  __entry->status)
);

TRACE_EVENT(cfg80211_update_owe_info_event,
	    TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
		     struct cfg80211_update_owe_info *owe_info),
	    TP_ARGS(wiphy, netdev, owe_info),
	    TP_STRUCT__entry(WIPHY_ENTRY
			     NETDEV_ENTRY
			     MAC_ENTRY(peer)
			     __dynamic_array(u8, ie, owe_info->ie_len)),
	    TP_fast_assign(WIPHY_ASSIGN;
			   NETDEV_ASSIGN;
			   MAC_ASSIGN(peer, owe_info->peer);
			   memcpy(__get_dynamic_array(ie), owe_info->ie,
				  owe_info->ie_len);),
	    TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", peer: " MAC_PR_FMT,
		      WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer))
);

#endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */

#undef TRACE_INCLUDE_PATH