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

Commit 26c53c08 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "cfg80211/nl80211: Offload OWE processing to user space in AP mode"

parents 43e6c923 08177d39
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -2847,6 +2847,32 @@ struct cfg80211_external_auth_params {
	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;
};

/**
 * struct cfg80211_ops - backend description for wireless configuration
 *
@@ -3179,6 +3205,10 @@ struct cfg80211_external_auth_params {
 *
 * @tx_control_port: TX a control port frame (EAPoL).  The noencrypt parameter
 *	tells the driver that the frame should not be encrypted.
 *
 * @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);
@@ -3484,6 +3514,8 @@ struct cfg80211_ops {
				   const u8 *buf, size_t len,
				   const u8 *dest, const __be16 proto,
				   const bool noencrypt);
	int	(*update_owe_info)(struct wiphy *wiphy, struct net_device *dev,
				   struct cfg80211_update_owe_info *owe_info);
};

/*
@@ -6806,4 +6838,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 */
+7 −0
Original line number Diff line number Diff line
@@ -1065,6 +1065,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
 */
@@ -1285,6 +1290,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 */
+72 −0
Original line number Diff line number Diff line
@@ -13025,6 +13025,31 @@ static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
	return err;
}

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
@@ -13936,6 +13961,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,
	},
};

static struct genl_family nl80211_fam __ro_after_init = {
@@ -16110,6 +16142,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 __init nl80211_init(void)
+13 −0
Original line number Diff line number Diff line
@@ -1232,4 +1232,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
@@ -3259,6 +3259,44 @@ TRACE_EVENT(rdev_get_txq_stats,
	),
	TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
);

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