diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index b2c4120eb..c808b64aa 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -3165,7 +3165,8 @@ static int nl80211_set_conn_keys(struct wpa_driver_associate_params *params, int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, const u8 *addr, int cmd, u16 reason_code, - int local_state_change) + int local_state_change, + struct nl_handle *nl_connect) { int ret; struct nl_msg *msg; @@ -3179,7 +3180,10 @@ int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, return -1; } - ret = send_and_recv_msgs(drv, msg, NULL, NULL); + if (nl_connect) + ret = send_and_recv(drv->global, nl_connect, msg, NULL, NULL); + else + ret = send_and_recv_msgs(drv, msg, NULL, NULL); if (ret) { wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: MLME command failed: reason=%u ret=%d (%s)", @@ -3190,7 +3194,8 @@ int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv, - int reason_code) + int reason_code, + struct nl_handle *nl_connect) { int ret; int drv_associated = drv->associated; @@ -3199,7 +3204,7 @@ static int wpa_driver_nl80211_disconnect(struct wpa_driver_nl80211_data *drv, nl80211_mark_disconnected(drv); /* Disconnect command doesn't need BSSID - it uses cached value */ ret = wpa_driver_nl80211_mlme(drv, NULL, NL80211_CMD_DISCONNECT, - reason_code, 0); + reason_code, 0, nl_connect); /* * For locally generated disconnect, supplicant already generates a * DEAUTH event, so ignore the event from NL80211. @@ -3221,13 +3226,19 @@ static int wpa_driver_nl80211_deauthenticate(struct i802_bss *bss, nl80211_mark_disconnected(drv); return nl80211_leave_ibss(drv, 1); } - if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) - return wpa_driver_nl80211_disconnect(drv, reason_code); + if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) { + struct nl_handle *nl_connect = NULL; + + if (bss->use_nl_connect) + nl_connect = bss->nl_connect; + return wpa_driver_nl80211_disconnect(drv, reason_code, + nl_connect); + } wpa_printf(MSG_DEBUG, "%s(addr=" MACSTR " reason_code=%d)", __func__, MAC2STR(addr), reason_code); nl80211_mark_disconnected(drv); ret = wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE, - reason_code, 0); + reason_code, 0, NULL); /* * For locally generated deauthenticate, supplicant already generates a * DEAUTH event, so ignore the event from NL80211. @@ -5642,7 +5653,7 @@ static int wpa_driver_nl80211_connect( "disconnecting before reassociation " "attempt"); if (wpa_driver_nl80211_disconnect( - drv, WLAN_REASON_PREV_AUTH_NOT_VALID)) + drv, WLAN_REASON_PREV_AUTH_NOT_VALID, nl_connect)) return -1; ret = wpa_driver_nl80211_try_connect(drv, params, nl_connect); } @@ -5673,8 +5684,13 @@ static int wpa_driver_nl80211_associate( if (wpa_driver_nl80211_set_mode(priv, nlmode) < 0) return -1; - if (params->auth_alg & WPA_AUTH_ALG_SAE) + if (params->auth_alg & WPA_AUTH_ALG_SAE) { nl_connect = bss->nl_connect; + bss->use_nl_connect = 1; + } else { + bss->use_nl_connect = 0; + } + return wpa_driver_nl80211_connect(drv, params, nl_connect); } diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h index 5ac0c7dfc..bc562ba7a 100644 --- a/src/drivers/driver_nl80211.h +++ b/src/drivers/driver_nl80211.h @@ -66,6 +66,7 @@ struct i802_bss { unsigned int wdev_id_set:1; unsigned int added_if:1; unsigned int static_ap:1; + unsigned int use_nl_connect:1; u8 addr[ETH_ALEN]; @@ -252,7 +253,8 @@ int wpa_driver_nl80211_set_mode(struct i802_bss *bss, enum nl80211_iftype nlmode); int wpa_driver_nl80211_mlme(struct wpa_driver_nl80211_data *drv, const u8 *addr, int cmd, u16 reason_code, - int local_state_change); + int local_state_change, + struct nl_handle *nl_connect); int nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv); void nl80211_remove_monitor_interface(struct wpa_driver_nl80211_data *drv); diff --git a/src/drivers/driver_nl80211_scan.c b/src/drivers/driver_nl80211_scan.c index 86501f46e..33a8d3598 100644 --- a/src/drivers/driver_nl80211_scan.c +++ b/src/drivers/driver_nl80211_scan.c @@ -866,7 +866,8 @@ static void clear_state_mismatch(struct wpa_driver_nl80211_data *drv, "mismatch (" MACSTR ")", MAC2STR(addr)); wpa_driver_nl80211_mlme(drv, addr, NL80211_CMD_DEAUTHENTICATE, - WLAN_REASON_PREV_AUTH_NOT_VALID, 1); + WLAN_REASON_PREV_AUTH_NOT_VALID, 1, + NULL); } }