summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-08-06 20:41:34 +0200
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:12:47 -0400
commitb6f0b639089fb160b10984ac56e07e7043dabad7 (patch)
treea0f1b09c77be822d41df7d26772e1e3b57ad63fe /net/wireless
parente458b8a22d33eef62765c9f89889efeb4041f073 (diff)
downloadlinux-b6f0b639089fb160b10984ac56e07e7043dabad7.tar.bz2
cfg80211: fix SME association after disassociation
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>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/sme.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 8a7dcbf90602..0b776b769c0f 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -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);