Commit 24b6b15f authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville

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: default avatarJouni Malinen <j@w1.fi>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent af65cd96
...@@ -446,12 +446,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, ...@@ -446,12 +446,23 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
struct cfg80211_assoc_request req; struct cfg80211_assoc_request req;
struct cfg80211_internal_bss *bss; struct cfg80211_internal_bss *bss;
int i, err, slot = -1; int i, err, slot = -1;
bool was_connected = false;
ASSERT_WDEV_LOCK(wdev); ASSERT_WDEV_LOCK(wdev);
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
if (wdev->current_bss) if (wdev->current_bss && prev_bssid &&
memcmp(wdev->current_bss->pub.bssid, prev_bssid, ETH_ALEN) == 0) {
/*
* Trying to reassociate: Allow this to proceed and let the old
* association to be dropped when the new one is completed.
*/
if (wdev->sme_state == CFG80211_SME_CONNECTED) {
was_connected = true;
wdev->sme_state = CFG80211_SME_CONNECTING;
}
} else if (wdev->current_bss)
return -EALREADY; return -EALREADY;
req.ie = ie; req.ie = ie;
...@@ -461,8 +472,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, ...@@ -461,8 +472,11 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
req.prev_bssid = prev_bssid; req.prev_bssid = prev_bssid;
req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (!req.bss) if (!req.bss) {
if (was_connected)
wdev->sme_state = CFG80211_SME_CONNECTED;
return -ENOENT; return -ENOENT;
}
bss = bss_from_pub(req.bss); bss = bss_from_pub(req.bss);
...@@ -480,6 +494,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, ...@@ -480,6 +494,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
err = rdev->ops->assoc(&rdev->wiphy, dev, &req); err = rdev->ops->assoc(&rdev->wiphy, dev, &req);
out: out:
if (err && was_connected)
wdev->sme_state = CFG80211_SME_CONNECTED;
/* still a reference in wdev->auth_bsses[slot] */ /* still a reference in wdev->auth_bsses[slot] */
cfg80211_put_bss(req.bss); cfg80211_put_bss(req.bss);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment