Wireless Daemon for Linux
 help / color / mirror / Atom feed
From: Denis Kenzior <denkenz@gmail.com>
To: iwd@lists.01.org
Subject: [PATCH 8/8] station: Move AP directed roam watch to station
Date: Tue, 20 Apr 2021 11:35:19 -0500	[thread overview]
Message-ID: <20210420163519.12375-8-denkenz@gmail.com> (raw)
In-Reply-To: <20210420163519.12375-1-denkenz@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5819 bytes --]

Logically this frame watch belongs in station.  It was kept in device.c
for the purported reason that the station object was removed with
ifdown/ifup changes and hence the frame watch might need to be removed
and re-added unnecessarily.  Since the kernel does not actually allow to
unregister a frame watch (only when the netdev is removed or its iftype
changes), re-adding a frame watch might trigger a -EALREADY or similar
error.

Avoid this by registering the frame watch when a new netdev is detected
in STATION mode, or when the interface type changes to STATION.
---
 src/device.c  | 22 ----------------------
 src/station.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
 src/station.h |  4 ----
 3 files changed, 45 insertions(+), 32 deletions(-)

diff --git a/src/device.c b/src/device.c
index dc2c181ad4b3..02da2cdc0f08 100644
--- a/src/device.c
+++ b/src/device.c
@@ -37,8 +37,6 @@
 #include "src/scan.h"
 #include "src/netdev.h"
 #include "src/dbus.h"
-#include "src/frame-xchg.h"
-#include "src/station.h"
 
 struct device {
 	uint32_t index;
@@ -54,18 +52,6 @@ struct device {
 
 static uint32_t netdev_watch;
 
-static void device_ap_roam_frame_event(const struct mmpdu_header *hdr,
-		const void *body, size_t body_len, int rssi, void *user_data)
-{
-	struct device *device = user_data;
-	struct station *station = station_find(device->index);
-
-	if (!station)
-		return;
-
-	station_ap_directed_roam(station, hdr, body, body_len);
-}
-
 static bool device_property_get_name(struct l_dbus *dbus,
 					struct l_dbus_message *message,
 					struct l_dbus_message_builder *builder,
@@ -304,7 +290,6 @@ static struct device *device_create(struct wiphy *wiphy, struct netdev *netdev)
 	struct device *device;
 	struct l_dbus *dbus = dbus_get_bus();
 	uint32_t ifindex = netdev_get_ifindex(netdev);
-	const uint8_t action_ap_roam_prefix[2] = { 0x0a, 0x07 };
 
 	device = l_new(struct device, 1);
 	device->index = ifindex;
@@ -320,13 +305,6 @@ static struct device *device_create(struct wiphy *wiphy, struct netdev *netdev)
 		l_info("Unable to register %s interface",
 				L_DBUS_INTERFACE_PROPERTIES);
 
-	/*
-	 * register for AP roam transition watch
-	 */
-	frame_watch_add(netdev_get_wdev_id(netdev), 0, 0x00d0,
-			action_ap_roam_prefix, sizeof(action_ap_roam_prefix),
-			device_ap_roam_frame_event, device, NULL);
-
 	device->powered = netdev_get_is_up(netdev);
 
 	device->dbus_powered = true;
diff --git a/src/station.c b/src/station.c
index 064872c688af..5e3338f0dace 100644
--- a/src/station.c
+++ b/src/station.c
@@ -55,6 +55,7 @@
 #include "src/anqp.h"
 #include "src/anqputil.h"
 #include "src/diagnostic.h"
+#include "src/frame-xchg.h"
 
 static struct l_queue *station_list;
 static uint32_t netdev_watch;
@@ -2221,9 +2222,9 @@ static bool station_cannot_roam(struct station *station)
 #define WNM_REQUEST_MODE_TERMINATION_IMMINENT		(1 << 3)
 #define WNM_REQUEST_MODE_ESS_DISASSOCIATION_IMMINENT	(1 << 4)
 
-void station_ap_directed_roam(struct station *station,
-				const struct mmpdu_header *hdr,
-				const void *body, size_t body_len)
+static void station_ap_directed_roam(struct station *station,
+					const struct mmpdu_header *hdr,
+					const void *body, size_t body_len)
 {
 	uint32_t pos = 0;
 	uint8_t req_mode;
@@ -3704,15 +3705,48 @@ static void station_destroy_diagnostic_interface(void *user_data)
 {
 }
 
+static void ap_roam_frame_event(const struct mmpdu_header *hdr,
+					const void *body, size_t body_len,
+					int rssi, void *user_data)
+{
+	uint32_t ifindex = L_PTR_TO_UINT(user_data);
+	struct station *station = station_find(ifindex);
+
+	if (!station)
+		return;
+
+	station_ap_directed_roam(station, hdr, body, body_len);
+}
+
+static void add_frame_watches(struct netdev *netdev)
+{
+	static const uint8_t action_ap_roam_prefix[2] = { 0x0a, 0x07 };
+
+	/*
+	 * register for AP roam transition watch
+	 */
+	frame_watch_add(netdev_get_wdev_id(netdev), 0, 0x00d0,
+			action_ap_roam_prefix, sizeof(action_ap_roam_prefix),
+			ap_roam_frame_event,
+			L_UINT_TO_PTR(netdev_get_ifindex(netdev)), NULL);
+}
+
 static void station_netdev_watch(struct netdev *netdev,
 				enum netdev_watch_event event, void *userdata)
 {
 	switch (event) {
-	case NETDEV_WATCH_EVENT_UP:
 	case NETDEV_WATCH_EVENT_NEW:
-		if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_STATION &&
-				netdev_get_is_up(netdev))
+		if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_STATION) {
+			add_frame_watches(netdev);
+
+			if (netdev_get_is_up(netdev))
+				station_create(netdev);
+		}
+		break;
+	case NETDEV_WATCH_EVENT_UP:
+		if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_STATION)
 			station_create(netdev);
+
 		break;
 	case NETDEV_WATCH_EVENT_DOWN:
 	case NETDEV_WATCH_EVENT_DEL:
@@ -3720,6 +3754,11 @@ static void station_netdev_watch(struct netdev *netdev,
 						netdev_get_path(netdev),
 						IWD_STATION_INTERFACE);
 		break;
+	case NETDEV_WATCH_EVENT_IFTYPE_CHANGE:
+		if (netdev_get_iftype(netdev) == NETDEV_IFTYPE_STATION)
+			add_frame_watches(netdev);
+
+		break;
 	default:
 		break;
 	}
diff --git a/src/station.h b/src/station.h
index f114733b0cbc..6918b1464a5a 100644
--- a/src/station.h
+++ b/src/station.h
@@ -83,10 +83,6 @@ void station_remove_anqp_watch(uint32_t id);
 
 bool station_set_autoconnect(struct station *station, bool autoconnect);
 
-void station_ap_directed_roam(struct station *station,
-				const struct mmpdu_header *hdr,
-				const void *body, size_t body_len);
-
 int __station_connect_network(struct station *station, struct network *network,
 				struct scan_bss *bss);
 void station_connect_network(struct station *station, struct network *network,
-- 
2.26.3

  parent reply	other threads:[~2021-04-20 16:35 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-20 16:35 [PATCH 1/8] netdev: Track SET_INTERFACE events Denis Kenzior
2021-04-20 16:35 ` [PATCH 2/8] frame-xchg: iftype changes to be managed by netdev Denis Kenzior
2021-04-20 16:35 ` [PATCH 3/8] netdev: Re-add frame watches on iftype change Denis Kenzior
2021-04-20 16:35 ` [PATCH 4/8] rrm: Track that station is removed Denis Kenzior
2021-04-20 16:35 ` [PATCH 5/8] netdev: Add new iftype change event Denis Kenzior
2021-04-20 16:35 ` [PATCH 6/8] rrm: Always create RRM state Denis Kenzior
2021-04-20 16:35 ` [PATCH 7/8] rrm: React to IFTYPE_CHANGE events Denis Kenzior
2021-04-20 16:35 ` Denis Kenzior [this message]
2021-04-23 14:52 ` [PATCH 1/8] netdev: Track SET_INTERFACE events 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=20210420163519.12375-8-denkenz@gmail.com \
    --to=denkenz@gmail.com \
    --cc=iwd@lists.01.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