From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.linux.dev
Cc: James Prestwood <prestwoj@gmail.com>
Subject: [PATCH] netdev: set a timeout for CMD_CONNECT based connections
Date: Tue, 5 Nov 2024 05:10:59 -0800 [thread overview]
Message-ID: <20241105131059.1290437-1-prestwoj@gmail.com> (raw)
Based on a users report/logs it appears some drivers (brcmfmac in
this case) may have issues which cause them to never respond with
a CMD_CONNECT event, leaving IWD hung waiting indefinitely for
this.
Since IWD cannot control driver behavior its safest to set a timer
in userspace as a last resort in case this happens.
---
src/netdev.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 58 insertions(+), 4 deletions(-)
diff --git a/src/netdev.c b/src/netdev.c
index 2eebf457..8aeae633 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -70,6 +70,8 @@
#define ENOTSUPP 524
#endif
+#define NETDEV_CONNECT_TIMEOUT 5
+
enum connection_type {
CONNECTION_TYPE_SOFTMAC,
CONNECTION_TYPE_FULLMAC,
@@ -140,6 +142,7 @@ struct netdev {
struct l_timeout *sa_query_timeout;
struct l_timeout *sa_query_delay;
struct l_timeout *group_handshake_timeout;
+ struct l_timeout *connect_timeout;
uint16_t sa_query_id;
int8_t rssi_levels[16];
uint8_t rssi_levels_num;
@@ -859,6 +862,11 @@ static void netdev_connect_free(struct netdev *netdev)
netdev->group_handshake_timeout = NULL;
}
+ if (netdev->connect_timeout) {
+ l_timeout_remove(netdev->connect_timeout);
+ netdev->connect_timeout = NULL;
+ }
+
netdev->associated = false;
netdev->operational = false;
netdev->connected = false;
@@ -2561,6 +2569,33 @@ static void netdev_cmd_connect_cb(struct l_genl_msg *msg, void *user_data)
MMPDU_STATUS_CODE_UNSPECIFIED);
}
+static void netdev_connect_timeout(struct l_timeout *timeout, void *user_data)
+{
+ struct netdev *netdev = user_data;
+
+ l_timeout_remove(netdev->connect_timeout);
+ netdev->connect_timeout = NULL;
+
+ l_error("Kernel never sent CMD_CONNECT event! This is a bug, please "
+ "report upstream");
+
+ /*
+ * Set this now in case the connect event does arrive in between the
+ * deauth and actually cleaning up the connection members.
+ */
+ netdev->connected = false;
+
+ /*
+ * Since the lack of the connect event indicates a kernel/driver bug its
+ * hard to say what state the kernel in. Its probably safest to deauth
+ * here just in case the kernel is in some state between authentication
+ * and association.
+ */
+ netdev_deauth_and_fail_connection(netdev,
+ NETDEV_RESULT_ASSOCIATION_FAILED,
+ MMPDU_STATUS_CODE_UNSPECIFIED);
+}
+
static bool netdev_retry_owe(struct netdev *netdev)
{
struct l_genl_msg *connect_cmd;
@@ -2578,11 +2613,19 @@ static bool netdev_retry_owe(struct netdev *netdev)
netdev_cmd_connect_cb, netdev,
NULL);
- if (netdev->connect_cmd_id > 0)
- return true;
+ if (!netdev->connect_cmd_id) {
+ l_genl_msg_unref(connect_cmd);
+ return false;
+ }
- l_genl_msg_unref(connect_cmd);
- return false;
+ if (netdev->connect_timeout)
+ l_timeout_remove(netdev->connect_timeout);
+
+ netdev->connect_timeout = l_timeout_create(NETDEV_CONNECT_TIMEOUT,
+ netdev_connect_timeout,
+ netdev, NULL);
+
+ return true;
}
static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
@@ -2602,6 +2645,12 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
l_debug("");
+ /* Clear the timer as soon as we receive this event */
+ if (netdev->connect_timeout) {
+ l_timeout_remove(netdev->connect_timeout);
+ netdev->connect_timeout = NULL;
+ }
+
if (netdev->aborting)
return;
@@ -3491,6 +3540,11 @@ static int netdev_begin_connection(struct netdev *netdev)
goto failed;
netdev->connect_cmd = NULL;
+
+ netdev->connect_timeout = l_timeout_create(
+ NETDEV_CONNECT_TIMEOUT,
+ netdev_connect_timeout,
+ netdev, NULL);
}
/*
--
2.34.1
reply other threads:[~2024-11-05 13:11 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20241105131059.1290437-1-prestwoj@gmail.com \
--to=prestwoj@gmail.com \
--cc=iwd@lists.linux.dev \
/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