diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-04-15 16:21:34 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-15 16:21:34 -0400 |
commit | 5c01d5669356e13f0fb468944c1dd4c6a7e978ad (patch) | |
tree | fa43345288d7b25fac92b3b35360a177c4947313 /net/wireless | |
parent | fea069152614cdeefba4b2bf80afcddb9c217fc8 (diff) | |
parent | a5e944f1d955f3819503348426763e21e0413ba6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
Documentation/feature-removal-schedule.txt
drivers/net/wireless/ath/ath5k/phy.c
drivers/net/wireless/wl12xx/wl1271_main.c
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/core.h | 15 | ||||
-rw-r--r-- | net/wireless/mlme.c | 39 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 22 | ||||
-rw-r--r-- | net/wireless/reg.c | 6 | ||||
-rw-r--r-- | net/wireless/sme.c | 15 | ||||
-rw-r--r-- | net/wireless/util.c | 24 |
6 files changed, 86 insertions, 35 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h index d52da913145a..b2234b436ead 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -293,13 +293,15 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
293 | const u8 *bssid, | 293 | const u8 *bssid, |
294 | const u8 *ssid, int ssid_len, | 294 | const u8 *ssid, int ssid_len, |
295 | const u8 *ie, int ie_len, | 295 | const u8 *ie, int ie_len, |
296 | const u8 *key, int key_len, int key_idx); | 296 | const u8 *key, int key_len, int key_idx, |
297 | bool local_state_change); | ||
297 | int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | 298 | int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, |
298 | struct net_device *dev, struct ieee80211_channel *chan, | 299 | struct net_device *dev, struct ieee80211_channel *chan, |
299 | enum nl80211_auth_type auth_type, const u8 *bssid, | 300 | enum nl80211_auth_type auth_type, const u8 *bssid, |
300 | const u8 *ssid, int ssid_len, | 301 | const u8 *ssid, int ssid_len, |
301 | const u8 *ie, int ie_len, | 302 | const u8 *ie, int ie_len, |
302 | const u8 *key, int key_len, int key_idx); | 303 | const u8 *key, int key_len, int key_idx, |
304 | bool local_state_change); | ||
303 | int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | 305 | int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, |
304 | struct net_device *dev, | 306 | struct net_device *dev, |
305 | struct ieee80211_channel *chan, | 307 | struct ieee80211_channel *chan, |
@@ -315,13 +317,16 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
315 | struct cfg80211_crypto_settings *crypt); | 317 | struct cfg80211_crypto_settings *crypt); |
316 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 318 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
317 | struct net_device *dev, const u8 *bssid, | 319 | struct net_device *dev, const u8 *bssid, |
318 | const u8 *ie, int ie_len, u16 reason); | 320 | const u8 *ie, int ie_len, u16 reason, |
321 | bool local_state_change); | ||
319 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 322 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
320 | struct net_device *dev, const u8 *bssid, | 323 | struct net_device *dev, const u8 *bssid, |
321 | const u8 *ie, int ie_len, u16 reason); | 324 | const u8 *ie, int ie_len, u16 reason, |
325 | bool local_state_change); | ||
322 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 326 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
323 | struct net_device *dev, const u8 *bssid, | 327 | struct net_device *dev, const u8 *bssid, |
324 | const u8 *ie, int ie_len, u16 reason); | 328 | const u8 *ie, int ie_len, u16 reason, |
329 | bool local_state_change); | ||
325 | void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, | 330 | void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, |
326 | struct net_device *dev); | 331 | struct net_device *dev); |
327 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 332 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 4bb734a95f57..48ead6f0426d 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -378,7 +378,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
378 | const u8 *bssid, | 378 | const u8 *bssid, |
379 | const u8 *ssid, int ssid_len, | 379 | const u8 *ssid, int ssid_len, |
380 | const u8 *ie, int ie_len, | 380 | const u8 *ie, int ie_len, |
381 | const u8 *key, int key_len, int key_idx) | 381 | const u8 *key, int key_len, int key_idx, |
382 | bool local_state_change) | ||
382 | { | 383 | { |
383 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 384 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
384 | struct cfg80211_auth_request req; | 385 | struct cfg80211_auth_request req; |
@@ -408,6 +409,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
408 | 409 | ||
409 | memset(&req, 0, sizeof(req)); | 410 | memset(&req, 0, sizeof(req)); |
410 | 411 | ||
412 | req.local_state_change = local_state_change; | ||
411 | req.ie = ie; | 413 | req.ie = ie; |
412 | req.ie_len = ie_len; | 414 | req.ie_len = ie_len; |
413 | req.auth_type = auth_type; | 415 | req.auth_type = auth_type; |
@@ -434,12 +436,18 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
434 | goto out; | 436 | goto out; |
435 | } | 437 | } |
436 | 438 | ||
437 | wdev->authtry_bsses[slot] = bss; | 439 | if (local_state_change) |
440 | wdev->auth_bsses[slot] = bss; | ||
441 | else | ||
442 | wdev->authtry_bsses[slot] = bss; | ||
438 | cfg80211_hold_bss(bss); | 443 | cfg80211_hold_bss(bss); |
439 | 444 | ||
440 | err = rdev->ops->auth(&rdev->wiphy, dev, &req); | 445 | err = rdev->ops->auth(&rdev->wiphy, dev, &req); |
441 | if (err) { | 446 | if (err) { |
442 | wdev->authtry_bsses[slot] = NULL; | 447 | if (local_state_change) |
448 | wdev->auth_bsses[slot] = NULL; | ||
449 | else | ||
450 | wdev->authtry_bsses[slot] = NULL; | ||
443 | cfg80211_unhold_bss(bss); | 451 | cfg80211_unhold_bss(bss); |
444 | } | 452 | } |
445 | 453 | ||
@@ -454,14 +462,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
454 | enum nl80211_auth_type auth_type, const u8 *bssid, | 462 | enum nl80211_auth_type auth_type, const u8 *bssid, |
455 | const u8 *ssid, int ssid_len, | 463 | const u8 *ssid, int ssid_len, |
456 | const u8 *ie, int ie_len, | 464 | const u8 *ie, int ie_len, |
457 | const u8 *key, int key_len, int key_idx) | 465 | const u8 *key, int key_len, int key_idx, |
466 | bool local_state_change) | ||
458 | { | 467 | { |
459 | int err; | 468 | int err; |
460 | 469 | ||
461 | wdev_lock(dev->ieee80211_ptr); | 470 | wdev_lock(dev->ieee80211_ptr); |
462 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 471 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
463 | ssid, ssid_len, ie, ie_len, | 472 | ssid, ssid_len, ie, ie_len, |
464 | key, key_len, key_idx); | 473 | key, key_len, key_idx, local_state_change); |
465 | wdev_unlock(dev->ieee80211_ptr); | 474 | wdev_unlock(dev->ieee80211_ptr); |
466 | 475 | ||
467 | return err; | 476 | return err; |
@@ -555,7 +564,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
555 | 564 | ||
556 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 565 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
557 | struct net_device *dev, const u8 *bssid, | 566 | struct net_device *dev, const u8 *bssid, |
558 | const u8 *ie, int ie_len, u16 reason) | 567 | const u8 *ie, int ie_len, u16 reason, |
568 | bool local_state_change) | ||
559 | { | 569 | { |
560 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 570 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
561 | struct cfg80211_deauth_request req; | 571 | struct cfg80211_deauth_request req; |
@@ -565,6 +575,7 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
565 | 575 | ||
566 | memset(&req, 0, sizeof(req)); | 576 | memset(&req, 0, sizeof(req)); |
567 | req.reason_code = reason; | 577 | req.reason_code = reason; |
578 | req.local_state_change = local_state_change; | ||
568 | req.ie = ie; | 579 | req.ie = ie; |
569 | req.ie_len = ie_len; | 580 | req.ie_len = ie_len; |
570 | if (wdev->current_bss && | 581 | if (wdev->current_bss && |
@@ -591,13 +602,15 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
591 | 602 | ||
592 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 603 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
593 | struct net_device *dev, const u8 *bssid, | 604 | struct net_device *dev, const u8 *bssid, |
594 | const u8 *ie, int ie_len, u16 reason) | 605 | const u8 *ie, int ie_len, u16 reason, |
606 | bool local_state_change) | ||
595 | { | 607 | { |
596 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 608 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
597 | int err; | 609 | int err; |
598 | 610 | ||
599 | wdev_lock(wdev); | 611 | wdev_lock(wdev); |
600 | err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason); | 612 | err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason, |
613 | local_state_change); | ||
601 | wdev_unlock(wdev); | 614 | wdev_unlock(wdev); |
602 | 615 | ||
603 | return err; | 616 | return err; |
@@ -605,7 +618,8 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
605 | 618 | ||
606 | static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 619 | static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
607 | struct net_device *dev, const u8 *bssid, | 620 | struct net_device *dev, const u8 *bssid, |
608 | const u8 *ie, int ie_len, u16 reason) | 621 | const u8 *ie, int ie_len, u16 reason, |
622 | bool local_state_change) | ||
609 | { | 623 | { |
610 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 624 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
611 | struct cfg80211_disassoc_request req; | 625 | struct cfg80211_disassoc_request req; |
@@ -620,6 +634,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | |||
620 | 634 | ||
621 | memset(&req, 0, sizeof(req)); | 635 | memset(&req, 0, sizeof(req)); |
622 | req.reason_code = reason; | 636 | req.reason_code = reason; |
637 | req.local_state_change = local_state_change; | ||
623 | req.ie = ie; | 638 | req.ie = ie; |
624 | req.ie_len = ie_len; | 639 | req.ie_len = ie_len; |
625 | if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) | 640 | if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) |
@@ -632,13 +647,15 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | |||
632 | 647 | ||
633 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 648 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
634 | struct net_device *dev, const u8 *bssid, | 649 | struct net_device *dev, const u8 *bssid, |
635 | const u8 *ie, int ie_len, u16 reason) | 650 | const u8 *ie, int ie_len, u16 reason, |
651 | bool local_state_change) | ||
636 | { | 652 | { |
637 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 653 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
638 | int err; | 654 | int err; |
639 | 655 | ||
640 | wdev_lock(wdev); | 656 | wdev_lock(wdev); |
641 | err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason); | 657 | err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason, |
658 | local_state_change); | ||
642 | wdev_unlock(wdev); | 659 | wdev_unlock(wdev); |
643 | 660 | ||
644 | return err; | 661 | return err; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 596bf189549a..356a84a5daee 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -151,6 +151,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
151 | [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, | 151 | [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, |
152 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, | 152 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, |
153 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, | 153 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, |
154 | [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, | ||
154 | }; | 155 | }; |
155 | 156 | ||
156 | /* policy for the attributes */ | 157 | /* policy for the attributes */ |
@@ -2097,7 +2098,8 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | |||
2097 | goto out_rtnl; | 2098 | goto out_rtnl; |
2098 | 2099 | ||
2099 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2100 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
2100 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) { | 2101 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && |
2102 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { | ||
2101 | err = -EINVAL; | 2103 | err = -EINVAL; |
2102 | goto out; | 2104 | goto out; |
2103 | } | 2105 | } |
@@ -3393,6 +3395,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
3393 | int err, ssid_len, ie_len = 0; | 3395 | int err, ssid_len, ie_len = 0; |
3394 | enum nl80211_auth_type auth_type; | 3396 | enum nl80211_auth_type auth_type; |
3395 | struct key_parse key; | 3397 | struct key_parse key; |
3398 | bool local_state_change; | ||
3396 | 3399 | ||
3397 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3400 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3398 | return -EINVAL; | 3401 | return -EINVAL; |
@@ -3471,9 +3474,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
3471 | goto out; | 3474 | goto out; |
3472 | } | 3475 | } |
3473 | 3476 | ||
3477 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; | ||
3478 | |||
3474 | err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 3479 | err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
3475 | ssid, ssid_len, ie, ie_len, | 3480 | ssid, ssid_len, ie, ie_len, |
3476 | key.p.key, key.p.key_len, key.idx); | 3481 | key.p.key, key.p.key_len, key.idx, |
3482 | local_state_change); | ||
3477 | 3483 | ||
3478 | out: | 3484 | out: |
3479 | cfg80211_unlock_rdev(rdev); | 3485 | cfg80211_unlock_rdev(rdev); |
@@ -3650,6 +3656,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) | |||
3650 | const u8 *ie = NULL, *bssid; | 3656 | const u8 *ie = NULL, *bssid; |
3651 | int err, ie_len = 0; | 3657 | int err, ie_len = 0; |
3652 | u16 reason_code; | 3658 | u16 reason_code; |
3659 | bool local_state_change; | ||
3653 | 3660 | ||
3654 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3661 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3655 | return -EINVAL; | 3662 | return -EINVAL; |
@@ -3695,7 +3702,10 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) | |||
3695 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3702 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3696 | } | 3703 | } |
3697 | 3704 | ||
3698 | err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code); | 3705 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
3706 | |||
3707 | err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, | ||
3708 | local_state_change); | ||
3699 | 3709 | ||
3700 | out: | 3710 | out: |
3701 | cfg80211_unlock_rdev(rdev); | 3711 | cfg80211_unlock_rdev(rdev); |
@@ -3712,6 +3722,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) | |||
3712 | const u8 *ie = NULL, *bssid; | 3722 | const u8 *ie = NULL, *bssid; |
3713 | int err, ie_len = 0; | 3723 | int err, ie_len = 0; |
3714 | u16 reason_code; | 3724 | u16 reason_code; |
3725 | bool local_state_change; | ||
3715 | 3726 | ||
3716 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3727 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3717 | return -EINVAL; | 3728 | return -EINVAL; |
@@ -3757,7 +3768,10 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) | |||
3757 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3768 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3758 | } | 3769 | } |
3759 | 3770 | ||
3760 | err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code); | 3771 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
3772 | |||
3773 | err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, | ||
3774 | local_state_change); | ||
3761 | 3775 | ||
3762 | out: | 3776 | out: |
3763 | cfg80211_unlock_rdev(rdev); | 3777 | cfg80211_unlock_rdev(rdev); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 422da20d1e5b..8f0d97dd3109 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -2356,10 +2356,10 @@ static void print_regdomain(const struct ieee80211_regdomain *rd) | |||
2356 | rdev->country_ie_alpha2[1]); | 2356 | rdev->country_ie_alpha2[1]); |
2357 | } else | 2357 | } else |
2358 | printk(KERN_INFO "cfg80211: Current regulatory " | 2358 | printk(KERN_INFO "cfg80211: Current regulatory " |
2359 | "domain intersected: \n"); | 2359 | "domain intersected:\n"); |
2360 | } else | 2360 | } else |
2361 | printk(KERN_INFO "cfg80211: Current regulatory " | 2361 | printk(KERN_INFO "cfg80211: Current regulatory " |
2362 | "domain intersected: \n"); | 2362 | "domain intersected:\n"); |
2363 | } else if (is_world_regdom(rd->alpha2)) | 2363 | } else if (is_world_regdom(rd->alpha2)) |
2364 | printk(KERN_INFO "cfg80211: World regulatory " | 2364 | printk(KERN_INFO "cfg80211: World regulatory " |
2365 | "domain updated:\n"); | 2365 | "domain updated:\n"); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index f4dfd5f5f2ea..c2735775ec19 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -171,7 +171,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
171 | params->ssid, params->ssid_len, | 171 | params->ssid, params->ssid_len, |
172 | NULL, 0, | 172 | NULL, 0, |
173 | params->key, params->key_len, | 173 | params->key, params->key_len, |
174 | params->key_idx); | 174 | params->key_idx, false); |
175 | case CFG80211_CONN_ASSOCIATE_NEXT: | 175 | case CFG80211_CONN_ASSOCIATE_NEXT: |
176 | BUG_ON(!rdev->ops->assoc); | 176 | BUG_ON(!rdev->ops->assoc); |
177 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; | 177 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; |
@@ -186,12 +186,13 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
186 | if (err) | 186 | if (err) |
187 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | 187 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
188 | NULL, 0, | 188 | NULL, 0, |
189 | WLAN_REASON_DEAUTH_LEAVING); | 189 | WLAN_REASON_DEAUTH_LEAVING, |
190 | false); | ||
190 | return err; | 191 | return err; |
191 | case CFG80211_CONN_DEAUTH_ASSOC_FAIL: | 192 | case CFG80211_CONN_DEAUTH_ASSOC_FAIL: |
192 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | 193 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
193 | NULL, 0, | 194 | NULL, 0, |
194 | WLAN_REASON_DEAUTH_LEAVING); | 195 | WLAN_REASON_DEAUTH_LEAVING, false); |
195 | /* return an error so that we call __cfg80211_connect_result() */ | 196 | /* return an error so that we call __cfg80211_connect_result() */ |
196 | return -EINVAL; | 197 | return -EINVAL; |
197 | default: | 198 | default: |
@@ -676,7 +677,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
676 | continue; | 677 | continue; |
677 | bssid = wdev->auth_bsses[i]->pub.bssid; | 678 | bssid = wdev->auth_bsses[i]->pub.bssid; |
678 | ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, | 679 | ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, |
679 | WLAN_REASON_DEAUTH_LEAVING); | 680 | WLAN_REASON_DEAUTH_LEAVING, |
681 | false); | ||
680 | WARN(ret, "deauth failed: %d\n", ret); | 682 | WARN(ret, "deauth failed: %d\n", ret); |
681 | } | 683 | } |
682 | } | 684 | } |
@@ -935,7 +937,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, | |||
935 | /* wdev->conn->params.bssid must be set if > SCANNING */ | 937 | /* wdev->conn->params.bssid must be set if > SCANNING */ |
936 | err = __cfg80211_mlme_deauth(rdev, dev, | 938 | err = __cfg80211_mlme_deauth(rdev, dev, |
937 | wdev->conn->params.bssid, | 939 | wdev->conn->params.bssid, |
938 | NULL, 0, reason); | 940 | NULL, 0, reason, false); |
939 | if (err) | 941 | if (err) |
940 | return err; | 942 | return err; |
941 | } else { | 943 | } else { |
@@ -991,7 +993,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx) | |||
991 | 993 | ||
992 | memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN); | 994 | memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN); |
993 | if (__cfg80211_mlme_deauth(rdev, dev, bssid, | 995 | if (__cfg80211_mlme_deauth(rdev, dev, bssid, |
994 | NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) { | 996 | NULL, 0, WLAN_REASON_DEAUTH_LEAVING, |
997 | false)) { | ||
995 | /* whatever -- assume gone anyway */ | 998 | /* whatever -- assume gone anyway */ |
996 | cfg80211_unhold_bss(wdev->auth_bsses[idx]); | 999 | cfg80211_unhold_bss(wdev->auth_bsses[idx]); |
997 | cfg80211_put_bss(&wdev->auth_bsses[idx]->pub); | 1000 | cfg80211_put_bss(&wdev->auth_bsses[idx]->pub); |
diff --git a/net/wireless/util.c b/net/wireless/util.c index d3574a4eb3ba..3416373a9c0c 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -331,11 +331,18 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
331 | if (iftype == NL80211_IFTYPE_MESH_POINT) { | 331 | if (iftype == NL80211_IFTYPE_MESH_POINT) { |
332 | struct ieee80211s_hdr *meshdr = | 332 | struct ieee80211s_hdr *meshdr = |
333 | (struct ieee80211s_hdr *) (skb->data + hdrlen); | 333 | (struct ieee80211s_hdr *) (skb->data + hdrlen); |
334 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | 334 | /* make sure meshdr->flags is on the linear part */ |
335 | if (!pskb_may_pull(skb, hdrlen + 1)) | ||
336 | return -1; | ||
335 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { | 337 | if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { |
336 | memcpy(dst, meshdr->eaddr1, ETH_ALEN); | 338 | skb_copy_bits(skb, hdrlen + |
337 | memcpy(src, meshdr->eaddr2, ETH_ALEN); | 339 | offsetof(struct ieee80211s_hdr, eaddr1), |
340 | dst, ETH_ALEN); | ||
341 | skb_copy_bits(skb, hdrlen + | ||
342 | offsetof(struct ieee80211s_hdr, eaddr2), | ||
343 | src, ETH_ALEN); | ||
338 | } | 344 | } |
345 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | ||
339 | } | 346 | } |
340 | break; | 347 | break; |
341 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): | 348 | case cpu_to_le16(IEEE80211_FCTL_FROMDS): |
@@ -347,9 +354,14 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
347 | if (iftype == NL80211_IFTYPE_MESH_POINT) { | 354 | if (iftype == NL80211_IFTYPE_MESH_POINT) { |
348 | struct ieee80211s_hdr *meshdr = | 355 | struct ieee80211s_hdr *meshdr = |
349 | (struct ieee80211s_hdr *) (skb->data + hdrlen); | 356 | (struct ieee80211s_hdr *) (skb->data + hdrlen); |
350 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | 357 | /* make sure meshdr->flags is on the linear part */ |
358 | if (!pskb_may_pull(skb, hdrlen + 1)) | ||
359 | return -1; | ||
351 | if (meshdr->flags & MESH_FLAGS_AE_A4) | 360 | if (meshdr->flags & MESH_FLAGS_AE_A4) |
352 | memcpy(src, meshdr->eaddr1, ETH_ALEN); | 361 | skb_copy_bits(skb, hdrlen + |
362 | offsetof(struct ieee80211s_hdr, eaddr1), | ||
363 | src, ETH_ALEN); | ||
364 | hdrlen += ieee80211_get_mesh_hdrlen(meshdr); | ||
353 | } | 365 | } |
354 | break; | 366 | break; |
355 | case cpu_to_le16(0): | 367 | case cpu_to_le16(0): |
@@ -358,7 +370,7 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | |||
358 | break; | 370 | break; |
359 | } | 371 | } |
360 | 372 | ||
361 | if (unlikely(skb->len - hdrlen < 8)) | 373 | if (!pskb_may_pull(skb, hdrlen + 8)) |
362 | return -1; | 374 | return -1; |
363 | 375 | ||
364 | payload = skb->data + hdrlen; | 376 | payload = skb->data + hdrlen; |