diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-10-30 04:09:48 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-10-30 04:09:48 -0400 |
commit | 6fb47de9cf1be4710fb9f364c500ff216fb47b34 (patch) | |
tree | e638cd1de972e7120dff9200efe71ce1b4ca3805 /net/mac80211 | |
parent | 1041638f2bba0f1de75e66086d50fb1251d64dcf (diff) | |
parent | ab3d59d265e772e734c36fe738809cb1a910f566 (diff) |
Merge remote-tracking branch 'wireless-next/master' into mac80211-next
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/ibss.c | 2 | ||||
-rw-r--r-- | net/mac80211/iface.c | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 34 | ||||
-rw-r--r-- | net/mac80211/rx.c | 74 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 4 | ||||
-rw-r--r-- | net/mac80211/util.c | 46 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 14 |
7 files changed, 130 insertions, 46 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 3d5332e367f8..c7386b2b767e 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -1110,7 +1110,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1110 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; | 1110 | sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; |
1111 | sdata->u.ibss.ibss_join_req = jiffies; | 1111 | sdata->u.ibss.ibss_join_req = jiffies; |
1112 | 1112 | ||
1113 | memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); | 1113 | memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); |
1114 | sdata->u.ibss.ssid_len = params->ssid_len; | 1114 | sdata->u.ibss.ssid_len = params->ssid_len; |
1115 | 1115 | ||
1116 | mutex_unlock(&sdata->u.ibss.mtx); | 1116 | mutex_unlock(&sdata->u.ibss.mtx); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 944c6cf53eb7..1a6fe135f201 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -840,7 +840,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
840 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 840 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
841 | if (info->control.vif == &sdata->vif) { | 841 | if (info->control.vif == &sdata->vif) { |
842 | __skb_unlink(skb, &local->pending[i]); | 842 | __skb_unlink(skb, &local->pending[i]); |
843 | dev_kfree_skb_irq(skb); | 843 | ieee80211_free_txskb(&local->hw, skb); |
844 | } | 844 | } |
845 | } | 845 | } |
846 | } | 846 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2bdf7769506f..1d1fdf0791f0 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3177,26 +3177,37 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, | |||
3177 | ht_cfreq, ht_oper->primary_chan, | 3177 | ht_cfreq, ht_oper->primary_chan, |
3178 | cbss->channel->band); | 3178 | cbss->channel->band); |
3179 | ht_oper = NULL; | 3179 | ht_oper = NULL; |
3180 | } else { | ||
3181 | channel_type = NL80211_CHAN_HT20; | ||
3180 | } | 3182 | } |
3181 | } | 3183 | } |
3182 | 3184 | ||
3183 | if (ht_oper) { | 3185 | if (ht_oper && sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { |
3186 | /* | ||
3187 | * cfg80211 already verified that the channel itself can | ||
3188 | * be used, but it didn't check that we can do the right | ||
3189 | * HT type, so do that here as well. If HT40 isn't allowed | ||
3190 | * on this channel, disable 40 MHz operation. | ||
3191 | */ | ||
3184 | const u8 *ht_cap_ie; | 3192 | const u8 *ht_cap_ie; |
3185 | const struct ieee80211_ht_cap *ht_cap; | 3193 | const struct ieee80211_ht_cap *ht_cap; |
3186 | u8 chains = 1; | 3194 | u8 chains = 1; |
3187 | 3195 | ||
3188 | channel_type = NL80211_CHAN_HT20; | 3196 | channel_type = NL80211_CHAN_HT20; |
3189 | 3197 | ||
3190 | if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { | 3198 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
3191 | switch (ht_oper->ht_param & | 3199 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
3192 | IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 3200 | if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40PLUS) |
3193 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 3201 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; |
3202 | else | ||
3194 | channel_type = NL80211_CHAN_HT40PLUS; | 3203 | channel_type = NL80211_CHAN_HT40PLUS; |
3195 | break; | 3204 | break; |
3196 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: | 3205 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
3206 | if (cbss->channel->flags & IEEE80211_CHAN_NO_HT40MINUS) | ||
3207 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; | ||
3208 | else | ||
3197 | channel_type = NL80211_CHAN_HT40MINUS; | 3209 | channel_type = NL80211_CHAN_HT40MINUS; |
3198 | break; | 3210 | break; |
3199 | } | ||
3200 | } | 3211 | } |
3201 | 3212 | ||
3202 | ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, | 3213 | ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, |
@@ -3648,6 +3659,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3648 | { | 3659 | { |
3649 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3660 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3650 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 3661 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
3662 | bool tx = !req->local_state_change; | ||
3651 | 3663 | ||
3652 | mutex_lock(&ifmgd->mtx); | 3664 | mutex_lock(&ifmgd->mtx); |
3653 | 3665 | ||
@@ -3664,12 +3676,12 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3664 | if (ifmgd->associated && | 3676 | if (ifmgd->associated && |
3665 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { | 3677 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) { |
3666 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3678 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3667 | req->reason_code, true, frame_buf); | 3679 | req->reason_code, tx, frame_buf); |
3668 | } else { | 3680 | } else { |
3669 | drv_mgd_prepare_tx(sdata->local, sdata); | 3681 | drv_mgd_prepare_tx(sdata->local, sdata); |
3670 | ieee80211_send_deauth_disassoc(sdata, req->bssid, | 3682 | ieee80211_send_deauth_disassoc(sdata, req->bssid, |
3671 | IEEE80211_STYPE_DEAUTH, | 3683 | IEEE80211_STYPE_DEAUTH, |
3672 | req->reason_code, true, | 3684 | req->reason_code, tx, |
3673 | frame_buf); | 3685 | frame_buf); |
3674 | } | 3686 | } |
3675 | 3687 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c0a1f53e68ab..38b382682cae 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -525,6 +525,11 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
525 | 525 | ||
526 | if (ieee80211_is_action(hdr->frame_control)) { | 526 | if (ieee80211_is_action(hdr->frame_control)) { |
527 | u8 category; | 527 | u8 category; |
528 | |||
529 | /* make sure category field is present */ | ||
530 | if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) | ||
531 | return RX_DROP_MONITOR; | ||
532 | |||
528 | mgmt = (struct ieee80211_mgmt *)hdr; | 533 | mgmt = (struct ieee80211_mgmt *)hdr; |
529 | category = mgmt->u.action.category; | 534 | category = mgmt->u.action.category; |
530 | if (category != WLAN_CATEGORY_MESH_ACTION && | 535 | if (category != WLAN_CATEGORY_MESH_ACTION && |
@@ -875,14 +880,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
875 | */ | 880 | */ |
876 | if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && | 881 | if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && |
877 | ieee80211_is_data_present(hdr->frame_control)) { | 882 | ieee80211_is_data_present(hdr->frame_control)) { |
878 | u16 ethertype; | 883 | unsigned int hdrlen; |
879 | u8 *payload; | 884 | __be16 ethertype; |
880 | 885 | ||
881 | payload = rx->skb->data + | 886 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
882 | ieee80211_hdrlen(hdr->frame_control); | 887 | |
883 | ethertype = (payload[6] << 8) | payload[7]; | 888 | if (rx->skb->len < hdrlen + 8) |
884 | if (cpu_to_be16(ethertype) == | 889 | return RX_DROP_MONITOR; |
885 | rx->sdata->control_port_protocol) | 890 | |
891 | skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); | ||
892 | if (ethertype == rx->sdata->control_port_protocol) | ||
886 | return RX_CONTINUE; | 893 | return RX_CONTINUE; |
887 | } | 894 | } |
888 | 895 | ||
@@ -1459,11 +1466,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1459 | 1466 | ||
1460 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 1467 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
1461 | fc = hdr->frame_control; | 1468 | fc = hdr->frame_control; |
1469 | |||
1470 | if (ieee80211_is_ctl(fc)) | ||
1471 | return RX_CONTINUE; | ||
1472 | |||
1462 | sc = le16_to_cpu(hdr->seq_ctrl); | 1473 | sc = le16_to_cpu(hdr->seq_ctrl); |
1463 | frag = sc & IEEE80211_SCTL_FRAG; | 1474 | frag = sc & IEEE80211_SCTL_FRAG; |
1464 | 1475 | ||
1465 | if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || | 1476 | if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || |
1466 | (rx->skb)->len < 24 || | ||
1467 | is_multicast_ether_addr(hdr->addr1))) { | 1477 | is_multicast_ether_addr(hdr->addr1))) { |
1468 | /* not fragmented */ | 1478 | /* not fragmented */ |
1469 | goto out; | 1479 | goto out; |
@@ -1882,6 +1892,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1882 | 1892 | ||
1883 | hdr = (struct ieee80211_hdr *) skb->data; | 1893 | hdr = (struct ieee80211_hdr *) skb->data; |
1884 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1894 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1895 | |||
1896 | /* make sure fixed part of mesh header is there, also checks skb len */ | ||
1897 | if (!pskb_may_pull(rx->skb, hdrlen + 6)) | ||
1898 | return RX_DROP_MONITOR; | ||
1899 | |||
1900 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | ||
1901 | |||
1902 | /* make sure full mesh header is there, also checks skb len */ | ||
1903 | if (!pskb_may_pull(rx->skb, | ||
1904 | hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) | ||
1905 | return RX_DROP_MONITOR; | ||
1906 | |||
1907 | /* reload pointers */ | ||
1908 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1885 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | 1909 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
1886 | 1910 | ||
1887 | /* frame is in RMC, don't forward */ | 1911 | /* frame is in RMC, don't forward */ |
@@ -1890,7 +1914,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1890 | mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) | 1914 | mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) |
1891 | return RX_DROP_MONITOR; | 1915 | return RX_DROP_MONITOR; |
1892 | 1916 | ||
1893 | if (!ieee80211_is_data(hdr->frame_control)) | 1917 | if (!ieee80211_is_data(hdr->frame_control) || |
1918 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1894 | return RX_CONTINUE; | 1919 | return RX_CONTINUE; |
1895 | 1920 | ||
1896 | if (!mesh_hdr->ttl) | 1921 | if (!mesh_hdr->ttl) |
@@ -1904,9 +1929,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1904 | if (is_multicast_ether_addr(hdr->addr1)) { | 1929 | if (is_multicast_ether_addr(hdr->addr1)) { |
1905 | mpp_addr = hdr->addr3; | 1930 | mpp_addr = hdr->addr3; |
1906 | proxied_addr = mesh_hdr->eaddr1; | 1931 | proxied_addr = mesh_hdr->eaddr1; |
1907 | } else { | 1932 | } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { |
1933 | /* has_a4 already checked in ieee80211_rx_mesh_check */ | ||
1908 | mpp_addr = hdr->addr4; | 1934 | mpp_addr = hdr->addr4; |
1909 | proxied_addr = mesh_hdr->eaddr2; | 1935 | proxied_addr = mesh_hdr->eaddr2; |
1936 | } else { | ||
1937 | return RX_DROP_MONITOR; | ||
1910 | } | 1938 | } |
1911 | 1939 | ||
1912 | rcu_read_lock(); | 1940 | rcu_read_lock(); |
@@ -1934,12 +1962,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1934 | } | 1962 | } |
1935 | skb_set_queue_mapping(skb, q); | 1963 | skb_set_queue_mapping(skb, q); |
1936 | 1964 | ||
1937 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) | ||
1938 | goto out; | ||
1939 | |||
1940 | if (!--mesh_hdr->ttl) { | 1965 | if (!--mesh_hdr->ttl) { |
1941 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); | 1966 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); |
1942 | return RX_DROP_MONITOR; | 1967 | goto out; |
1943 | } | 1968 | } |
1944 | 1969 | ||
1945 | if (!ifmsh->mshcfg.dot11MeshForwarding) | 1970 | if (!ifmsh->mshcfg.dot11MeshForwarding) |
@@ -2346,6 +2371,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2346 | } | 2371 | } |
2347 | break; | 2372 | break; |
2348 | case WLAN_CATEGORY_SELF_PROTECTED: | 2373 | case WLAN_CATEGORY_SELF_PROTECTED: |
2374 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
2375 | sizeof(mgmt->u.action.u.self_prot.action_code))) | ||
2376 | break; | ||
2377 | |||
2349 | switch (mgmt->u.action.u.self_prot.action_code) { | 2378 | switch (mgmt->u.action.u.self_prot.action_code) { |
2350 | case WLAN_SP_MESH_PEERING_OPEN: | 2379 | case WLAN_SP_MESH_PEERING_OPEN: |
2351 | case WLAN_SP_MESH_PEERING_CLOSE: | 2380 | case WLAN_SP_MESH_PEERING_CLOSE: |
@@ -2364,6 +2393,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2364 | } | 2393 | } |
2365 | break; | 2394 | break; |
2366 | case WLAN_CATEGORY_MESH_ACTION: | 2395 | case WLAN_CATEGORY_MESH_ACTION: |
2396 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
2397 | sizeof(mgmt->u.action.u.mesh_action.action_code))) | ||
2398 | break; | ||
2399 | |||
2367 | if (!ieee80211_vif_is_mesh(&sdata->vif)) | 2400 | if (!ieee80211_vif_is_mesh(&sdata->vif)) |
2368 | break; | 2401 | break; |
2369 | if (mesh_action_is_path_sel(mgmt) && | 2402 | if (mesh_action_is_path_sel(mgmt) && |
@@ -2905,10 +2938,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2905 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) | 2938 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) |
2906 | local->dot11ReceivedFragmentCount++; | 2939 | local->dot11ReceivedFragmentCount++; |
2907 | 2940 | ||
2908 | if (ieee80211_is_mgmt(fc)) | 2941 | if (ieee80211_is_mgmt(fc)) { |
2909 | err = skb_linearize(skb); | 2942 | /* drop frame if too short for header */ |
2910 | else | 2943 | if (skb->len < ieee80211_hdrlen(fc)) |
2944 | err = -ENOBUFS; | ||
2945 | else | ||
2946 | err = skb_linearize(skb); | ||
2947 | } else { | ||
2911 | err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); | 2948 | err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); |
2949 | } | ||
2912 | 2950 | ||
2913 | if (err) { | 2951 | if (err) { |
2914 | dev_kfree_skb(skb); | 2952 | dev_kfree_skb(skb); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index daf55e1e0fd3..f7bb54f9ab72 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -664,7 +664,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, | |||
664 | */ | 664 | */ |
665 | if (!skb) | 665 | if (!skb) |
666 | break; | 666 | break; |
667 | dev_kfree_skb(skb); | 667 | ieee80211_free_txskb(&local->hw, skb); |
668 | } | 668 | } |
669 | 669 | ||
670 | /* | 670 | /* |
@@ -693,7 +693,7 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, | |||
693 | local->total_ps_buffered--; | 693 | local->total_ps_buffered--; |
694 | ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", | 694 | ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", |
695 | sta->sta.addr); | 695 | sta->sta.addr); |
696 | dev_kfree_skb(skb); | 696 | ieee80211_free_txskb(&local->hw, skb); |
697 | } | 697 | } |
698 | 698 | ||
699 | /* | 699 | /* |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index dd0e6f20fc51..6636d3962317 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -406,7 +406,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
406 | int queue = info->hw_queue; | 406 | int queue = info->hw_queue; |
407 | 407 | ||
408 | if (WARN_ON(!info->control.vif)) { | 408 | if (WARN_ON(!info->control.vif)) { |
409 | kfree_skb(skb); | 409 | ieee80211_free_txskb(&local->hw, skb); |
410 | return; | 410 | return; |
411 | } | 411 | } |
412 | 412 | ||
@@ -431,7 +431,7 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
431 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 431 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
432 | 432 | ||
433 | if (WARN_ON(!info->control.vif)) { | 433 | if (WARN_ON(!info->control.vif)) { |
434 | kfree_skb(skb); | 434 | ieee80211_free_txskb(&local->hw, skb); |
435 | continue; | 435 | continue; |
436 | } | 436 | } |
437 | 437 | ||
@@ -643,13 +643,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | |||
643 | break; | 643 | break; |
644 | } | 644 | } |
645 | 645 | ||
646 | if (id != WLAN_EID_VENDOR_SPECIFIC && | 646 | switch (id) { |
647 | id != WLAN_EID_QUIET && | 647 | case WLAN_EID_SSID: |
648 | test_bit(id, seen_elems)) { | 648 | case WLAN_EID_SUPP_RATES: |
649 | elems->parse_error = true; | 649 | case WLAN_EID_FH_PARAMS: |
650 | left -= elen; | 650 | case WLAN_EID_DS_PARAMS: |
651 | pos += elen; | 651 | case WLAN_EID_CF_PARAMS: |
652 | continue; | 652 | case WLAN_EID_TIM: |
653 | case WLAN_EID_IBSS_PARAMS: | ||
654 | case WLAN_EID_CHALLENGE: | ||
655 | case WLAN_EID_RSN: | ||
656 | case WLAN_EID_ERP_INFO: | ||
657 | case WLAN_EID_EXT_SUPP_RATES: | ||
658 | case WLAN_EID_HT_CAPABILITY: | ||
659 | case WLAN_EID_HT_OPERATION: | ||
660 | case WLAN_EID_VHT_CAPABILITY: | ||
661 | case WLAN_EID_VHT_OPERATION: | ||
662 | case WLAN_EID_MESH_ID: | ||
663 | case WLAN_EID_MESH_CONFIG: | ||
664 | case WLAN_EID_PEER_MGMT: | ||
665 | case WLAN_EID_PREQ: | ||
666 | case WLAN_EID_PREP: | ||
667 | case WLAN_EID_PERR: | ||
668 | case WLAN_EID_RANN: | ||
669 | case WLAN_EID_CHANNEL_SWITCH: | ||
670 | case WLAN_EID_EXT_CHANSWITCH_ANN: | ||
671 | case WLAN_EID_COUNTRY: | ||
672 | case WLAN_EID_PWR_CONSTRAINT: | ||
673 | case WLAN_EID_TIMEOUT_INTERVAL: | ||
674 | if (test_bit(id, seen_elems)) { | ||
675 | elems->parse_error = true; | ||
676 | left -= elen; | ||
677 | pos += elen; | ||
678 | continue; | ||
679 | } | ||
680 | break; | ||
653 | } | 681 | } |
654 | 682 | ||
655 | if (calc_crc && id < 64 && (filter & (1ULL << id))) | 683 | if (calc_crc && id < 64 && (filter & (1ULL << id))) |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index bdb53aba888e..8bd2f5c6a56e 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -106,7 +106,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
106 | if (status->flag & RX_FLAG_MMIC_ERROR) | 106 | if (status->flag & RX_FLAG_MMIC_ERROR) |
107 | goto mic_fail; | 107 | goto mic_fail; |
108 | 108 | ||
109 | if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key) | 109 | if (!(status->flag & RX_FLAG_IV_STRIPPED) && rx->key && |
110 | rx->key->conf.cipher == WLAN_CIPHER_SUITE_TKIP) | ||
110 | goto update_iv; | 111 | goto update_iv; |
111 | 112 | ||
112 | return RX_CONTINUE; | 113 | return RX_CONTINUE; |
@@ -545,14 +546,19 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
545 | 546 | ||
546 | static void bip_aad(struct sk_buff *skb, u8 *aad) | 547 | static void bip_aad(struct sk_buff *skb, u8 *aad) |
547 | { | 548 | { |
549 | __le16 mask_fc; | ||
550 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
551 | |||
548 | /* BIP AAD: FC(masked) || A1 || A2 || A3 */ | 552 | /* BIP AAD: FC(masked) || A1 || A2 || A3 */ |
549 | 553 | ||
550 | /* FC type/subtype */ | 554 | /* FC type/subtype */ |
551 | aad[0] = skb->data[0]; | ||
552 | /* Mask FC Retry, PwrMgt, MoreData flags to zero */ | 555 | /* Mask FC Retry, PwrMgt, MoreData flags to zero */ |
553 | aad[1] = skb->data[1] & ~(BIT(4) | BIT(5) | BIT(6)); | 556 | mask_fc = hdr->frame_control; |
557 | mask_fc &= ~cpu_to_le16(IEEE80211_FCTL_RETRY | IEEE80211_FCTL_PM | | ||
558 | IEEE80211_FCTL_MOREDATA); | ||
559 | put_unaligned(mask_fc, (__le16 *) &aad[0]); | ||
554 | /* A1 || A2 || A3 */ | 560 | /* A1 || A2 || A3 */ |
555 | memcpy(aad + 2, skb->data + 4, 3 * ETH_ALEN); | 561 | memcpy(aad + 2, &hdr->addr1, 3 * ETH_ALEN); |
556 | } | 562 | } |
557 | 563 | ||
558 | 564 | ||