From: James Prestwood <prestwoj@gmail.com>
To: iwd@lists.linux.dev
Cc: James Prestwood <prestwoj@gmail.com>
Subject: [PATCH 1/4] station: treat netconfig failures as connection failures
Date: Wed, 28 May 2025 07:27:47 -0700 [thread overview]
Message-ID: <20250528142750.498252-1-prestwoj@gmail.com> (raw)
Currently the netconfig functionality is somewhat separated from
IWD's "connection" process. Regardless if netconfig is enabled
the method return from Connect() will happen after IWD has completed
the 4-way handshake. If netconfig fails its shows externally as an
IWD state change rather than part of the method return from
Connect(). Overall this doesn't pose a significant problem since a
netconfig failure essentially appears as if IWD became disconnected
but more critical is that IWD will not iteratively try more BSS's if
netconfig fails.
For example a BSS may be misconfigured, or not able to communicate to
the DHCP server. IWD could connect to it, and fail netconfig thereby
restarting the autoconnect logic. IWD will then choose the "best" BSS
which may be the one it just failed on. This would then repeat
indefinitely or until a better BSS comes around which could be never.
To improve this netconfig has been adopted into the IWD's BSS retry
logic. If netconfig fails this will not result in IWD transitioning
to a disconnected state, and instead the BSS will be network
blacklisted and the next will be tried. Only once all BSS's have been
tried will IWD go into a disconnected state and start autoconnect
over.
---
src/station.c | 104 +++++++++++++++++++++++++-------------------------
1 file changed, 51 insertions(+), 53 deletions(-)
diff --git a/src/station.c b/src/station.c
index 2b6a18f8..81c1e595 100644
--- a/src/station.c
+++ b/src/station.c
@@ -1795,6 +1795,13 @@ static void station_enter_state(struct station *station,
periodic_scan_stop(station);
break;
case STATION_STATE_CONNECTED:
+ if (station->connect_pending) {
+ struct l_dbus_message *reply =
+ l_dbus_message_new_method_return(
+ station->connect_pending);
+ dbus_pending_reply(&station->connect_pending, reply);
+ }
+
l_dbus_object_add_interface(dbus,
netdev_get_path(station->netdev),
IWD_STATION_DIAGNOSTIC_INTERFACE,
@@ -2214,6 +2221,26 @@ static void station_early_neighbor_report_cb(struct netdev *netdev, int err,
&station->roam_freqs);
}
+static bool station_try_next_bss(struct station *station)
+{
+ struct scan_bss *next;
+ int ret;
+
+ next = network_bss_select(station->connected_network, false);
+
+ if (!next)
+ return false;
+
+ ret = __station_connect_network(station, station->connected_network,
+ next, station->state);
+ if (ret < 0)
+ return false;
+
+ l_debug("Attempting to connect to next BSS "MAC, MAC_STR(next->addr));
+
+ return true;
+}
+
static bool station_can_fast_transition(struct station *station,
struct handshake_state *hs,
struct scan_bss *bss)
@@ -2256,28 +2283,28 @@ static bool station_can_fast_transition(struct station *station,
return true;
}
-static void station_disconnect_on_error_cb(struct netdev *netdev, bool success,
- void *user_data)
+static void station_disconnect_on_netconfig_failed(struct netdev *netdev,
+ bool success,
+ void *user_data)
{
struct station *station = user_data;
- bool continue_autoconnect;
- station_enter_state(station, STATION_STATE_DISCONNECTED);
+ if (station_try_next_bss(station))
+ return;
- continue_autoconnect = station->state == STATION_STATE_CONNECTING_AUTO;
+ network_disconnected(station->connected_network);
- if (continue_autoconnect) {
- if (station_autoconnect_next(station) < 0) {
- l_debug("Nothing left on autoconnect list");
- station_enter_state(station,
- STATION_STATE_AUTOCONNECT_FULL);
- }
+ if (station->connect_pending) {
+ struct l_dbus_message *reply = dbus_error_failed(
+ station->connect_pending);
- return;
+ dbus_pending_reply(&station->connect_pending, reply);
}
- if (station->autoconnect)
- station_enter_state(station, STATION_STATE_AUTOCONNECT_QUICK);
+ station_reset_connection_state(station);
+
+ station_enter_state(station, STATION_STATE_DISCONNECTED);
+ station_enter_state(station, STATION_STATE_AUTOCONNECT_FULL);
}
static void station_netconfig_event_handler(enum netconfig_event event,
@@ -2287,26 +2314,24 @@ static void station_netconfig_event_handler(enum netconfig_event event,
switch (event) {
case NETCONFIG_EVENT_CONNECTED:
+ network_connected(station->connected_network);
station_enter_state(station, STATION_STATE_CONNECTED);
break;
case NETCONFIG_EVENT_FAILED:
- if (station->connect_pending) {
- struct l_dbus_message *reply = dbus_error_failed(
- station->connect_pending);
+ station_debug_event(station, "netconfig-failed");
- dbus_pending_reply(&station->connect_pending, reply);
- }
+ netconfig_reset(station->netconfig);
if (station->state == STATION_STATE_NETCONFIG)
network_connect_failed(station->connected_network,
false);
+ network_blacklist_add(station->connected_network,
+ station->connected_bss);
+
netdev_disconnect(station->netdev,
- station_disconnect_on_error_cb,
+ station_disconnect_on_netconfig_failed,
station);
- station_reset_connection_state(station);
-
- station_enter_state(station, STATION_STATE_DISCONNECTING);
break;
default:
l_error("station: Unsupported netconfig event: %d.", event);
@@ -3409,26 +3434,6 @@ static void station_event_channel_switched(struct station *station,
network_bss_update(network, station->connected_bss);
}
-static bool station_try_next_bss(struct station *station)
-{
- struct scan_bss *next;
- int ret;
-
- next = network_bss_select(station->connected_network, false);
-
- if (!next)
- return false;
-
- ret = __station_connect_network(station, station->connected_network,
- next, station->state);
- if (ret < 0)
- return false;
-
- l_debug("Attempting to connect to next BSS "MAC, MAC_STR(next->addr));
-
- return true;
-}
-
static bool station_retry_owe_default_group(struct station *station)
{
/*
@@ -3581,13 +3586,6 @@ static void station_connect_ok(struct station *station)
l_debug("");
- if (station->connect_pending) {
- struct l_dbus_message *reply =
- l_dbus_message_new_method_return(
- station->connect_pending);
- dbus_pending_reply(&station->connect_pending, reply);
- }
-
/*
* Get a neighbor report now so future roams can avoid waiting for
* a report at that time
@@ -3598,8 +3596,6 @@ static void station_connect_ok(struct station *station)
l_warn("Could not request neighbor report");
}
- network_connected(station->connected_network);
-
if (station->netconfig) {
if (hs->fils_ip_req_ie && hs->fils_ip_resp_ie) {
struct ie_fils_ip_addr_response_info info;
@@ -3639,8 +3635,10 @@ static void station_connect_ok(struct station *station)
return;
station_enter_state(station, STATION_STATE_NETCONFIG);
- } else
+ } else {
+ network_connected(station->connected_network);
station_enter_state(station, STATION_STATE_CONNECTED);
+ }
}
static void station_connect_cb(struct netdev *netdev, enum netdev_result result,
--
2.34.1
next reply other threads:[~2025-05-28 14:27 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-28 14:27 James Prestwood [this message]
2025-05-28 14:27 ` [PATCH 2/4] auto-t: allow configurable DBus timeout/callbacks on connect{_bssid} James Prestwood
2025-05-28 14:27 ` [PATCH 3/4] auto-t: update serveral tests to work with netconfig refactor James Prestwood
2025-05-28 14:40 ` Paul Menzel
2025-05-28 14:42 ` James Prestwood
2025-05-28 14:27 ` [PATCH 4/4] doc: add note about timeouts to Network.Connect() James Prestwood
2025-05-28 17:47 ` [PATCH 1/4] station: treat netconfig failures as connection failures 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=20250528142750.498252-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