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:
Jouni Malinen 2012-11-05 16:42:28 +02:00 committed by Jouni Malinen
parent e50d01b4f1
commit 42d235477f

View file

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