aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/wext-compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/wext-compat.c')
-rw-r--r--net/wireless/wext-compat.c98
1 files changed, 85 insertions, 13 deletions
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 561a45cf2a6a..54face3d4424 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -437,6 +437,7 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
437{ 437{
438 struct wireless_dev *wdev = dev->ieee80211_ptr; 438 struct wireless_dev *wdev = dev->ieee80211_ptr;
439 int err, i; 439 int err, i;
440 bool rejoin = false;
440 441
441 if (!wdev->wext.keys) { 442 if (!wdev->wext.keys) {
442 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), 443 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
@@ -466,8 +467,25 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
466 467
467 if (remove) { 468 if (remove) {
468 err = 0; 469 err = 0;
469 if (wdev->current_bss) 470 if (wdev->current_bss) {
471 /*
472 * If removing the current TX key, we will need to
473 * join a new IBSS without the privacy bit clear.
474 */
475 if (idx == wdev->wext.default_key &&
476 wdev->iftype == NL80211_IFTYPE_ADHOC) {
477 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
478 rejoin = true;
479 }
470 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); 480 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
481 }
482 wdev->wext.connect.privacy = false;
483 /*
484 * Applications using wireless extensions expect to be
485 * able to delete keys that don't exist, so allow that.
486 */
487 if (err == -ENOENT)
488 err = 0;
471 if (!err) { 489 if (!err) {
472 if (!addr) { 490 if (!addr) {
473 wdev->wext.keys->params[idx].key_len = 0; 491 wdev->wext.keys->params[idx].key_len = 0;
@@ -478,12 +496,9 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
478 else if (idx == wdev->wext.default_mgmt_key) 496 else if (idx == wdev->wext.default_mgmt_key)
479 wdev->wext.default_mgmt_key = -1; 497 wdev->wext.default_mgmt_key = -1;
480 } 498 }
481 /* 499
482 * Applications using wireless extensions expect to be 500 if (!err && rejoin)
483 * able to delete keys that don't exist, so allow that. 501 err = cfg80211_ibss_wext_join(rdev, wdev);
484 */
485 if (err == -ENOENT)
486 return 0;
487 502
488 return err; 503 return err;
489 } 504 }
@@ -511,11 +526,25 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
511 if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 || 526 if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
512 params->cipher == WLAN_CIPHER_SUITE_WEP104) && 527 params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
513 (tx_key || (!addr && wdev->wext.default_key == -1))) { 528 (tx_key || (!addr && wdev->wext.default_key == -1))) {
514 if (wdev->current_bss) 529 if (wdev->current_bss) {
530 /*
531 * If we are getting a new TX key from not having
532 * had one before we need to join a new IBSS with
533 * the privacy bit set.
534 */
535 if (wdev->iftype == NL80211_IFTYPE_ADHOC &&
536 wdev->wext.default_key == -1) {
537 __cfg80211_leave_ibss(rdev, wdev->netdev, true);
538 rejoin = true;
539 }
515 err = rdev->ops->set_default_key(&rdev->wiphy, 540 err = rdev->ops->set_default_key(&rdev->wiphy,
516 dev, idx); 541 dev, idx);
517 if (!err) 542 }
543 if (!err) {
518 wdev->wext.default_key = idx; 544 wdev->wext.default_key = idx;
545 if (rejoin)
546 err = cfg80211_ibss_wext_join(rdev, wdev);
547 }
519 return err; 548 return err;
520 } 549 }
521 550
@@ -539,10 +568,13 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
539{ 568{
540 int err; 569 int err;
541 570
571 /* devlist mutex needed for possible IBSS re-join */
572 mutex_lock(&rdev->devlist_mtx);
542 wdev_lock(dev->ieee80211_ptr); 573 wdev_lock(dev->ieee80211_ptr);
543 err = __cfg80211_set_encryption(rdev, dev, addr, remove, 574 err = __cfg80211_set_encryption(rdev, dev, addr, remove,
544 tx_key, idx, params); 575 tx_key, idx, params);
545 wdev_unlock(dev->ieee80211_ptr); 576 wdev_unlock(dev->ieee80211_ptr);
577 mutex_unlock(&rdev->devlist_mtx);
546 578
547 return err; 579 return err;
548} 580}
@@ -904,8 +936,6 @@ static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
904 936
905static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions) 937static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
906{ 938{
907 wdev->wext.connect.crypto.wpa_versions = 0;
908
909 if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA | 939 if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
910 IW_AUTH_WPA_VERSION_WPA2| 940 IW_AUTH_WPA_VERSION_WPA2|
911 IW_AUTH_WPA_VERSION_DISABLED)) 941 IW_AUTH_WPA_VERSION_DISABLED))
@@ -933,8 +963,6 @@ static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
933 963
934static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher) 964static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
935{ 965{
936 wdev->wext.connect.crypto.cipher_group = 0;
937
938 if (cipher & IW_AUTH_CIPHER_WEP40) 966 if (cipher & IW_AUTH_CIPHER_WEP40)
939 wdev->wext.connect.crypto.cipher_group = 967 wdev->wext.connect.crypto.cipher_group =
940 WLAN_CIPHER_SUITE_WEP40; 968 WLAN_CIPHER_SUITE_WEP40;
@@ -950,6 +978,8 @@ static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher)
950 else if (cipher & IW_AUTH_CIPHER_AES_CMAC) 978 else if (cipher & IW_AUTH_CIPHER_AES_CMAC)
951 wdev->wext.connect.crypto.cipher_group = 979 wdev->wext.connect.crypto.cipher_group =
952 WLAN_CIPHER_SUITE_AES_CMAC; 980 WLAN_CIPHER_SUITE_AES_CMAC;
981 else if (cipher & IW_AUTH_CIPHER_NONE)
982 wdev->wext.connect.crypto.cipher_group = 0;
953 else 983 else
954 return -EINVAL; 984 return -EINVAL;
955 985
@@ -1372,6 +1402,47 @@ int cfg80211_wext_giwessid(struct net_device *dev,
1372} 1402}
1373EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); 1403EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
1374 1404
1405int cfg80211_wext_siwpmksa(struct net_device *dev,
1406 struct iw_request_info *info,
1407 struct iw_point *data, char *extra)
1408{
1409 struct wireless_dev *wdev = dev->ieee80211_ptr;
1410 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1411 struct cfg80211_pmksa cfg_pmksa;
1412 struct iw_pmksa *pmksa = (struct iw_pmksa *)extra;
1413
1414 memset(&cfg_pmksa, 0, sizeof(struct cfg80211_pmksa));
1415
1416 if (wdev->iftype != NL80211_IFTYPE_STATION)
1417 return -EINVAL;
1418
1419 cfg_pmksa.bssid = pmksa->bssid.sa_data;
1420 cfg_pmksa.pmkid = pmksa->pmkid;
1421
1422 switch (pmksa->cmd) {
1423 case IW_PMKSA_ADD:
1424 if (!rdev->ops->set_pmksa)
1425 return -EOPNOTSUPP;
1426
1427 return rdev->ops->set_pmksa(&rdev->wiphy, dev, &cfg_pmksa);
1428
1429 case IW_PMKSA_REMOVE:
1430 if (!rdev->ops->del_pmksa)
1431 return -EOPNOTSUPP;
1432
1433 return rdev->ops->del_pmksa(&rdev->wiphy, dev, &cfg_pmksa);
1434
1435 case IW_PMKSA_FLUSH:
1436 if (!rdev->ops->flush_pmksa)
1437 return -EOPNOTSUPP;
1438
1439 return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
1440
1441 default:
1442 return -EOPNOTSUPP;
1443 }
1444}
1445
1375static const iw_handler cfg80211_handlers[] = { 1446static const iw_handler cfg80211_handlers[] = {
1376 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, 1447 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
1377 [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq, 1448 [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq,
@@ -1404,6 +1475,7 @@ static const iw_handler cfg80211_handlers[] = {
1404 [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth, 1475 [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth,
1405 [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth, 1476 [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth,
1406 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext, 1477 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext,
1478 [IW_IOCTL_IDX(SIOCSIWPMKSA)] = (iw_handler) cfg80211_wext_siwpmksa,
1407}; 1479};
1408 1480
1409const struct iw_handler_def cfg80211_wext_handler = { 1481const struct iw_handler_def cfg80211_wext_handler = {