Wireless Daemon for Linux
 help / color / mirror / Atom feed
* [PATCH 01/11] netdev: Add a wdev_id based frame watch API
@ 2019-10-21 13:55 Andrew Zaborowski
  2019-10-21 13:55 ` [PATCH 02/11] netdev: Report RSSI to frame watch callbacks Andrew Zaborowski
                   ` (10 more replies)
  0 siblings, 11 replies; 36+ messages in thread
From: Andrew Zaborowski @ 2019-10-21 13:55 UTC (permalink / raw)
  To: iwd

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

From: Andrew Zaborowski <andrew.zaborowski@intel.com>

Allow watching for frames on interfaces that have no netdev in the
kernel and can only be referenced through the wdev_id instead of the
ifindex.
---
 src/netdev.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++-----
 src/netdev.h |  6 ++++
 2 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/src/netdev.c b/src/netdev.c
index 350ade98..526480dd 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -167,6 +167,7 @@ struct netdev_frame_watch {
 	uint16_t frame_type;
 	uint8_t *prefix;
 	size_t prefix_len;
+	uint64_t wdev_id;
 	struct watchlist_item super;
 };
 
@@ -174,6 +175,7 @@ static struct l_netlink *rtnl = NULL;
 static struct l_genl_family *nl80211;
 static struct l_queue *netdev_list;
 static struct watchlist netdev_watches;
+static struct watchlist wdev_frame_watches;
 
 static void do_debug(const char *str, void *user_data)
 {
@@ -3482,6 +3484,7 @@ struct frame_prefix_info {
 	uint16_t frame_type;
 	const uint8_t *body;
 	size_t body_len;
+	uint64_t wdev_id;
 };
 
 static bool netdev_frame_watch_match_prefix(const void *a, const void *b)
@@ -3494,11 +3497,13 @@ static bool netdev_frame_watch_match_prefix(const void *a, const void *b)
 	return fw->frame_type == info->frame_type &&
 		fw->prefix_len <= info->body_len &&
 		(fw->prefix_len == 0 ||
-		 !memcmp(fw->prefix, info->body, fw->prefix_len));
+		 !memcmp(fw->prefix, info->body, fw->prefix_len)) &&
+		(!info->wdev_id || info->wdev_id == fw->wdev_id);
 }
 
 static void netdev_mgmt_frame_event(struct l_genl_msg *msg,
-					struct netdev *netdev)
+					struct netdev *netdev,
+					uint64_t wdev_id)
 {
 	struct l_genl_attr attr;
 	uint16_t type, len, frame_len;
@@ -3530,7 +3535,7 @@ static void netdev_mgmt_frame_event(struct l_genl_msg *msg,
 
 	body = mmpdu_body(mpdu);
 
-	if (memcmp(mpdu->address_1, netdev->addr, 6) &&
+	if (netdev && memcmp(mpdu->address_1, netdev->addr, 6) &&
 			!util_is_broadcast_address(mpdu->address_1))
 		return;
 
@@ -3539,11 +3544,18 @@ static void netdev_mgmt_frame_event(struct l_genl_msg *msg,
 	info.frame_type = l_get_le16(mpdu) & FC_FTYPE_STYPE_MASK;
 	info.body = (const uint8_t *) body;
 	info.body_len = (const uint8_t *) mpdu + frame_len - body;
+	info.wdev_id = netdev ? 0 : wdev_id;
 
-	WATCHLIST_NOTIFY_MATCHES(&netdev->frame_watches,
+	if (netdev)
+		WATCHLIST_NOTIFY_MATCHES(&netdev->frame_watches,
 					netdev_frame_watch_match_prefix, &info,
 					netdev_frame_watch_func_t,
 					netdev, mpdu, body, info.body_len);
+	else
+		WATCHLIST_NOTIFY_MATCHES(&wdev_frame_watches,
+					netdev_frame_watch_match_prefix, &info,
+					netdev_frame_watch_func_t,
+					NULL, mpdu, body, info.body_len);
 }
 
 static void netdev_pae_destroy(void *user_data)
@@ -3735,6 +3747,7 @@ static int netdev_control_port_frame(uint32_t ifindex,
 static void netdev_unicast_notify(struct l_genl_msg *msg, void *user_data)
 {
 	struct netdev *netdev = NULL;
+	const uint64_t *wdev_id = NULL;
 	struct l_genl_attr attr;
 	uint16_t type, len;
 	const void *data;
@@ -3759,17 +3772,28 @@ static void netdev_unicast_notify(struct l_genl_msg *msg, void *user_data)
 
 			netdev = netdev_find(*((uint32_t *) data));
 			break;
+		case NL80211_ATTR_WDEV:
+			if (len != sizeof(uint64_t)) {
+				l_warn("Invalid wdev attribute");
+				return;
+			}
+
+			wdev_id = data;
+			break;
 		}
 	}
 
-	if (!netdev)
-		return;
-
 	switch (cmd) {
 	case NL80211_CMD_FRAME:
-		netdev_mgmt_frame_event(msg, netdev);
+		if (!wdev_id)
+			break;
+
+		netdev_mgmt_frame_event(msg, netdev, *wdev_id);
 		break;
 	case NL80211_CMD_CONTROL_PORT_FRAME:
+		if (!netdev)
+			break;
+
 		netdev_control_port_frame_event(msg, netdev);
 		break;
 	}
@@ -4456,6 +4480,50 @@ bool netdev_frame_watch_remove(struct netdev *netdev, uint32_t id)
 	return watchlist_remove(&netdev->frame_watches, id);
 }
 
+uint32_t netdev_wdev_frame_watch_add(uint64_t wdev_id, uint16_t frame_type,
+				const uint8_t *prefix, size_t prefix_len,
+				netdev_frame_watch_func_t handler,
+				void *user_data)
+{
+	struct netdev_frame_watch *fw;
+	struct l_genl_msg *msg;
+	struct frame_prefix_info info = { frame_type, prefix, prefix_len, wdev_id };
+	bool registered;
+	uint32_t id;
+
+	registered = l_queue_find(wdev_frame_watches.items,
+					netdev_frame_watch_match_prefix,
+					&info);
+
+	fw = l_new(struct netdev_frame_watch, 1);
+	fw->frame_type = frame_type;
+	fw->prefix = prefix_len ? l_memdup(prefix, prefix_len) : NULL;
+	fw->prefix_len = prefix_len;
+	fw->wdev_id = wdev_id;
+	id = watchlist_link(&wdev_frame_watches, &fw->super,
+						handler, user_data, NULL);
+
+	if (registered)
+		return id;
+
+	msg = l_genl_msg_new_sized(NL80211_CMD_REGISTER_FRAME, 32 + prefix_len);
+
+	l_genl_msg_append_attr(msg, NL80211_ATTR_WDEV, 8, &wdev_id);
+	l_genl_msg_append_attr(msg, NL80211_ATTR_FRAME_TYPE, 2, &frame_type);
+	l_genl_msg_append_attr(msg, NL80211_ATTR_FRAME_MATCH,
+				prefix_len, prefix);
+
+	l_genl_family_send(nl80211, msg, netdev_frame_cb,
+			L_UINT_TO_PTR(frame_type), NULL);
+
+	return id;
+}
+
+bool netdev_wdev_frame_watch_remove(uint32_t id)
+{
+	return watchlist_remove(&wdev_frame_watches, id);
+}
+
 static struct l_io *pae_open(uint32_t ifindex)
 {
 	/*
@@ -4796,6 +4864,8 @@ static int netdev_init(void)
 	watchlist_init(&netdev_watches, NULL);
 	netdev_list = l_queue_new();
 
+	watchlist_init(&wdev_frame_watches, &netdev_frame_watch_ops);
+
 	__handshake_set_install_tk_func(netdev_set_tk);
 	__handshake_set_install_gtk_func(netdev_set_gtk);
 	__handshake_set_install_igtk_func(netdev_set_igtk);
diff --git a/src/netdev.h b/src/netdev.h
index 114a6035..624811b2 100644
--- a/src/netdev.h
+++ b/src/netdev.h
@@ -197,6 +197,12 @@ uint32_t netdev_frame_watch_add(struct netdev *netdev, uint16_t frame_type,
 				void *user_data);
 bool netdev_frame_watch_remove(struct netdev *netdev, uint32_t id);
 
+uint32_t netdev_wdev_frame_watch_add(uint64_t wdev_id, uint16_t frame_type,
+				const uint8_t *prefix, size_t prefix_len,
+				netdev_frame_watch_func_t handler,
+				void *user_data);
+bool netdev_wdev_frame_watch_remove(uint32_t id);
+
 void netdev_handshake_failed(struct handshake_state *hs, uint16_t reason_code);
 
 struct netdev *netdev_find(int ifindex);
-- 
2.20.1

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

end of thread, other threads:[~2019-10-25  4:42 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-10-21 13:55 [PATCH 01/11] netdev: Add a wdev_id based frame watch API Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 02/11] netdev: Report RSSI to frame watch callbacks Andrew Zaborowski
2019-10-22  3:34   ` Denis Kenzior
2019-10-22 13:46     ` Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 03/11] netdev: Extend checks for P2P scenarios Andrew Zaborowski
2019-10-22  3:36   ` Denis Kenzior
2019-10-21 13:55 ` [PATCH 04/11] eapol: Move the EAP event handler to handshake state Andrew Zaborowski
2019-10-22  4:11   ` Denis Kenzior
2019-10-22 14:00     ` Andrew Zaborowski
2019-10-22 14:34       ` Denis Kenzior
2019-10-21 13:55 ` [PATCH 05/11] unit: Update test-wsc to use handshake_state_set_eap_event_func Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 06/11] wsc: Replace netdev_connect_wsc with netdev_connect usage Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 07/11] netdev: Drop unused netdev_connect_wsc Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 08/11] wsc: Add wsc_new_p2p_enrollee, refactor Andrew Zaborowski
2019-10-22 14:47   ` Denis Kenzior
2019-10-22 23:46     ` Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 09/11] wsc: Accept extra IEs in wsc_new_p2p_enrollee Andrew Zaborowski
2019-10-21 13:55 ` [PATCH 10/11] wiphy: Add wiphy_get_max_roc_duration Andrew Zaborowski
2019-10-22  3:26   ` Denis Kenzior
2019-10-21 13:55 ` [PATCH 11/11] wiphy: Add wiphy_get_supported_rates Andrew Zaborowski
2019-10-22 14:53 ` [PATCH 01/11] netdev: Add a wdev_id based frame watch API Denis Kenzior
2019-10-22 23:56   ` Andrew Zaborowski
2019-10-23  0:23     ` Denis Kenzior
2019-10-23  1:04       ` Andrew Zaborowski
2019-10-23  1:32         ` Denis Kenzior
2019-10-24  0:59           ` Andrew Zaborowski
2019-10-24  2:53             ` Denis Kenzior
2019-10-24  3:22               ` Andrew Zaborowski
2019-10-24 15:29                 ` Denis Kenzior
2019-10-24 21:47                   ` Andrew Zaborowski
2019-10-24 22:16                     ` Denis Kenzior
2019-10-24 22:45                       ` Andrew Zaborowski
2019-10-25  1:27                         ` Denis Kenzior
2019-10-25  2:59                           ` Andrew Zaborowski
2019-10-25  3:56                             ` Denis Kenzior
2019-10-25  4:42                               ` Andrew Zaborowski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox