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?
This commit is contained in:
James Prestwood 2024-03-28 10:37:45 -07:00 committed by Denis Kenzior
parent 6365c1f6de
commit ccd702f7da
1 changed files with 16 additions and 3 deletions

View File

@ -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);