From: Andrew Zaborowski <balrogg@gmail.com>
To: iwd@lists.01.org
Subject: [PATCH 01/11] netdev: Add a wdev_id based frame watch API
Date: Mon, 21 Oct 2019 15:55:00 +0200 [thread overview]
Message-ID: <20191021135510.12657-1-balrogg@gmail.com> (raw)
[-- 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
next reply other threads:[~2019-10-21 13:55 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-21 13:55 Andrew Zaborowski [this message]
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
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=20191021135510.12657-1-balrogg@gmail.com \
--to=balrogg@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