mirror of https://gitee.com/openkylin/linux.git
cfg80211: re-join IBSS when privacy changes
When going from/to a WEP protected IBSS, we need to leave this one and join a new one to take care of the changed capability. Cc: Hong Zhang <henryzhang62@yahoo.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
0bc6b1871c
commit
98d3a7ca92
|
@ -273,6 +273,8 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
|
||||||
struct cfg80211_ibss_params *params,
|
struct cfg80211_ibss_params *params,
|
||||||
struct cfg80211_cached_keys *connkeys);
|
struct cfg80211_cached_keys *connkeys);
|
||||||
void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
|
void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
|
||||||
|
int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
|
||||||
|
struct net_device *dev, bool nowext);
|
||||||
int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
|
int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
|
||||||
struct net_device *dev, bool nowext);
|
struct net_device *dev, bool nowext);
|
||||||
void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
|
void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
|
||||||
|
|
|
@ -169,8 +169,8 @@ void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
|
||||||
wdev_unlock(wdev);
|
wdev_unlock(wdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
|
int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
|
||||||
struct net_device *dev, bool nowext)
|
struct net_device *dev, bool nowext)
|
||||||
{
|
{
|
||||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
int err;
|
int err;
|
||||||
|
|
|
@ -437,6 +437,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
|
||||||
{
|
{
|
||||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||||
int err, i;
|
int err, i;
|
||||||
|
bool rejoin = false;
|
||||||
|
|
||||||
if (!wdev->wext.keys) {
|
if (!wdev->wext.keys) {
|
||||||
wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
|
wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
|
||||||
|
@ -466,8 +467,24 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
|
||||||
|
|
||||||
if (remove) {
|
if (remove) {
|
||||||
err = 0;
|
err = 0;
|
||||||
if (wdev->current_bss)
|
if (wdev->current_bss) {
|
||||||
|
/*
|
||||||
|
* If removing the current TX key, we will need to
|
||||||
|
* join a new IBSS without the privacy bit clear.
|
||||||
|
*/
|
||||||
|
if (idx == wdev->wext.default_key &&
|
||||||
|
wdev->iftype == NL80211_IFTYPE_ADHOC) {
|
||||||
|
__cfg80211_leave_ibss(rdev, wdev->netdev, true);
|
||||||
|
rejoin = true;
|
||||||
|
}
|
||||||
err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
|
err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Applications using wireless extensions expect to be
|
||||||
|
* able to delete keys that don't exist, so allow that.
|
||||||
|
*/
|
||||||
|
if (err == -ENOENT)
|
||||||
|
err = 0;
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (!addr) {
|
if (!addr) {
|
||||||
wdev->wext.keys->params[idx].key_len = 0;
|
wdev->wext.keys->params[idx].key_len = 0;
|
||||||
|
@ -478,12 +495,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
|
||||||
else if (idx == wdev->wext.default_mgmt_key)
|
else if (idx == wdev->wext.default_mgmt_key)
|
||||||
wdev->wext.default_mgmt_key = -1;
|
wdev->wext.default_mgmt_key = -1;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* Applications using wireless extensions expect to be
|
if (!err && rejoin)
|
||||||
* able to delete keys that don't exist, so allow that.
|
err = cfg80211_ibss_wext_join(rdev, wdev);
|
||||||
*/
|
|
||||||
if (err == -ENOENT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -511,11 +525,25 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
|
||||||
if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
|
if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
|
||||||
params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
|
params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
|
||||||
(tx_key || (!addr && wdev->wext.default_key == -1))) {
|
(tx_key || (!addr && wdev->wext.default_key == -1))) {
|
||||||
if (wdev->current_bss)
|
if (wdev->current_bss) {
|
||||||
|
/*
|
||||||
|
* If we are getting a new TX key from not having
|
||||||
|
* had one before we need to join a new IBSS with
|
||||||
|
* the privacy bit set.
|
||||||
|
*/
|
||||||
|
if (wdev->iftype == NL80211_IFTYPE_ADHOC &&
|
||||||
|
wdev->wext.default_key == -1) {
|
||||||
|
__cfg80211_leave_ibss(rdev, wdev->netdev, true);
|
||||||
|
rejoin = true;
|
||||||
|
}
|
||||||
err = rdev->ops->set_default_key(&rdev->wiphy,
|
err = rdev->ops->set_default_key(&rdev->wiphy,
|
||||||
dev, idx);
|
dev, idx);
|
||||||
if (!err)
|
}
|
||||||
|
if (!err) {
|
||||||
wdev->wext.default_key = idx;
|
wdev->wext.default_key = idx;
|
||||||
|
if (rejoin)
|
||||||
|
err = cfg80211_ibss_wext_join(rdev, wdev);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,10 +567,13 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/* devlist mutex needed for possible IBSS re-join */
|
||||||
|
mutex_lock(&rdev->devlist_mtx);
|
||||||
wdev_lock(dev->ieee80211_ptr);
|
wdev_lock(dev->ieee80211_ptr);
|
||||||
err = __cfg80211_set_encryption(rdev, dev, addr, remove,
|
err = __cfg80211_set_encryption(rdev, dev, addr, remove,
|
||||||
tx_key, idx, params);
|
tx_key, idx, params);
|
||||||
wdev_unlock(dev->ieee80211_ptr);
|
wdev_unlock(dev->ieee80211_ptr);
|
||||||
|
mutex_unlock(&rdev->devlist_mtx);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue