linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Denis Kenzior <denkenz@gmail.com>
To: linux-wireless@vger.kernel.org, johannes@sipsolutions.net
Cc: Denis Kenzior <denkenz@gmail.com>
Subject: [RFCv3 3/3] nl80211: Send large new_wiphy events
Date: Fri,  6 Sep 2019 10:43:03 -0500	[thread overview]
Message-ID: <20190906154303.9303-3-denkenz@gmail.com> (raw)
In-Reply-To: <20190906154303.9303-1-denkenz@gmail.com>

Send large NEW_WIPHY events on a new multicast group so that clients
that can accept larger messages do not need to round-trip to the kernel
and perform extra filtered wiphy dumps.

A new multicast group is introduced and the large message is sent before
the legacy message.  This way clients that listen on both multicast
groups can ignore duplicate legacy messages if needed.

Signed-off-by: Denis Kenzior <denkenz@gmail.com>
---
 include/uapi/linux/nl80211.h | 31 +++++++++++++++++++++++++++++++
 net/wireless/nl80211.c       | 34 ++++++++++++++++++++++++++++++++--
 2 files changed, 63 insertions(+), 2 deletions(-)

Changes in this version:

- Updated the docs based on Johannes' feedback
- Added WARN_ON in case the large message building fails (e.g. our
  buffer size needs to be increased)
- Minor style fixes based on Johannes' feedback
- Added a missing skb_get to take an extra reference when sending
  NEW/DEL INTERFACE events.

diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index beee59c831a7..7a125cb4d9d9 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -50,6 +50,7 @@
 #define NL80211_MULTICAST_GROUP_MLME		"mlme"
 #define NL80211_MULTICAST_GROUP_VENDOR		"vendor"
 #define NL80211_MULTICAST_GROUP_NAN		"nan"
+#define NL80211_MULTICAST_GROUP_CONFIG2		"config2"
 #define NL80211_MULTICAST_GROUP_TESTMODE	"testmode"
 
 #define NL80211_EDMG_BW_CONFIG_MIN	4
@@ -267,8 +268,30 @@
  * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
  *	or rename notification. Has attributes %NL80211_ATTR_WIPHY and
  *	%NL80211_ATTR_WIPHY_NAME.
+ *
+ *	Note that when %NL80211_CMD_NEW_WIPHY is being sent as an event, it
+ *	will be multicast on two groups: "config" and "config2".  The messages
+ *	on the two multicast groups will be different.  On "config" multicast
+ *	group, %NL80211_CMD_NEW_WIPHY messages will be 'reduced' size and will
+ *	only contain legacy information.  This is due to historical kernel
+ *	behavior that limited such messages to 4096 bytes.  The "config2"
+ *	multicast group was introduced to support applications that can
+ *	allocate larger buffers and can thus accept new wiphy events with
+ *	the full set of information included.  Messages on the "config2"
+ *	multicast group are sent before the "config" multicast group.
+ *
+ *	There are no limits (outside of netlink protocol limits) on
+ *	message sizes that can be sent over the "config2" multicast group. It
+ *	is assumed that applications utilizing "config2" multicast group
+ *	utilize buffers that are inherently large enough or can utilize
+ *	MSG_PEEK/MSG_TRUNC in the netlink transport in order to allocate big
+ *	enough buffers.
  * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes
  *	%NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME.
+ *	Note that when %NL80211_CMD_DEL_WIPHY is being sent as an event, it
+ *	will be multicast on two groups: "config" and "config2".  Messages on
+ *	the "config2" multicast group are sent before the "config" multicast
+ *	group.
  *
  * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration;
  *	either a dump request for all interfaces or a specific get with a
@@ -281,10 +304,18 @@
  *	be sent from userspace to request creation of a new virtual interface,
  *	then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and
  *	%NL80211_ATTR_IFNAME.
+ *	Note that when %NL80211_CMD_NEW_INTERFACE is being sent as an event, it
+ *	will be multicast on two groups: "config" and "config2".  Messages on
+ *	the "config2" multicast group are sent before the "config" multicast
+ *	group.
  * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes
  *	%NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from
  *	userspace to request deletion of a virtual interface, then requires
  *	attribute %NL80211_ATTR_IFINDEX.
+ *	Note that when %NL80211_CMD_DEL_INTERFACE is being sent as an event, it
+ *	will be multicast on two groups: "config" and "config2".  Messages on
+ *	the "config2" multicast group are sent before the "config" multicast
+ *	group.
  *
  * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified
  *	by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC.
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 03421f66eea3..68f496c0c0a4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -46,6 +46,7 @@ enum nl80211_multicast_groups {
 	NL80211_MCGRP_MLME,
 	NL80211_MCGRP_VENDOR,
 	NL80211_MCGRP_NAN,
+	NL80211_MCGRP_CONFIG2,
 	NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
 };
 
@@ -56,6 +57,7 @@ static const struct genl_multicast_group nl80211_mcgrps[] = {
 	[NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
 	[NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
 	[NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
+	[NL80211_MCGRP_CONFIG2] = { .name = NL80211_MULTICAST_GROUP_CONFIG2 },
 #ifdef CONFIG_NL80211_TESTMODE
 	[NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
 #endif
@@ -1856,6 +1858,7 @@ struct nl80211_dump_wiphy_state {
 	long start;
 	long split_start, band_start, chan_start;
 	bool legacy;
+	bool large_message;
 };
 
 static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
@@ -2414,7 +2417,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
 
  nla_put_failure:
 	if ((state->legacy && state->split_start < 9) ||
-	    !last_good_pos) {
+	    !last_good_pos || state->large_message) {
 		genlmsg_cancel(msg, hdr);
 		return -EMSGSIZE;
 	}
@@ -14732,14 +14735,37 @@ void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
 			  enum nl80211_commands cmd)
 {
 	struct sk_buff *msg;
+	size_t alloc_size;
 	struct nl80211_dump_wiphy_state state = {};
 
 	WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
 		cmd != NL80211_CMD_DEL_WIPHY);
 
+	if (cmd == NL80211_CMD_NEW_WIPHY) {
+		state.large_message = true;
+		alloc_size = 8192UL;
+	} else {
+		alloc_size = NLMSG_DEFAULT_SIZE;
+	}
+
+	msg = nlmsg_new(alloc_size, GFP_KERNEL);
+	if (!msg)
+		goto legacy;
+
+	if (WARN_ON(nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0)) {
+		nlmsg_free(msg);
+		goto legacy;
+	}
+
+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+				NL80211_MCGRP_CONFIG2, GFP_KERNEL);
+
+legacy:
+	state.large_message = false;
 	state.legacy = true;
 
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	alloc_size = NLMSG_DEFAULT_SIZE;
+	msg = nlmsg_new(alloc_size, GFP_KERNEL);
 	if (!msg)
 		return;
 
@@ -14767,6 +14793,10 @@ void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
 		return;
 	}
 
+	/* We will be sending the same message twice, grab an extra ref */
+	msg = skb_get(msg);
+	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
+				NL80211_MCGRP_CONFIG2, GFP_KERNEL);
 	genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
 				NL80211_MCGRP_CONFIG, GFP_KERNEL);
 }
-- 
2.19.2


  parent reply	other threads:[~2019-09-06 15:49 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-06 15:43 [RFCv3 1/3] nl80211: Fix broken non-split wiphy dumps Denis Kenzior
2019-09-06 15:43 ` [RFCv3 2/3] nl80211: Support >4096 byte NEW_WIPHY event nlmsg Denis Kenzior
2019-09-11  9:44   ` Johannes Berg
2019-09-11 12:41     ` Denis Kenzior
2019-09-11 15:28       ` Johannes Berg
2019-09-11 13:51         ` Denis Kenzior
2019-10-01  9:23           ` Johannes Berg
2019-09-06 15:43 ` Denis Kenzior [this message]
2019-09-11  9:47   ` [RFCv3 3/3] nl80211: Send large new_wiphy events Johannes Berg
2019-09-11 12:20     ` Denis Kenzior
2019-09-11 15:12       ` Johannes Berg
2019-09-11 13:23         ` Denis Kenzior
2020-09-28 11:14           ` Johannes Berg
2020-10-02 14:54             ` Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190906154303.9303-3-denkenz@gmail.com \
    --to=denkenz@gmail.com \
    --cc=johannes@sipsolutions.net \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).