nl80211: Ignore deauth/disassoc event during Connect reassociation

cfg80211 reports a deauth/disassoc event when internally clearing
connection with the previous BSS. Ignore that event to allow the new
connect command to complete.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2016-03-24 22:33:48 +02:00 committed by Jouni Malinen
parent 6a5ee810a3
commit 1126c0787d
3 changed files with 23 additions and 0 deletions

View File

@ -4841,12 +4841,14 @@ static int nl80211_connect_common(struct wpa_driver_nl80211_data *drv,
return -1;
}
drv->connect_reassoc = 0;
if (params->prev_bssid) {
wpa_printf(MSG_DEBUG, " * prev_bssid=" MACSTR,
MAC2STR(params->prev_bssid));
if (nla_put(msg, NL80211_ATTR_PREV_BSSID, ETH_ALEN,
params->prev_bssid))
return -1;
drv->connect_reassoc = 1;
}
return 0;

View File

@ -151,6 +151,7 @@ struct wpa_driver_nl80211_data {
unsigned int get_pref_freq_list:1;
unsigned int set_prob_oper_freq:1;
unsigned int scan_vendor_cmd_avail:1;
unsigned int connect_reassoc:1;
u64 vendor_scan_cookie;
u64 remain_on_chan_cookie;

View File

@ -285,6 +285,8 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv,
return;
}
drv->connect_reassoc = 0;
status_code = status ? nla_get_u16(status) : WLAN_STATUS_SUCCESS;
if (cmd == NL80211_CMD_CONNECT) {
@ -670,6 +672,24 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
return;
}
if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME) &&
drv->connect_reassoc && drv->associated &&
os_memcmp(bssid, drv->prev_bssid, ETH_ALEN) == 0 &&
os_memcmp(bssid, drv->auth_attempt_bssid, ETH_ALEN) != 0) {
/*
* Avoid issues with some roaming cases where
* disconnection event for the old AP may show up after
* we have started connection with the new AP.
*/
wpa_printf(MSG_DEBUG,
"nl80211: Ignore deauth/disassoc event from old AP "
MACSTR
" when already connecting with " MACSTR,
MAC2STR(bssid),
MAC2STR(drv->auth_attempt_bssid));
return;
}
if (drv->associated != 0 &&
os_memcmp(bssid, drv->bssid, ETH_ALEN) != 0 &&
os_memcmp(bssid, drv->auth_bssid, ETH_ALEN) != 0) {