cfg80211: fix SME association after disassociation
authorJohannes Berg <johannes@sipsolutions.net>
Thu, 6 Aug 2009 18:41:34 +0000 (20:41 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 14 Aug 2009 13:12:47 +0000 (09:12 -0400)
When an AP disassociates us, we currently go into a weird
state because the SME doesn't handle authenticated but not
associated well unless it's within its own state machine,
it can't recover from that. However, it shouldn't need to,
since we don't do any decisions in it really -- so when we
get disconnected, simply deauthenticate too.

Reported-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/wireless/sme.c

index 8a7dcbf9060233bbf9bb7f5ef7a3a2af11caa8d3..0b776b769c0f63ac7d885e010082b572cf2e8aee 100644 (file)
@@ -570,10 +570,30 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
        wdev->ssid_len = 0;
 
        if (wdev->conn) {
+               const u8 *bssid;
+               int ret;
+
                kfree(wdev->conn->ie);
                wdev->conn->ie = NULL;
                kfree(wdev->conn);
                wdev->conn = NULL;
+
+               /*
+                * If this disconnect was due to a disassoc, we
+                * we might still have an auth BSS around. For
+                * the userspace SME that's currently expected,
+                * but for the kernel SME (nl80211 CONNECT or
+                * wireless extensions) we want to clear up all
+                * state.
+                */
+               for (i = 0; i < MAX_AUTH_BSSES; i++) {
+                       if (!wdev->auth_bsses[i])
+                               continue;
+                       bssid = wdev->auth_bsses[i]->pub.bssid;
+                       ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
+                                               WLAN_REASON_DEAUTH_LEAVING);
+                       WARN(ret, "deauth failed: %d\n", ret);
+               }
        }
 
        nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);