aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-12-02 06:43:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-22 13:31:17 -0500
commit5fba4af32ceeb935b3926714df9a64a33c2c9cf5 (patch)
tree0f9fe83dade3dfd394bfecd2b675e4e600ec350b /net/wireless/mlme.c
parentf38fd12fa7b7b98e158a9b31d388da34eef25c22 (diff)
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/mlme.c')
-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 1001db4912f7..acaeaa784d68 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -137,22 +137,23 @@ void __cfg80211_send_deauth(struct net_device *dev,
137 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 137 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
138 const u8 *bssid = mgmt->bssid; 138 const u8 *bssid = mgmt->bssid;
139 int i; 139 int i;
140 bool found = false;
140 141
141 ASSERT_WDEV_LOCK(wdev); 142 ASSERT_WDEV_LOCK(wdev);
142 143
143 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
144
145 if (wdev->current_bss && 144 if (wdev->current_bss &&
146 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) { 145 memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) {
147 cfg80211_unhold_bss(wdev->current_bss); 146 cfg80211_unhold_bss(wdev->current_bss);
148 cfg80211_put_bss(&wdev->current_bss->pub); 147 cfg80211_put_bss(&wdev->current_bss->pub);
149 wdev->current_bss = NULL; 148 wdev->current_bss = NULL;
149 found = true;
150 } else for (i = 0; i < MAX_AUTH_BSSES; i++) { 150 } else for (i = 0; i < MAX_AUTH_BSSES; i++) {
151 if (wdev->auth_bsses[i] && 151 if (wdev->auth_bsses[i] &&
152 memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) { 152 memcmp(wdev->auth_bsses[i]->pub.bssid, bssid, ETH_ALEN) == 0) {
153 cfg80211_unhold_bss(wdev->auth_bsses[i]); 153 cfg80211_unhold_bss(wdev->auth_bsses[i]);
154 cfg80211_put_bss(&wdev->auth_bsses[i]->pub); 154 cfg80211_put_bss(&wdev->auth_bsses[i]->pub);
155 wdev->auth_bsses[i] = NULL; 155 wdev->auth_bsses[i] = NULL;
156 found = true;
156 break; 157 break;
157 } 158 }
158 if (wdev->authtry_bsses[i] && 159 if (wdev->authtry_bsses[i] &&
@@ -160,10 +161,16 @@ void __cfg80211_send_deauth(struct net_device *dev,
160 cfg80211_unhold_bss(wdev->authtry_bsses[i]); 161 cfg80211_unhold_bss(wdev->authtry_bsses[i]);
161 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub); 162 cfg80211_put_bss(&wdev->authtry_bsses[i]->pub);
162 wdev->authtry_bsses[i] = NULL; 163 wdev->authtry_bsses[i] = NULL;
164 found = true;
163 break; 165 break;
164 } 166 }
165 } 167 }
166 168
169 if (!found)
170 return;
171
172 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL);
173
167 if (wdev->sme_state == CFG80211_SME_CONNECTED) { 174 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
168 u16 reason_code; 175 u16 reason_code;
169 bool from_ap; 176 bool from_ap;