aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Prestwood <prestwoj@gmail.com>2024-03-28 10:37:45 -0700
committerDenis Kenzior <denkenz@gmail.com>2024-03-28 17:16:37 -0500
commitccd702f7da4be5544f5facb21f29044c1dcd1d32 (patch)
treea3cf0b6b3d520987653e353964b9a5b5c16a8d40
parent6365c1f6def8ddd3495b62816a206e82a4b12c38 (diff)
netdev: use CMD_DEAUTHENTICATE when needed on disconnect
netdev_disconnect() was unconditionally sending CMD_DISCONNECT which is not the right behavior when IWD has not associated. This means that if a connection was started then immediately canceled with the Disconnect() method the kernel would continue to authenticate. Instead if IWD has not yet associated it should send a deauth command which causes the kernel to correctly cleanup its state and stop trying to authenticate. Below are logs showing the behavior. Autoconnect is started followed immediately by a DBus Disconnect call, yet the kernel continues sending authenticate events. event: state, old: autoconnect_quick, new: connecting (auto) src/scan.c:scan_cancel() Trying to cancel scan id 1 for wdev 7d src/wiphy.c:wiphy_radio_work_done() Work item 1 done src/wiphy.c:wiphy_radio_work_next() Starting work item 2 src/netdev.c:netdev_mlme_notify() MLME notification New Station(19) src/station.c:station_dbus_disconnect() src/station.c:station_reset_connection_state() 85 src/station.c:station_roam_state_clear() 85 event: state, old: connecting (auto), new: disconnecting src/wiphy.c:wiphy_radio_work_done() Work item 2 done src/station.c:station_connect_cb() 85, result: 5 src/station.c:station_disconnect_cb() 85, success: 1 event: state, old: disconnecting, new: disconnected src/netdev.c:netdev_mlme_notify() MLME notification Authenticate(37) src/netdev.c:netdev_authenticate_event() Unexpected connection related event -- is another supplicant running? src/netdev.c:netdev_mlme_notify() MLME notification Authenticate(37) src/netdev.c:netdev_authenticate_event() Unexpected connection related event -- is another supplicant running? src/netdev.c:netdev_mlme_notify() MLME notification Authenticate(37) src/netdev.c:netdev_authenticate_event() Unexpected connection related event -- is another supplicant running? src/netdev.c:netdev_mlme_notify() MLME notification Del Station(20) src/netdev.c:netdev_mlme_notify() MLME notification Authenticate(37) src/netdev.c:netdev_authenticate_event() Unexpected connection related event -- is another supplicant running?
-rw-r--r--src/netdev.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/src/netdev.c b/src/netdev.c
index 09fac959a..26e360813 100644
--- a/src/netdev.c
+++ b/src/netdev.c
@@ -3935,6 +3935,8 @@ int netdev_disconnect(struct netdev *netdev,
{
struct l_genl_msg *disconnect;
bool send_disconnect = true;
+ bool deauth = false;
+ uint8_t aa[6];
if (!(netdev->ifi_flags & IFF_UP))
return -ENETDOWN;
@@ -3953,8 +3955,8 @@ int netdev_disconnect(struct netdev *netdev,
* 1. We do not actually have a connect in progress (work.id
* is zero), then we can bail out early with an error.
* 2. We have sent CMD_CONNECT but not fully connected. The
- * CMD_CONNECT needs to be canceled and a disconnect should
- * be sent.
+ * CMD_CONNECT needs to be canceled and a disconnect or
+ * deauth should be sent.
* 3. Queued up the connect work, but haven't sent CMD_CONNECT
* to the kernel. This case we do not need to send a
* disconnect.
@@ -3969,6 +3971,11 @@ int netdev_disconnect(struct netdev *netdev,
netdev->work.id))
send_disconnect = false;
+ if (netdev->handshake && !netdev->associated) {
+ memcpy(aa, netdev->handshake->aa, 6);
+ deauth = true;
+ }
+
netdev_connect_failed(netdev, NETDEV_RESULT_ABORTED,
MMPDU_REASON_CODE_UNSPECIFIED);
} else {
@@ -3976,8 +3983,14 @@ int netdev_disconnect(struct netdev *netdev,
}
if (send_disconnect) {
- disconnect = nl80211_build_disconnect(netdev->index,
+ if (deauth)
+ disconnect = nl80211_build_deauthenticate(
+ netdev->index, aa,
MMPDU_REASON_CODE_DEAUTH_LEAVING);
+ else
+ disconnect = nl80211_build_disconnect(netdev->index,
+ MMPDU_REASON_CODE_DEAUTH_LEAVING);
+
netdev->disconnect_cmd_id = l_genl_family_send(nl80211,
disconnect, netdev_cmd_disconnect_cb,
netdev, NULL);