diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 63 |
1 files changed, 47 insertions, 16 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index dc5049d58c51..d8d50fb5e823 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -426,7 +426,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
426 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); | 426 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); |
427 | } | 427 | } |
428 | 428 | ||
429 | ieee80211_tx_skb(sdata, skb, 0); | 429 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
430 | ieee80211_tx_skb(sdata, skb); | ||
430 | } | 431 | } |
431 | 432 | ||
432 | 433 | ||
@@ -458,10 +459,18 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | |||
458 | mgmt->u.deauth.reason_code = cpu_to_le16(reason); | 459 | mgmt->u.deauth.reason_code = cpu_to_le16(reason); |
459 | 460 | ||
460 | if (stype == IEEE80211_STYPE_DEAUTH) | 461 | if (stype == IEEE80211_STYPE_DEAUTH) |
461 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, cookie); | 462 | if (cookie) |
463 | __cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | ||
464 | else | ||
465 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | ||
462 | else | 466 | else |
463 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, cookie); | 467 | if (cookie) |
464 | ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED); | 468 | __cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); |
469 | else | ||
470 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); | ||
471 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) | ||
472 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | ||
473 | ieee80211_tx_skb(sdata, skb); | ||
465 | } | 474 | } |
466 | 475 | ||
467 | void ieee80211_send_pspoll(struct ieee80211_local *local, | 476 | void ieee80211_send_pspoll(struct ieee80211_local *local, |
@@ -492,7 +501,8 @@ void ieee80211_send_pspoll(struct ieee80211_local *local, | |||
492 | memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); | 501 | memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); |
493 | memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN); | 502 | memcpy(pspoll->ta, sdata->dev->dev_addr, ETH_ALEN); |
494 | 503 | ||
495 | ieee80211_tx_skb(sdata, skb, 0); | 504 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
505 | ieee80211_tx_skb(sdata, skb); | ||
496 | } | 506 | } |
497 | 507 | ||
498 | void ieee80211_send_nullfunc(struct ieee80211_local *local, | 508 | void ieee80211_send_nullfunc(struct ieee80211_local *local, |
@@ -525,7 +535,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
525 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); | 535 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); |
526 | memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); | 536 | memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); |
527 | 537 | ||
528 | ieee80211_tx_skb(sdata, skb, 0); | 538 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
539 | ieee80211_tx_skb(sdata, skb); | ||
529 | } | 540 | } |
530 | 541 | ||
531 | /* spectrum management related things */ | 542 | /* spectrum management related things */ |
@@ -923,7 +934,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
923 | ieee80211_recalc_ps(local, -1); | 934 | ieee80211_recalc_ps(local, -1); |
924 | mutex_unlock(&local->iflist_mtx); | 935 | mutex_unlock(&local->iflist_mtx); |
925 | 936 | ||
926 | netif_tx_start_all_queues(sdata->dev); | 937 | netif_start_queue(sdata->dev); |
927 | netif_carrier_on(sdata->dev); | 938 | netif_carrier_on(sdata->dev); |
928 | } | 939 | } |
929 | 940 | ||
@@ -1055,7 +1066,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1055 | * time -- we don't want the scan code to enable queues. | 1066 | * time -- we don't want the scan code to enable queues. |
1056 | */ | 1067 | */ |
1057 | 1068 | ||
1058 | netif_tx_stop_all_queues(sdata->dev); | 1069 | netif_stop_queue(sdata->dev); |
1059 | netif_carrier_off(sdata->dev); | 1070 | netif_carrier_off(sdata->dev); |
1060 | 1071 | ||
1061 | rcu_read_lock(); | 1072 | rcu_read_lock(); |
@@ -1072,8 +1083,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1072 | 1083 | ||
1073 | ieee80211_set_wmm_default(sdata); | 1084 | ieee80211_set_wmm_default(sdata); |
1074 | 1085 | ||
1075 | ieee80211_recalc_idle(local); | ||
1076 | |||
1077 | /* channel(_type) changes are handled by ieee80211_hw_config */ | 1086 | /* channel(_type) changes are handled by ieee80211_hw_config */ |
1078 | local->oper_channel_type = NL80211_CHAN_NO_HT; | 1087 | local->oper_channel_type = NL80211_CHAN_NO_HT; |
1079 | 1088 | ||
@@ -1359,6 +1368,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1359 | 1368 | ||
1360 | if (!wk) { | 1369 | if (!wk) { |
1361 | ieee80211_set_disassoc(sdata, true); | 1370 | ieee80211_set_disassoc(sdata, true); |
1371 | ieee80211_recalc_idle(sdata->local); | ||
1362 | } else { | 1372 | } else { |
1363 | list_del(&wk->list); | 1373 | list_del(&wk->list); |
1364 | kfree(wk); | 1374 | kfree(wk); |
@@ -1392,6 +1402,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1392 | sdata->dev->name, mgmt->sa, reason_code); | 1402 | sdata->dev->name, mgmt->sa, reason_code); |
1393 | 1403 | ||
1394 | ieee80211_set_disassoc(sdata, false); | 1404 | ieee80211_set_disassoc(sdata, false); |
1405 | ieee80211_recalc_idle(sdata->local); | ||
1395 | return RX_MGMT_CFG80211_DISASSOC; | 1406 | return RX_MGMT_CFG80211_DISASSOC; |
1396 | } | 1407 | } |
1397 | 1408 | ||
@@ -1892,7 +1903,6 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1892 | fc = le16_to_cpu(mgmt->frame_control); | 1903 | fc = le16_to_cpu(mgmt->frame_control); |
1893 | 1904 | ||
1894 | switch (fc & IEEE80211_FCTL_STYPE) { | 1905 | switch (fc & IEEE80211_FCTL_STYPE) { |
1895 | case IEEE80211_STYPE_PROBE_REQ: | ||
1896 | case IEEE80211_STYPE_PROBE_RESP: | 1906 | case IEEE80211_STYPE_PROBE_RESP: |
1897 | case IEEE80211_STYPE_BEACON: | 1907 | case IEEE80211_STYPE_BEACON: |
1898 | case IEEE80211_STYPE_AUTH: | 1908 | case IEEE80211_STYPE_AUTH: |
@@ -1958,12 +1968,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1958 | /* no action */ | 1968 | /* no action */ |
1959 | break; | 1969 | break; |
1960 | case RX_MGMT_CFG80211_DEAUTH: | 1970 | case RX_MGMT_CFG80211_DEAUTH: |
1961 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, | 1971 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); |
1962 | NULL); | ||
1963 | break; | 1972 | break; |
1964 | case RX_MGMT_CFG80211_DISASSOC: | 1973 | case RX_MGMT_CFG80211_DISASSOC: |
1965 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len, | 1974 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); |
1966 | NULL); | ||
1967 | break; | 1975 | break; |
1968 | default: | 1976 | default: |
1969 | WARN(1, "unexpected: %d", rma); | 1977 | WARN(1, "unexpected: %d", rma); |
@@ -2018,7 +2026,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
2018 | cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len); | 2026 | cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len); |
2019 | break; | 2027 | break; |
2020 | case RX_MGMT_CFG80211_DEAUTH: | 2028 | case RX_MGMT_CFG80211_DEAUTH: |
2021 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, NULL); | 2029 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); |
2022 | break; | 2030 | break; |
2023 | default: | 2031 | default: |
2024 | WARN(1, "unexpected: %d", rma); | 2032 | WARN(1, "unexpected: %d", rma); |
@@ -2109,6 +2117,7 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2109 | " after %dms, disconnecting.\n", | 2117 | " after %dms, disconnecting.\n", |
2110 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); | 2118 | bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); |
2111 | ieee80211_set_disassoc(sdata, true); | 2119 | ieee80211_set_disassoc(sdata, true); |
2120 | ieee80211_recalc_idle(local); | ||
2112 | mutex_unlock(&ifmgd->mtx); | 2121 | mutex_unlock(&ifmgd->mtx); |
2113 | /* | 2122 | /* |
2114 | * must be outside lock due to cfg80211, | 2123 | * must be outside lock due to cfg80211, |
@@ -2500,6 +2509,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2500 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2509 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2501 | struct ieee80211_mgd_work *wk; | 2510 | struct ieee80211_mgd_work *wk; |
2502 | const u8 *bssid = NULL; | 2511 | const u8 *bssid = NULL; |
2512 | bool not_auth_yet = false; | ||
2503 | 2513 | ||
2504 | mutex_lock(&ifmgd->mtx); | 2514 | mutex_lock(&ifmgd->mtx); |
2505 | 2515 | ||
@@ -2509,6 +2519,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2509 | } else list_for_each_entry(wk, &ifmgd->work_list, list) { | 2519 | } else list_for_each_entry(wk, &ifmgd->work_list, list) { |
2510 | if (&wk->bss->cbss == req->bss) { | 2520 | if (&wk->bss->cbss == req->bss) { |
2511 | bssid = req->bss->bssid; | 2521 | bssid = req->bss->bssid; |
2522 | if (wk->state == IEEE80211_MGD_STATE_PROBE) | ||
2523 | not_auth_yet = true; | ||
2512 | list_del(&wk->list); | 2524 | list_del(&wk->list); |
2513 | kfree(wk); | 2525 | kfree(wk); |
2514 | break; | 2526 | break; |
@@ -2516,6 +2528,20 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2516 | } | 2528 | } |
2517 | 2529 | ||
2518 | /* | 2530 | /* |
2531 | * If somebody requests authentication and we haven't | ||
2532 | * sent out an auth frame yet there's no need to send | ||
2533 | * out a deauth frame either. If the state was PROBE, | ||
2534 | * then this is the case. If it's AUTH we have sent a | ||
2535 | * frame, and if it's IDLE we have completed the auth | ||
2536 | * process already. | ||
2537 | */ | ||
2538 | if (not_auth_yet) { | ||
2539 | mutex_unlock(&ifmgd->mtx); | ||
2540 | __cfg80211_auth_canceled(sdata->dev, bssid); | ||
2541 | return 0; | ||
2542 | } | ||
2543 | |||
2544 | /* | ||
2519 | * cfg80211 should catch this ... but it's racy since | 2545 | * cfg80211 should catch this ... but it's racy since |
2520 | * we can receive a deauth frame, process it, hand it | 2546 | * we can receive a deauth frame, process it, hand it |
2521 | * to cfg80211 while that's in a locked section already | 2547 | * to cfg80211 while that's in a locked section already |
@@ -2535,6 +2561,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2535 | IEEE80211_STYPE_DEAUTH, req->reason_code, | 2561 | IEEE80211_STYPE_DEAUTH, req->reason_code, |
2536 | cookie); | 2562 | cookie); |
2537 | 2563 | ||
2564 | ieee80211_recalc_idle(sdata->local); | ||
2565 | |||
2538 | return 0; | 2566 | return 0; |
2539 | } | 2567 | } |
2540 | 2568 | ||
@@ -2567,5 +2595,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2567 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, | 2595 | ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, |
2568 | IEEE80211_STYPE_DISASSOC, req->reason_code, | 2596 | IEEE80211_STYPE_DISASSOC, req->reason_code, |
2569 | cookie); | 2597 | cookie); |
2598 | |||
2599 | ieee80211_recalc_idle(sdata->local); | ||
2600 | |||
2570 | return 0; | 2601 | return 0; |
2571 | } | 2602 | } |