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 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.