Use wpa_drv_{disassociate,deauthenticate} while waiting for connection
wpa_supplicant_{disassociate,deauthenticate}() need to inform the driver about decision to disconnect even if this happens during the time when the driver is still trying to complete association. During that time, wpa_s->bssid is not set, so the code in these functions needs to figure out the correct BSSID based on that field or wpa_s->pending_bssid. In addition, it is possible that the BSSID is not even known at wpa_supplicant at this point in time when using drivers that perform BSS selection internally. In those cases, the disconnect command needs to be sent to the driver without the BSSID. This fixes issues where the driver (or cfg80211 in particular) may be left in mismatching state with wpa_supplicant when disconnection (e.g., due to a ctrl_iface command) happens between connection request and association event. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
e50d01b4f1
commit
42d235477f
1 changed files with 52 additions and 4 deletions
|
@ -1694,14 +1694,38 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
u8 *addr = NULL;
|
u8 *addr = NULL;
|
||||||
union wpa_event_data event;
|
union wpa_event_data event;
|
||||||
|
int zero_addr = 0;
|
||||||
|
|
||||||
if (!is_zero_ether_addr(wpa_s->bssid)) {
|
wpa_dbg(wpa_s, MSG_DEBUG, "Request to disassociate - bssid=" MACSTR
|
||||||
wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
|
" pending_bssid=" MACSTR " reason=%d state=%s",
|
||||||
|
MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
|
||||||
|
reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
|
||||||
|
|
||||||
|
if (!is_zero_ether_addr(wpa_s->bssid))
|
||||||
addr = wpa_s->bssid;
|
addr = wpa_s->bssid;
|
||||||
|
else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
|
||||||
|
(wpa_s->wpa_state == WPA_AUTHENTICATING ||
|
||||||
|
wpa_s->wpa_state == WPA_ASSOCIATING))
|
||||||
|
addr = wpa_s->pending_bssid;
|
||||||
|
else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
|
||||||
|
/*
|
||||||
|
* When using driver-based BSS selection, we may not know the
|
||||||
|
* BSSID with which we are currently trying to associate. We
|
||||||
|
* need to notify the driver of this disconnection even in such
|
||||||
|
* a case, so use the all zeros address here.
|
||||||
|
*/
|
||||||
|
addr = wpa_s->bssid;
|
||||||
|
zero_addr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr) {
|
||||||
|
wpa_drv_disassociate(wpa_s, addr, reason_code);
|
||||||
os_memset(&event, 0, sizeof(event));
|
os_memset(&event, 0, sizeof(event));
|
||||||
event.disassoc_info.reason_code = (u16) reason_code;
|
event.disassoc_info.reason_code = (u16) reason_code;
|
||||||
event.disassoc_info.locally_generated = 1;
|
event.disassoc_info.locally_generated = 1;
|
||||||
wpa_supplicant_event(wpa_s, EVENT_DISASSOC, &event);
|
wpa_supplicant_event(wpa_s, EVENT_DISASSOC, &event);
|
||||||
|
if (zero_addr)
|
||||||
|
addr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_supplicant_clear_connection(wpa_s, addr);
|
wpa_supplicant_clear_connection(wpa_s, addr);
|
||||||
|
@ -1721,14 +1745,38 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
|
||||||
{
|
{
|
||||||
u8 *addr = NULL;
|
u8 *addr = NULL;
|
||||||
union wpa_event_data event;
|
union wpa_event_data event;
|
||||||
|
int zero_addr = 0;
|
||||||
|
|
||||||
if (!is_zero_ether_addr(wpa_s->bssid)) {
|
wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
|
||||||
wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code);
|
" pending_bssid=" MACSTR " reason=%d state=%s",
|
||||||
|
MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
|
||||||
|
reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
|
||||||
|
|
||||||
|
if (!is_zero_ether_addr(wpa_s->bssid))
|
||||||
addr = wpa_s->bssid;
|
addr = wpa_s->bssid;
|
||||||
|
else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
|
||||||
|
(wpa_s->wpa_state == WPA_AUTHENTICATING ||
|
||||||
|
wpa_s->wpa_state == WPA_ASSOCIATING))
|
||||||
|
addr = wpa_s->pending_bssid;
|
||||||
|
else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
|
||||||
|
/*
|
||||||
|
* When using driver-based BSS selection, we may not know the
|
||||||
|
* BSSID with which we are currently trying to associate. We
|
||||||
|
* need to notify the driver of this disconnection even in such
|
||||||
|
* a case, so use the all zeros address here.
|
||||||
|
*/
|
||||||
|
addr = wpa_s->bssid;
|
||||||
|
zero_addr = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr) {
|
||||||
|
wpa_drv_deauthenticate(wpa_s, addr, reason_code);
|
||||||
os_memset(&event, 0, sizeof(event));
|
os_memset(&event, 0, sizeof(event));
|
||||||
event.deauth_info.reason_code = (u16) reason_code;
|
event.deauth_info.reason_code = (u16) reason_code;
|
||||||
event.deauth_info.locally_generated = 1;
|
event.deauth_info.locally_generated = 1;
|
||||||
wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
|
wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
|
||||||
|
if (zero_addr)
|
||||||
|
addr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wpa_supplicant_clear_connection(wpa_s, addr);
|
wpa_supplicant_clear_connection(wpa_s, addr);
|
||||||
|
|
Loading…
Reference in a new issue