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