aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2009-11-17 14:35:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-18 17:09:24 -0500
commit24b6b15f7d07d26330f73057d618089976a08792 (patch)
tree52bf74ad76afae6fecce3f5ff75dfc027971d9b2 /net
parentaf65cd96dd4ea8ea5adc6ee850e61a407cd1067a (diff)
cfg80211: Allow reassociation in associated state
cfg80211 rejects all association requests when in associated state. This prevents clean roaming within an ESS since one would first need to disassociate before being able to request reassociation. Accept the reassociation request and let the old association to be dropped when the new one is completed. This fixes nl80211-based roaming with the current snapshot version of wpa_supplicant (that has code for requesting reassociation explicitly withthe previous BSSID attribute). Signed-off-by: Jouni Malinen <j@w1.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/mlme.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 2610b746effa..622af5649b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -446,12 +446,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
446 struct cfg80211_assoc_request req; 446 struct cfg80211_assoc_request req;
447 struct cfg80211_internal_bss *bss; 447 struct cfg80211_internal_bss *bss;
448 int i, err, slot = -1; 448 int i, err, slot = -1;
449 bool was_connected = false;
449 450
450 ASSERT_WDEV_LOCK(wdev); 451 ASSERT_WDEV_LOCK(wdev);
451 452
452 memset(&req, 0, sizeof(req)); 453 memset(&req, 0, sizeof(req));
453 454
454 if (wdev->current_bss) 455 if (wdev->current_bss && prev_bssid &&
456 memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
457 /*
458 * Trying to reassociate: Allow this to proceed and let the old
459 * association to be dropped when the new one is completed.
460 */
461 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
462 was_connected = true;
463 wdev->sme_state = CFG80211_SME_CONNECTING;
464 }
465 } else if (wdev->current_bss)
455 return -EALREADY; 466 return -EALREADY;
456 467
457 req.ie = ie; 468 req.ie = ie;
@@ -461,8 +472,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
461 req.prev_bssid = prev_bssid; 472 req.prev_bssid = prev_bssid;
462 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 473 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
463 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 474 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
464 if (!req.bss) 475 if (!req.bss) {
476 if (was_connected)
477 wdev->sme_state = CFG80211_SME_CONNECTED;
465 return -ENOENT; 478 return -ENOENT;
479 }
466 480
467 bss = bss_from_pub(req.bss); 481 bss = bss_from_pub(req.bss);
468 482
@@ -480,6 +494,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
480 494
481 err = rdev->ops->assoc(&rdev->wiphy, dev, &req); 495 err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
482 out: 496 out:
497 if (err && was_connected)
498 wdev->sme_state = CFG80211_SME_CONNECTED;
483 /* still a reference in wdev->auth_bsses[slot] */ 499 /* still a reference in wdev->auth_bsses[slot] */
484 cfg80211_put_bss(req.bss); 500 cfg80211_put_bss(req.bss);
485 return err; 501 return err;