diff options
author | James Prestwood <prestwoj@gmail.com> | 2024-03-28 10:37:45 -0700 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2024-03-28 17:16:37 -0500 |
commit | ccd702f7da4be5544f5facb21f29044c1dcd1d32 (patch) | |
tree | a3cf0b6b3d520987653e353964b9a5b5c16a8d40 | |
parent | 6365c1f6def8ddd3495b62816a206e82a4b12c38 (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.c | 19 |
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); |