aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2009-11-19 06:45:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-19 11:09:02 -0500
commita58ce43f2fb17b728395ff530f019ca53c80145f (patch)
tree1de5d2680d42de12902ccb85e99bc86f63eebf58 /net
parent7351c6bd482712e5e3ec9dffc547de0e0863efb0 (diff)
mac80211: avoid spurious deauth frames/messages
With WEXT, it happens frequently that the SME requests an authentication but then deauthenticates right away because some new parameters came along. Every time this happens we print a deauth message and send a deauth frame, but both of that is rather confusing. Avoid it by aborting the authentication process silently, and telling cfg80211 about that. The patch looks larger than it really is: __cfg80211_auth_remove() is split out from cfg80211_send_auth_timeout(), there's no new code except __cfg80211_auth_canceled() (a one-liner) and the mac80211 bits (7 new lines of code). Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mlme.c17
-rw-r--r--net/wireless/mlme.c36
2 files changed, 42 insertions, 11 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f399547306c3..6dc7b5ad9a41 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2508,6 +2508,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2508 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2508 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2509 struct ieee80211_mgd_work *wk; 2509 struct ieee80211_mgd_work *wk;
2510 const u8 *bssid = NULL; 2510 const u8 *bssid = NULL;
2511 bool not_auth_yet = false;
2511 2512
2512 mutex_lock(&ifmgd->mtx); 2513 mutex_lock(&ifmgd->mtx);
2513 2514
@@ -2517,6 +2518,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2517 } else list_for_each_entry(wk, &ifmgd->work_list, list) { 2518 } else list_for_each_entry(wk, &ifmgd->work_list, list) {
2518 if (&wk->bss->cbss == req->bss) { 2519 if (&wk->bss->cbss == req->bss) {
2519 bssid = req->bss->bssid; 2520 bssid = req->bss->bssid;
2521 if (wk->state == IEEE80211_MGD_STATE_PROBE)
2522 not_auth_yet = true;
2520 list_del(&wk->list); 2523 list_del(&wk->list);
2521 kfree(wk); 2524 kfree(wk);
2522 break; 2525 break;
@@ -2524,6 +2527,20 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2524 } 2527 }
2525 2528
2526 /* 2529 /*
2530 * If somebody requests authentication and we haven't
2531 * sent out an auth frame yet there's no need to send
2532 * out a deauth frame either. If the state was PROBE,
2533 * then this is the case. If it's AUTH we have sent a
2534 * frame, and if it's IDLE we have completed the auth
2535 * process already.
2536 */
2537 if (not_auth_yet) {
2538 mutex_unlock(&ifmgd->mtx);
2539 __cfg80211_auth_canceled(sdata->dev, bssid);
2540 return 0;
2541 }
2542
2543 /*
2527 * cfg80211 should catch this ... but it's racy since 2544 * cfg80211 should catch this ... but it's racy since
2528 * we can receive a deauth frame, process it, hand it 2545 * we can receive a deauth frame, process it, hand it
2529 * to cfg80211 while that's in a locked section already 2546 * to cfg80211 while that's in a locked section already
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 622af5649b9a..1001db4912f7 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -243,21 +243,12 @@ void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
243} 243}
244EXPORT_SYMBOL(cfg80211_send_disassoc); 244EXPORT_SYMBOL(cfg80211_send_disassoc);
245 245
246void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 246static void __cfg80211_auth_remove(struct wireless_dev *wdev, const u8 *addr)
247{ 247{
248 struct wireless_dev *wdev = dev->ieee80211_ptr;
249 struct wiphy *wiphy = wdev->wiphy;
250 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
251 int i; 248 int i;
252 bool done = false; 249 bool done = false;
253 250
254 wdev_lock(wdev); 251 ASSERT_WDEV_LOCK(wdev);
255
256 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
257 if (wdev->sme_state == CFG80211_SME_CONNECTING)
258 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
259 WLAN_STATUS_UNSPECIFIED_FAILURE,
260 false, NULL);
261 252
262 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 253 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
263 if (wdev->authtry_bsses[i] && 254 if (wdev->authtry_bsses[i] &&
@@ -272,6 +263,29 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
272 } 263 }
273 264
274 WARN_ON(!done); 265 WARN_ON(!done);
266}
267
268void __cfg80211_auth_canceled(struct net_device *dev, const u8 *addr)
269{
270 __cfg80211_auth_remove(dev->ieee80211_ptr, addr);
271}
272EXPORT_SYMBOL(__cfg80211_auth_canceled);
273
274void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
275{
276 struct wireless_dev *wdev = dev->ieee80211_ptr;
277 struct wiphy *wiphy = wdev->wiphy;
278 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
279
280 wdev_lock(wdev);
281
282 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
283 if (wdev->sme_state == CFG80211_SME_CONNECTING)
284 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
285 WLAN_STATUS_UNSPECIFIED_FAILURE,
286 false, NULL);
287
288 __cfg80211_auth_remove(wdev, addr);
275 289
276 wdev_unlock(wdev); 290 wdev_unlock(wdev);
277} 291}