summaryrefslogtreecommitdiff
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-12-02 12:43:42 +0100
committerJohn W. Linville <linville@tuxdriver.com>2009-12-22 13:31:17 -0500
commit5fba4af32ceeb935b3926714df9a64a33c2c9cf5 (patch)
tree0f9fe83dade3dfd394bfecd2b675e4e600ec350b /net/wireless
parentf38fd12fa7b7b98e158a9b31d388da34eef25c22 (diff)
downloadlinux-3.10-5fba4af32ceeb935b3926714df9a64a33c2c9cf5.tar.gz
linux-3.10-5fba4af32ceeb935b3926714df9a64a33c2c9cf5.tar.bz2
linux-3.10-5fba4af32ceeb935b3926714df9a64a33c2c9cf5.zip
cfg80211: avoid sending spurious deauth to userspace
Before commit ca9034592823e8179511e48a78731f95bfdd766c Author: Holger Schurig <hs4233@mail.mn-solutions.de> Date: Tue Oct 13 13:45:28 2009 +0200 cfg80211: remove warning in deauth case we assumed that drivers never give us spurious deauth frames because they filter them out based on the auth state they keep track of. This turned out to be racy, because userspace might deauth while the AP is also sending a deauth frame, so the warning was removed. However, in that case we should not tell userspace about the AP's frame if it requested deauth "first", where "first" means it came to cfg80211 first. 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/mlme.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 1001db4912f..acaeaa784d6 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -137,22 +137,23 @@ void __cfg80211_send_deauth(struct net_device *dev,
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
const u8 *bssid = mgmt->bssid;
int i;
+ bool found = false;
ASSERT_WDEV_LOCK(wdev);
- nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
-
if (wdev->current_bss &&
memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
cfg80211_unhold_bss(wdev->current_bss);
cfg80211_put_bss(&wdev->current_bss->pub);
wdev->current_bss = NULL;
+ found = true;
} else for (i = 0; i < MAX_AUTH_BSSES; i++) {
if (wdev->auth_bsses[i] &&
memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
cfg80211_unhold_bss(wdev->auth_bsses[i]);
cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
wdev->auth_bsses[i] = NULL;
+ found = true;
break;
}
if (wdev->authtry_bsses[i] &&
@@ -160,10 +161,16 @@ void __cfg80211_send_deauth(struct net_device *dev,
cfg80211_unhold_bss(wdev->authtry_bsses[i]);
cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
wdev->authtry_bsses[i] = NULL;
+ found = true;
break;
}
}
+ if (!found)
+ return;
+
+ nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
+
if (wdev->sme_state == CFG80211_SME_CONNECTED) {
u16 reason_code;
bool from_ap;