nl80211: Ignore deauth/disassoc event during Connect reassociation
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 24 Mar 2016 20:33:48 +0000 (22:33 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 24 Mar 2016 20:35:10 +0000 (22:35 +0200)
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>
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h
src/drivers/driver_nl80211_event.c

index baa418b..798e694 100644 (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;
index 3f65569..b0d2b6d 100644 (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;
index dae203a..bd16edb 100644 (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) {