diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/mlme.c | 23 | ||||
-rw-r--r-- | net/wireless/core.h | 15 | ||||
-rw-r--r-- | net/wireless/mlme.c | 39 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 19 | ||||
-rw-r--r-- | net/wireless/sme.c | 15 |
5 files changed, 78 insertions, 33 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 57a3c62139e2..4c189d0be4a3 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -210,7 +210,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
210 | 210 | ||
211 | static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | 211 | static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, |
212 | const u8 *bssid, u16 stype, u16 reason, | 212 | const u8 *bssid, u16 stype, u16 reason, |
213 | void *cookie) | 213 | void *cookie, bool send_frame) |
214 | { | 214 | { |
215 | struct ieee80211_local *local = sdata->local; | 215 | struct ieee80211_local *local = sdata->local; |
216 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 216 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
@@ -247,7 +247,11 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | |||
247 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); | 247 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); |
248 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) | 248 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) |
249 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 249 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
250 | ieee80211_tx_skb(sdata, skb); | 250 | |
251 | if (send_frame) | ||
252 | ieee80211_tx_skb(sdata, skb); | ||
253 | else | ||
254 | kfree_skb(skb); | ||
251 | } | 255 | } |
252 | 256 | ||
253 | void ieee80211_send_pspoll(struct ieee80211_local *local, | 257 | void ieee80211_send_pspoll(struct ieee80211_local *local, |
@@ -980,7 +984,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) | |||
980 | ieee80211_send_deauth_disassoc(sdata, bssid, | 984 | ieee80211_send_deauth_disassoc(sdata, bssid, |
981 | IEEE80211_STYPE_DEAUTH, | 985 | IEEE80211_STYPE_DEAUTH, |
982 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | 986 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, |
983 | NULL); | 987 | NULL, true); |
984 | } | 988 | } |
985 | 989 | ||
986 | void ieee80211_beacon_connection_loss_work(struct work_struct *work) | 990 | void ieee80211_beacon_connection_loss_work(struct work_struct *work) |
@@ -1724,7 +1728,7 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
1724 | ieee80211_send_deauth_disassoc(sdata, bssid, | 1728 | ieee80211_send_deauth_disassoc(sdata, bssid, |
1725 | IEEE80211_STYPE_DEAUTH, | 1729 | IEEE80211_STYPE_DEAUTH, |
1726 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | 1730 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, |
1727 | NULL); | 1731 | NULL, true); |
1728 | mutex_lock(&ifmgd->mtx); | 1732 | mutex_lock(&ifmgd->mtx); |
1729 | } | 1733 | } |
1730 | } | 1734 | } |
@@ -1908,6 +1912,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
1908 | struct ieee80211_work *wk; | 1912 | struct ieee80211_work *wk; |
1909 | u16 auth_alg; | 1913 | u16 auth_alg; |
1910 | 1914 | ||
1915 | if (req->local_state_change) | ||
1916 | return 0; /* no need to update mac80211 state */ | ||
1917 | |||
1911 | switch (req->auth_type) { | 1918 | switch (req->auth_type) { |
1912 | case NL80211_AUTHTYPE_OPEN_SYSTEM: | 1919 | case NL80211_AUTHTYPE_OPEN_SYSTEM: |
1913 | auth_alg = WLAN_AUTH_OPEN; | 1920 | auth_alg = WLAN_AUTH_OPEN; |
@@ -2163,9 +2170,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2163 | printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", | 2170 | printk(KERN_DEBUG "%s: deauthenticating from %pM by local choice (reason=%d)\n", |
2164 | sdata->name, bssid, req->reason_code); | 2171 | sdata->name, bssid, req->reason_code); |
2165 | 2172 | ||
2166 | ieee80211_send_deauth_disassoc(sdata, bssid, | 2173 | ieee80211_send_deauth_disassoc(sdata, bssid, IEEE80211_STYPE_DEAUTH, |
2167 | IEEE80211_STYPE_DEAUTH, req->reason_code, | 2174 | req->reason_code, cookie, |
2168 | cookie); | 2175 | !req->local_state_change); |
2169 | 2176 | ||
2170 | ieee80211_recalc_idle(sdata->local); | 2177 | ieee80211_recalc_idle(sdata->local); |
2171 | 2178 | ||
@@ -2202,7 +2209,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2202 | 2209 | ||
2203 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, | 2210 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, |
2204 | IEEE80211_STYPE_DISASSOC, req->reason_code, | 2211 | IEEE80211_STYPE_DISASSOC, req->reason_code, |
2205 | cookie); | 2212 | cookie, !req->local_state_change); |
2206 | sta_info_destroy_addr(sdata, bssid); | 2213 | sta_info_destroy_addr(sdata, bssid); |
2207 | 2214 | ||
2208 | ieee80211_recalc_idle(sdata->local); | 2215 | ieee80211_recalc_idle(sdata->local); |
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 0855f0d32349..387dd2a27d2f 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -377,7 +377,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
377 | const u8 *bssid, | 377 | const u8 *bssid, |
378 | const u8 *ssid, int ssid_len, | 378 | const u8 *ssid, int ssid_len, |
379 | const u8 *ie, int ie_len, | 379 | const u8 *ie, int ie_len, |
380 | const u8 *key, int key_len, int key_idx) | 380 | const u8 *key, int key_len, int key_idx, |
381 | bool local_state_change) | ||
381 | { | 382 | { |
382 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 383 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
383 | struct cfg80211_auth_request req; | 384 | struct cfg80211_auth_request req; |
@@ -407,6 +408,7 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
407 | 408 | ||
408 | memset(&req, 0, sizeof(req)); | 409 | memset(&req, 0, sizeof(req)); |
409 | 410 | ||
411 | req.local_state_change = local_state_change; | ||
410 | req.ie = ie; | 412 | req.ie = ie; |
411 | req.ie_len = ie_len; | 413 | req.ie_len = ie_len; |
412 | req.auth_type = auth_type; | 414 | req.auth_type = auth_type; |
@@ -433,12 +435,18 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
433 | goto out; | 435 | goto out; |
434 | } | 436 | } |
435 | 437 | ||
436 | wdev->authtry_bsses[slot] = bss; | 438 | if (local_state_change) |
439 | wdev->auth_bsses[slot] = bss; | ||
440 | else | ||
441 | wdev->authtry_bsses[slot] = bss; | ||
437 | cfg80211_hold_bss(bss); | 442 | cfg80211_hold_bss(bss); |
438 | 443 | ||
439 | err = rdev->ops->auth(&rdev->wiphy, dev, &req); | 444 | err = rdev->ops->auth(&rdev->wiphy, dev, &req); |
440 | if (err) { | 445 | if (err) { |
441 | wdev->authtry_bsses[slot] = NULL; | 446 | if (local_state_change) |
447 | wdev->auth_bsses[slot] = NULL; | ||
448 | else | ||
449 | wdev->authtry_bsses[slot] = NULL; | ||
442 | cfg80211_unhold_bss(bss); | 450 | cfg80211_unhold_bss(bss); |
443 | } | 451 | } |
444 | 452 | ||
@@ -453,14 +461,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, | |||
453 | enum nl80211_auth_type auth_type, const u8 *bssid, | 461 | enum nl80211_auth_type auth_type, const u8 *bssid, |
454 | const u8 *ssid, int ssid_len, | 462 | const u8 *ssid, int ssid_len, |
455 | const u8 *ie, int ie_len, | 463 | const u8 *ie, int ie_len, |
456 | const u8 *key, int key_len, int key_idx) | 464 | const u8 *key, int key_len, int key_idx, |
465 | bool local_state_change) | ||
457 | { | 466 | { |
458 | int err; | 467 | int err; |
459 | 468 | ||
460 | wdev_lock(dev->ieee80211_ptr); | 469 | wdev_lock(dev->ieee80211_ptr); |
461 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 470 | err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
462 | ssid, ssid_len, ie, ie_len, | 471 | ssid, ssid_len, ie, ie_len, |
463 | key, key_len, key_idx); | 472 | key, key_len, key_idx, local_state_change); |
464 | wdev_unlock(dev->ieee80211_ptr); | 473 | wdev_unlock(dev->ieee80211_ptr); |
465 | 474 | ||
466 | return err; | 475 | return err; |
@@ -554,7 +563,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, | |||
554 | 563 | ||
555 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 564 | int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
556 | struct net_device *dev, const u8 *bssid, | 565 | struct net_device *dev, const u8 *bssid, |
557 | const u8 *ie, int ie_len, u16 reason) | 566 | const u8 *ie, int ie_len, u16 reason, |
567 | bool local_state_change) | ||
558 | { | 568 | { |
559 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 569 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
560 | struct cfg80211_deauth_request req; | 570 | struct cfg80211_deauth_request req; |
@@ -564,6 +574,7 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
564 | 574 | ||
565 | memset(&req, 0, sizeof(req)); | 575 | memset(&req, 0, sizeof(req)); |
566 | req.reason_code = reason; | 576 | req.reason_code = reason; |
577 | req.local_state_change = local_state_change; | ||
567 | req.ie = ie; | 578 | req.ie = ie; |
568 | req.ie_len = ie_len; | 579 | req.ie_len = ie_len; |
569 | if (wdev->current_bss && | 580 | if (wdev->current_bss && |
@@ -590,13 +601,15 @@ int __cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
590 | 601 | ||
591 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | 602 | int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, |
592 | struct net_device *dev, const u8 *bssid, | 603 | struct net_device *dev, const u8 *bssid, |
593 | const u8 *ie, int ie_len, u16 reason) | 604 | const u8 *ie, int ie_len, u16 reason, |
605 | bool local_state_change) | ||
594 | { | 606 | { |
595 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 607 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
596 | int err; | 608 | int err; |
597 | 609 | ||
598 | wdev_lock(wdev); | 610 | wdev_lock(wdev); |
599 | err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason); | 611 | err = __cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason, |
612 | local_state_change); | ||
600 | wdev_unlock(wdev); | 613 | wdev_unlock(wdev); |
601 | 614 | ||
602 | return err; | 615 | return err; |
@@ -604,7 +617,8 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev, | |||
604 | 617 | ||
605 | static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 618 | static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
606 | struct net_device *dev, const u8 *bssid, | 619 | struct net_device *dev, const u8 *bssid, |
607 | const u8 *ie, int ie_len, u16 reason) | 620 | const u8 *ie, int ie_len, u16 reason, |
621 | bool local_state_change) | ||
608 | { | 622 | { |
609 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 623 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
610 | struct cfg80211_disassoc_request req; | 624 | struct cfg80211_disassoc_request req; |
@@ -619,6 +633,7 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | |||
619 | 633 | ||
620 | memset(&req, 0, sizeof(req)); | 634 | memset(&req, 0, sizeof(req)); |
621 | req.reason_code = reason; | 635 | req.reason_code = reason; |
636 | req.local_state_change = local_state_change; | ||
622 | req.ie = ie; | 637 | req.ie = ie; |
623 | req.ie_len = ie_len; | 638 | req.ie_len = ie_len; |
624 | if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) | 639 | if (memcmp(wdev->current_bss->pub.bssid, bssid, ETH_ALEN) == 0) |
@@ -631,13 +646,15 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | |||
631 | 646 | ||
632 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, | 647 | int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev, |
633 | struct net_device *dev, const u8 *bssid, | 648 | struct net_device *dev, const u8 *bssid, |
634 | const u8 *ie, int ie_len, u16 reason) | 649 | const u8 *ie, int ie_len, u16 reason, |
650 | bool local_state_change) | ||
635 | { | 651 | { |
636 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 652 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
637 | int err; | 653 | int err; |
638 | 654 | ||
639 | wdev_lock(wdev); | 655 | wdev_lock(wdev); |
640 | err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason); | 656 | err = __cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason, |
657 | local_state_change); | ||
641 | wdev_unlock(wdev); | 658 | wdev_unlock(wdev); |
642 | 659 | ||
643 | return err; | 660 | return err; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 95149f303409..df5505b3930c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -150,6 +150,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
150 | [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, | 150 | [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, |
151 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, | 151 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, |
152 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, | 152 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, |
153 | [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, | ||
153 | }; | 154 | }; |
154 | 155 | ||
155 | /* policy for the attributes */ | 156 | /* policy for the attributes */ |
@@ -3393,6 +3394,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
3393 | int err, ssid_len, ie_len = 0; | 3394 | int err, ssid_len, ie_len = 0; |
3394 | enum nl80211_auth_type auth_type; | 3395 | enum nl80211_auth_type auth_type; |
3395 | struct key_parse key; | 3396 | struct key_parse key; |
3397 | bool local_state_change; | ||
3396 | 3398 | ||
3397 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3399 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3398 | return -EINVAL; | 3400 | return -EINVAL; |
@@ -3471,9 +3473,12 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | |||
3471 | goto out; | 3473 | goto out; |
3472 | } | 3474 | } |
3473 | 3475 | ||
3476 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; | ||
3477 | |||
3474 | err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 3478 | err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
3475 | ssid, ssid_len, ie, ie_len, | 3479 | ssid, ssid_len, ie, ie_len, |
3476 | key.p.key, key.p.key_len, key.idx); | 3480 | key.p.key, key.p.key_len, key.idx, |
3481 | local_state_change); | ||
3477 | 3482 | ||
3478 | out: | 3483 | out: |
3479 | cfg80211_unlock_rdev(rdev); | 3484 | cfg80211_unlock_rdev(rdev); |
@@ -3650,6 +3655,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) | |||
3650 | const u8 *ie = NULL, *bssid; | 3655 | const u8 *ie = NULL, *bssid; |
3651 | int err, ie_len = 0; | 3656 | int err, ie_len = 0; |
3652 | u16 reason_code; | 3657 | u16 reason_code; |
3658 | bool local_state_change; | ||
3653 | 3659 | ||
3654 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3660 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3655 | return -EINVAL; | 3661 | return -EINVAL; |
@@ -3695,7 +3701,10 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) | |||
3695 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3701 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3696 | } | 3702 | } |
3697 | 3703 | ||
3698 | err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code); | 3704 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
3705 | |||
3706 | err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, | ||
3707 | local_state_change); | ||
3699 | 3708 | ||
3700 | out: | 3709 | out: |
3701 | cfg80211_unlock_rdev(rdev); | 3710 | cfg80211_unlock_rdev(rdev); |
@@ -3712,6 +3721,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) | |||
3712 | const u8 *ie = NULL, *bssid; | 3721 | const u8 *ie = NULL, *bssid; |
3713 | int err, ie_len = 0; | 3722 | int err, ie_len = 0; |
3714 | u16 reason_code; | 3723 | u16 reason_code; |
3724 | bool local_state_change; | ||
3715 | 3725 | ||
3716 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3726 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3717 | return -EINVAL; | 3727 | return -EINVAL; |
@@ -3757,7 +3767,10 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) | |||
3757 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 3767 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
3758 | } | 3768 | } |
3759 | 3769 | ||
3760 | err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code); | 3770 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
3771 | |||
3772 | err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, | ||
3773 | local_state_change); | ||
3761 | 3774 | ||
3762 | out: | 3775 | out: |
3763 | cfg80211_unlock_rdev(rdev); | 3776 | cfg80211_unlock_rdev(rdev); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 17fde0da1b08..17465777eb47 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -170,7 +170,7 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
170 | params->ssid, params->ssid_len, | 170 | params->ssid, params->ssid_len, |
171 | NULL, 0, | 171 | NULL, 0, |
172 | params->key, params->key_len, | 172 | params->key, params->key_len, |
173 | params->key_idx); | 173 | params->key_idx, false); |
174 | case CFG80211_CONN_ASSOCIATE_NEXT: | 174 | case CFG80211_CONN_ASSOCIATE_NEXT: |
175 | BUG_ON(!rdev->ops->assoc); | 175 | BUG_ON(!rdev->ops->assoc); |
176 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; | 176 | wdev->conn->state = CFG80211_CONN_ASSOCIATING; |
@@ -185,12 +185,13 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev) | |||
185 | if (err) | 185 | if (err) |
186 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | 186 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
187 | NULL, 0, | 187 | NULL, 0, |
188 | WLAN_REASON_DEAUTH_LEAVING); | 188 | WLAN_REASON_DEAUTH_LEAVING, |
189 | false); | ||
189 | return err; | 190 | return err; |
190 | case CFG80211_CONN_DEAUTH_ASSOC_FAIL: | 191 | case CFG80211_CONN_DEAUTH_ASSOC_FAIL: |
191 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, | 192 | __cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, |
192 | NULL, 0, | 193 | NULL, 0, |
193 | WLAN_REASON_DEAUTH_LEAVING); | 194 | WLAN_REASON_DEAUTH_LEAVING, false); |
194 | /* return an error so that we call __cfg80211_connect_result() */ | 195 | /* return an error so that we call __cfg80211_connect_result() */ |
195 | return -EINVAL; | 196 | return -EINVAL; |
196 | default: | 197 | default: |
@@ -675,7 +676,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, | |||
675 | continue; | 676 | continue; |
676 | bssid = wdev->auth_bsses[i]->pub.bssid; | 677 | bssid = wdev->auth_bsses[i]->pub.bssid; |
677 | ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, | 678 | ret = __cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, |
678 | WLAN_REASON_DEAUTH_LEAVING); | 679 | WLAN_REASON_DEAUTH_LEAVING, |
680 | false); | ||
679 | WARN(ret, "deauth failed: %d\n", ret); | 681 | WARN(ret, "deauth failed: %d\n", ret); |
680 | } | 682 | } |
681 | } | 683 | } |
@@ -934,7 +936,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, | |||
934 | /* wdev->conn->params.bssid must be set if > SCANNING */ | 936 | /* wdev->conn->params.bssid must be set if > SCANNING */ |
935 | err = __cfg80211_mlme_deauth(rdev, dev, | 937 | err = __cfg80211_mlme_deauth(rdev, dev, |
936 | wdev->conn->params.bssid, | 938 | wdev->conn->params.bssid, |
937 | NULL, 0, reason); | 939 | NULL, 0, reason, false); |
938 | if (err) | 940 | if (err) |
939 | return err; | 941 | return err; |
940 | } else { | 942 | } else { |
@@ -990,7 +992,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx) | |||
990 | 992 | ||
991 | memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN); | 993 | memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN); |
992 | if (__cfg80211_mlme_deauth(rdev, dev, bssid, | 994 | if (__cfg80211_mlme_deauth(rdev, dev, bssid, |
993 | NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) { | 995 | NULL, 0, WLAN_REASON_DEAUTH_LEAVING, |
996 | false)) { | ||
994 | /* whatever -- assume gone anyway */ | 997 | /* whatever -- assume gone anyway */ |
995 | cfg80211_unhold_bss(wdev->auth_bsses[idx]); | 998 | cfg80211_unhold_bss(wdev->auth_bsses[idx]); |
996 | cfg80211_put_bss(&wdev->auth_bsses[idx]->pub); | 999 | cfg80211_put_bss(&wdev->auth_bsses[idx]->pub); |