All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mac80211: Allow multiple listeners for management frames.
@ 2017-03-10  9:34 Sven Eckelmann
  2017-03-14 13:51 ` Johannes Berg
  0 siblings, 1 reply; 7+ messages in thread
From: Sven Eckelmann @ 2017-03-10  9:34 UTC (permalink / raw)
  To: linux-wireless
  Cc: Johannes Berg, simon.wunderlich, Benjamin Berg, Sven Eckelmann

From: Benjamin Berg <benjamin@sipsolutions.net>

Previously it was not possible to have multiple listeners for management
frames in userspace. This is a bit weird as multiple processes in
userspace might try to request management frame reporting but only
the first request was accepted.

Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
---
It is currently unknown why Benjamin never forwarded it. I am doing this
now to have a chance that this private patch doesn't have to be rebased
anymore by OpenMesh.
---
 net/wireless/mlme.c | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 22b3d9990065..f8ce18dcaa61 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -467,6 +467,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
 	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
 	struct cfg80211_mgmt_registration *reg, *nreg;
 	int err = 0;
+	int registered = 0;
 	u16 mgmt_type;
 
 	if (!wdev->wiphy->mgmt_stypes)
@@ -494,6 +495,12 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
 		if (frame_type != le16_to_cpu(reg->frame_type))
 			continue;
 
+		registered = 1;
+
+		/* Allow duplicate registrations on different ports */
+		if (snd_portid != reg->nlportid)
+			continue;
+
 		if (memcmp(reg->match, match_data, mlen) == 0) {
 			err = -EALREADY;
 			break;
@@ -516,7 +523,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_portid,
 	/* process all unregistrations to avoid driver confusion */
 	cfg80211_process_mlme_unregistrations(rdev);
 
-	if (rdev->ops->mgmt_frame_register)
+	if (rdev->ops->mgmt_frame_register && !registered)
 		rdev_mgmt_frame_register(rdev, wdev, frame_type, true);
 
 	return 0;
@@ -536,6 +543,26 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlportid)
 	spin_lock_bh(&wdev->mgmt_registrations_lock);
 
 	list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
+		struct cfg80211_mgmt_registration *inner;
+		int keep_registration = 0;
+
+		/* Do not remove registration as long as there is one other
+		 * registration for the frame type. Note that this registration
+		 * might even be on the same nlportid with a different match.
+		 */
+		list_for_each_entry(inner, &wdev->mgmt_registrations, list) {
+			if (inner == reg)
+				continue;
+
+			if (reg->frame_type == inner->frame_type) {
+				keep_registration = 1;
+				break;
+			}
+		}
+
+		if (keep_registration)
+			continue;
+
 		if (reg->nlportid != nlportid)
 			continue;
 
@@ -735,7 +762,6 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
 			continue;
 
 		result = true;
-		break;
 	}
 
 	spin_unlock_bh(&wdev->mgmt_registrations_lock);
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-03-14 14:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-10  9:34 [PATCH] mac80211: Allow multiple listeners for management frames Sven Eckelmann
2017-03-14 13:51 ` Johannes Berg
2017-03-14 14:06   ` Sven Eckelmann
2017-03-14 14:10     ` Simon Wunderlich
2017-03-14 14:13       ` Johannes Berg
2017-03-14 14:21         ` Sven Eckelmann
2017-03-14 14:27           ` Johannes Berg

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.