diff options
-rw-r--r-- | include/net/mac80211.h | 6 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 38 | ||||
-rw-r--r-- | net/mac80211/rx.c | 102 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 2 |
4 files changed, 91 insertions, 57 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 73469d8b64bb..fe8b9dae4dee 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -581,9 +581,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) | |||
581 | * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index | 581 | * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index |
582 | * @RX_FLAG_40MHZ: HT40 (40 MHz) was used | 582 | * @RX_FLAG_40MHZ: HT40 (40 MHz) was used |
583 | * @RX_FLAG_SHORT_GI: Short guard interval was used | 583 | * @RX_FLAG_SHORT_GI: Short guard interval was used |
584 | * @RX_FLAG_INTERNAL_CMTR: set internally after frame was reported | ||
585 | * on cooked monitor to avoid double-reporting it for multiple | ||
586 | * virtual interfaces | ||
587 | */ | 584 | */ |
588 | enum mac80211_rx_flags { | 585 | enum mac80211_rx_flags { |
589 | RX_FLAG_MMIC_ERROR = 1<<0, | 586 | RX_FLAG_MMIC_ERROR = 1<<0, |
@@ -597,7 +594,6 @@ enum mac80211_rx_flags { | |||
597 | RX_FLAG_HT = 1<<9, | 594 | RX_FLAG_HT = 1<<9, |
598 | RX_FLAG_40MHZ = 1<<10, | 595 | RX_FLAG_40MHZ = 1<<10, |
599 | RX_FLAG_SHORT_GI = 1<<11, | 596 | RX_FLAG_SHORT_GI = 1<<11, |
600 | RX_FLAG_INTERNAL_CMTR = 1<<12, | ||
601 | }; | 597 | }; |
602 | 598 | ||
603 | /** | 599 | /** |
@@ -618,6 +614,7 @@ enum mac80211_rx_flags { | |||
618 | * @rate_idx: index of data rate into band's supported rates or MCS index if | 614 | * @rate_idx: index of data rate into band's supported rates or MCS index if |
619 | * HT rates are use (RX_FLAG_HT) | 615 | * HT rates are use (RX_FLAG_HT) |
620 | * @flag: %RX_FLAG_* | 616 | * @flag: %RX_FLAG_* |
617 | * @rx_flags: internal RX flags for mac80211 | ||
621 | */ | 618 | */ |
622 | struct ieee80211_rx_status { | 619 | struct ieee80211_rx_status { |
623 | u64 mactime; | 620 | u64 mactime; |
@@ -627,6 +624,7 @@ struct ieee80211_rx_status { | |||
627 | int antenna; | 624 | int antenna; |
628 | int rate_idx; | 625 | int rate_idx; |
629 | int flag; | 626 | int flag; |
627 | unsigned int rx_flags; | ||
630 | }; | 628 | }; |
631 | 629 | ||
632 | /** | 630 | /** |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 40f747273389..945fbf29719d 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -159,13 +159,37 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
159 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) | 159 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) |
160 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) | 160 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) |
161 | 161 | ||
162 | #define IEEE80211_RX_IN_SCAN BIT(0) | 162 | /** |
163 | /* frame is destined to interface currently processed (incl. multicast frames) */ | 163 | * enum ieee80211_packet_rx_flags - packet RX flags |
164 | #define IEEE80211_RX_RA_MATCH BIT(1) | 164 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed |
165 | #define IEEE80211_RX_AMSDU BIT(2) | 165 | * (incl. multicast frames) |
166 | #define IEEE80211_RX_FRAGMENTED BIT(3) | 166 | * @IEEE80211_RX_IN_SCAN: received while scanning |
167 | #define IEEE80211_MALFORMED_ACTION_FRM BIT(4) | 167 | * @IEEE80211_RX_FRAGMENTED: fragmented frame |
168 | /* only add flags here that do not change with subframes of an aMPDU */ | 168 | * @IEEE80211_RX_AMSDU: a-MSDU packet |
169 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed | ||
170 | * | ||
171 | * These are per-frame flags that are attached to a frame in the | ||
172 | * @rx_flags field of &struct ieee80211_rx_status. | ||
173 | */ | ||
174 | enum ieee80211_packet_rx_flags { | ||
175 | IEEE80211_RX_IN_SCAN = BIT(0), | ||
176 | IEEE80211_RX_RA_MATCH = BIT(1), | ||
177 | IEEE80211_RX_FRAGMENTED = BIT(2), | ||
178 | IEEE80211_RX_AMSDU = BIT(3), | ||
179 | IEEE80211_RX_MALFORMED_ACTION_FRM = BIT(4), | ||
180 | }; | ||
181 | |||
182 | /** | ||
183 | * enum ieee80211_rx_flags - RX data flags | ||
184 | * | ||
185 | * @IEEE80211_RX_CMNTR: received on cooked monitor already | ||
186 | * | ||
187 | * These flags are used across handling multiple interfaces | ||
188 | * for a single frame. | ||
189 | */ | ||
190 | enum ieee80211_rx_flags { | ||
191 | IEEE80211_RX_CMNTR = BIT(0), | ||
192 | }; | ||
169 | 193 | ||
170 | struct ieee80211_rx_data { | 194 | struct ieee80211_rx_data { |
171 | struct sk_buff *skb; | 195 | struct sk_buff *skb; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8c666e9e8fb0..0b0e83ebe3d5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -315,6 +315,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
315 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | 315 | static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) |
316 | { | 316 | { |
317 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 317 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
318 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
318 | int tid; | 319 | int tid; |
319 | 320 | ||
320 | /* does the frame have a qos control field? */ | 321 | /* does the frame have a qos control field? */ |
@@ -323,9 +324,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
323 | /* frame has qos control */ | 324 | /* frame has qos control */ |
324 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; | 325 | tid = *qc & IEEE80211_QOS_CTL_TID_MASK; |
325 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) | 326 | if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT) |
326 | rx->flags |= IEEE80211_RX_AMSDU; | 327 | status->rx_flags |= IEEE80211_RX_AMSDU; |
327 | else | ||
328 | rx->flags &= ~IEEE80211_RX_AMSDU; | ||
329 | } else { | 328 | } else { |
330 | /* | 329 | /* |
331 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): | 330 | * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"): |
@@ -387,9 +386,10 @@ static ieee80211_rx_result debug_noinline | |||
387 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 386 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
388 | { | 387 | { |
389 | struct ieee80211_local *local = rx->local; | 388 | struct ieee80211_local *local = rx->local; |
389 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
390 | struct sk_buff *skb = rx->skb; | 390 | struct sk_buff *skb = rx->skb; |
391 | 391 | ||
392 | if (likely(!(rx->flags & IEEE80211_RX_IN_SCAN))) | 392 | if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN))) |
393 | return RX_CONTINUE; | 393 | return RX_CONTINUE; |
394 | 394 | ||
395 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) | 395 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) |
@@ -783,13 +783,14 @@ static ieee80211_rx_result debug_noinline | |||
783 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 783 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
784 | { | 784 | { |
785 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; | 785 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; |
786 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
786 | 787 | ||
787 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ | 788 | /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ |
788 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { | 789 | if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) { |
789 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && | 790 | if (unlikely(ieee80211_has_retry(hdr->frame_control) && |
790 | rx->sta->last_seq_ctrl[rx->queue] == | 791 | rx->sta->last_seq_ctrl[rx->queue] == |
791 | hdr->seq_ctrl)) { | 792 | hdr->seq_ctrl)) { |
792 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 793 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
793 | rx->local->dot11FrameDuplicateCount++; | 794 | rx->local->dot11FrameDuplicateCount++; |
794 | rx->sta->num_duplicates++; | 795 | rx->sta->num_duplicates++; |
795 | } | 796 | } |
@@ -822,7 +823,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
822 | if ((!ieee80211_has_fromds(hdr->frame_control) && | 823 | if ((!ieee80211_has_fromds(hdr->frame_control) && |
823 | !ieee80211_has_tods(hdr->frame_control) && | 824 | !ieee80211_has_tods(hdr->frame_control) && |
824 | ieee80211_is_data(hdr->frame_control)) || | 825 | ieee80211_is_data(hdr->frame_control)) || |
825 | !(rx->flags & IEEE80211_RX_RA_MATCH)) { | 826 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { |
826 | /* Drop IBSS frames and frames for other hosts | 827 | /* Drop IBSS frames and frames for other hosts |
827 | * silently. */ | 828 | * silently. */ |
828 | return RX_DROP_MONITOR; | 829 | return RX_DROP_MONITOR; |
@@ -879,7 +880,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
879 | * No point in finding a key and decrypting if the frame is neither | 880 | * No point in finding a key and decrypting if the frame is neither |
880 | * addressed to us nor a multicast frame. | 881 | * addressed to us nor a multicast frame. |
881 | */ | 882 | */ |
882 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 883 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
883 | return RX_CONTINUE; | 884 | return RX_CONTINUE; |
884 | 885 | ||
885 | /* start without a key */ | 886 | /* start without a key */ |
@@ -1112,7 +1113,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1112 | sta->last_rx = jiffies; | 1113 | sta->last_rx = jiffies; |
1113 | } | 1114 | } |
1114 | 1115 | ||
1115 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1116 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1116 | return RX_CONTINUE; | 1117 | return RX_CONTINUE; |
1117 | 1118 | ||
1118 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) | 1119 | if (rx->sdata->vif.type == NL80211_IFTYPE_STATION) |
@@ -1269,6 +1270,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1269 | unsigned int frag, seq; | 1270 | unsigned int frag, seq; |
1270 | struct ieee80211_fragment_entry *entry; | 1271 | struct ieee80211_fragment_entry *entry; |
1271 | struct sk_buff *skb; | 1272 | struct sk_buff *skb; |
1273 | struct ieee80211_rx_status *status; | ||
1272 | 1274 | ||
1273 | hdr = (struct ieee80211_hdr *)rx->skb->data; | 1275 | hdr = (struct ieee80211_hdr *)rx->skb->data; |
1274 | fc = hdr->frame_control; | 1276 | fc = hdr->frame_control; |
@@ -1368,7 +1370,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1368 | } | 1370 | } |
1369 | 1371 | ||
1370 | /* Complete frame has been reassembled - process it now */ | 1372 | /* Complete frame has been reassembled - process it now */ |
1371 | rx->flags |= IEEE80211_RX_FRAGMENTED; | 1373 | status = IEEE80211_SKB_RXCB(rx->skb); |
1374 | status->rx_flags |= IEEE80211_RX_FRAGMENTED; | ||
1372 | 1375 | ||
1373 | out: | 1376 | out: |
1374 | if (rx->sta) | 1377 | if (rx->sta) |
@@ -1385,9 +1388,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1385 | { | 1388 | { |
1386 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1389 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1387 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 1390 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
1391 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1388 | 1392 | ||
1389 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 1393 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
1390 | !(rx->flags & IEEE80211_RX_RA_MATCH))) | 1394 | !(status->rx_flags & IEEE80211_RX_RA_MATCH))) |
1391 | return RX_CONTINUE; | 1395 | return RX_CONTINUE; |
1392 | 1396 | ||
1393 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && | 1397 | if ((sdata->vif.type != NL80211_IFTYPE_AP) && |
@@ -1548,6 +1552,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1548 | struct sk_buff *skb, *xmit_skb; | 1552 | struct sk_buff *skb, *xmit_skb; |
1549 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; | 1553 | struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; |
1550 | struct sta_info *dsta; | 1554 | struct sta_info *dsta; |
1555 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1551 | 1556 | ||
1552 | skb = rx->skb; | 1557 | skb = rx->skb; |
1553 | xmit_skb = NULL; | 1558 | xmit_skb = NULL; |
@@ -1555,7 +1560,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1555 | if ((sdata->vif.type == NL80211_IFTYPE_AP || | 1560 | if ((sdata->vif.type == NL80211_IFTYPE_AP || |
1556 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && | 1561 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && |
1557 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && | 1562 | !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) && |
1558 | (rx->flags & IEEE80211_RX_RA_MATCH) && | 1563 | (status->rx_flags & IEEE80211_RX_RA_MATCH) && |
1559 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { | 1564 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) { |
1560 | if (is_multicast_ether_addr(ehdr->h_dest)) { | 1565 | if (is_multicast_ether_addr(ehdr->h_dest)) { |
1561 | /* | 1566 | /* |
@@ -1632,6 +1637,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1632 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1637 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1633 | __le16 fc = hdr->frame_control; | 1638 | __le16 fc = hdr->frame_control; |
1634 | struct sk_buff_head frame_list; | 1639 | struct sk_buff_head frame_list; |
1640 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1635 | 1641 | ||
1636 | if (unlikely(!ieee80211_is_data(fc))) | 1642 | if (unlikely(!ieee80211_is_data(fc))) |
1637 | return RX_CONTINUE; | 1643 | return RX_CONTINUE; |
@@ -1639,7 +1645,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1639 | if (unlikely(!ieee80211_is_data_present(fc))) | 1645 | if (unlikely(!ieee80211_is_data_present(fc))) |
1640 | return RX_DROP_MONITOR; | 1646 | return RX_DROP_MONITOR; |
1641 | 1647 | ||
1642 | if (!(rx->flags & IEEE80211_RX_AMSDU)) | 1648 | if (!(status->rx_flags & IEEE80211_RX_AMSDU)) |
1643 | return RX_CONTINUE; | 1649 | return RX_CONTINUE; |
1644 | 1650 | ||
1645 | if (ieee80211_has_a4(hdr->frame_control) && | 1651 | if (ieee80211_has_a4(hdr->frame_control) && |
@@ -1690,6 +1696,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1690 | struct sk_buff *skb = rx->skb, *fwd_skb; | 1696 | struct sk_buff *skb = rx->skb, *fwd_skb; |
1691 | struct ieee80211_local *local = rx->local; | 1697 | struct ieee80211_local *local = rx->local; |
1692 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1698 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1699 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
1693 | 1700 | ||
1694 | hdr = (struct ieee80211_hdr *) skb->data; | 1701 | hdr = (struct ieee80211_hdr *) skb->data; |
1695 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 1702 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
@@ -1735,7 +1742,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1735 | 1742 | ||
1736 | mesh_hdr->ttl--; | 1743 | mesh_hdr->ttl--; |
1737 | 1744 | ||
1738 | if (rx->flags & IEEE80211_RX_RA_MATCH) { | 1745 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) { |
1739 | if (!mesh_hdr->ttl) | 1746 | if (!mesh_hdr->ttl) |
1740 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, | 1747 | IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh, |
1741 | dropped_frames_ttl); | 1748 | dropped_frames_ttl); |
@@ -1945,6 +1952,7 @@ static ieee80211_rx_result debug_noinline | |||
1945 | ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | 1952 | ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) |
1946 | { | 1953 | { |
1947 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1954 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1955 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1948 | 1956 | ||
1949 | /* | 1957 | /* |
1950 | * From here on, look only at management frames. | 1958 | * From here on, look only at management frames. |
@@ -1957,7 +1965,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) | |||
1957 | if (!ieee80211_is_mgmt(mgmt->frame_control)) | 1965 | if (!ieee80211_is_mgmt(mgmt->frame_control)) |
1958 | return RX_DROP_MONITOR; | 1966 | return RX_DROP_MONITOR; |
1959 | 1967 | ||
1960 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1968 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1961 | return RX_DROP_MONITOR; | 1969 | return RX_DROP_MONITOR; |
1962 | 1970 | ||
1963 | if (ieee80211_drop_unencrypted_mgmt(rx)) | 1971 | if (ieee80211_drop_unencrypted_mgmt(rx)) |
@@ -1972,6 +1980,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1972 | struct ieee80211_local *local = rx->local; | 1980 | struct ieee80211_local *local = rx->local; |
1973 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 1981 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1974 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 1982 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
1983 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
1975 | int len = rx->skb->len; | 1984 | int len = rx->skb->len; |
1976 | 1985 | ||
1977 | if (!ieee80211_is_action(mgmt->frame_control)) | 1986 | if (!ieee80211_is_action(mgmt->frame_control)) |
@@ -1984,7 +1993,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
1984 | if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) | 1993 | if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) |
1985 | return RX_DROP_UNUSABLE; | 1994 | return RX_DROP_UNUSABLE; |
1986 | 1995 | ||
1987 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 1996 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
1988 | return RX_DROP_UNUSABLE; | 1997 | return RX_DROP_UNUSABLE; |
1989 | 1998 | ||
1990 | switch (mgmt->u.action.category) { | 1999 | switch (mgmt->u.action.category) { |
@@ -2080,7 +2089,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2080 | return RX_CONTINUE; | 2089 | return RX_CONTINUE; |
2081 | 2090 | ||
2082 | invalid: | 2091 | invalid: |
2083 | rx->flags |= IEEE80211_MALFORMED_ACTION_FRM; | 2092 | status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM; |
2084 | /* will return in the next handlers */ | 2093 | /* will return in the next handlers */ |
2085 | return RX_CONTINUE; | 2094 | return RX_CONTINUE; |
2086 | 2095 | ||
@@ -2102,10 +2111,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) | |||
2102 | static ieee80211_rx_result debug_noinline | 2111 | static ieee80211_rx_result debug_noinline |
2103 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | 2112 | ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) |
2104 | { | 2113 | { |
2105 | struct ieee80211_rx_status *status; | 2114 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); |
2106 | 2115 | ||
2107 | /* skip known-bad action frames and return them in the next handler */ | 2116 | /* skip known-bad action frames and return them in the next handler */ |
2108 | if (rx->flags & IEEE80211_MALFORMED_ACTION_FRM) | 2117 | if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) |
2109 | return RX_CONTINUE; | 2118 | return RX_CONTINUE; |
2110 | 2119 | ||
2111 | /* | 2120 | /* |
@@ -2114,7 +2123,6 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2114 | * so userspace can register for those to know whether ones | 2123 | * so userspace can register for those to know whether ones |
2115 | * it transmitted were processed or returned. | 2124 | * it transmitted were processed or returned. |
2116 | */ | 2125 | */ |
2117 | status = IEEE80211_SKB_RXCB(rx->skb); | ||
2118 | 2126 | ||
2119 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, | 2127 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, |
2120 | rx->skb->data, rx->skb->len, | 2128 | rx->skb->data, rx->skb->len, |
@@ -2136,6 +2144,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
2136 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; | 2144 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data; |
2137 | struct sk_buff *nskb; | 2145 | struct sk_buff *nskb; |
2138 | struct ieee80211_sub_if_data *sdata = rx->sdata; | 2146 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
2147 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
2139 | 2148 | ||
2140 | if (!ieee80211_is_action(mgmt->frame_control)) | 2149 | if (!ieee80211_is_action(mgmt->frame_control)) |
2141 | return RX_CONTINUE; | 2150 | return RX_CONTINUE; |
@@ -2150,7 +2159,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) | |||
2150 | * registration mechanisms, but older ones still use cooked | 2159 | * registration mechanisms, but older ones still use cooked |
2151 | * monitor interfaces so push all frames there. | 2160 | * monitor interfaces so push all frames there. |
2152 | */ | 2161 | */ |
2153 | if (!(rx->flags & IEEE80211_MALFORMED_ACTION_FRM) && | 2162 | if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) && |
2154 | (sdata->vif.type == NL80211_IFTYPE_AP || | 2163 | (sdata->vif.type == NL80211_IFTYPE_AP || |
2155 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) | 2164 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) |
2156 | return RX_DROP_MONITOR; | 2165 | return RX_DROP_MONITOR; |
@@ -2284,8 +2293,13 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2284 | struct net_device *prev_dev = NULL; | 2293 | struct net_device *prev_dev = NULL; |
2285 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 2294 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
2286 | 2295 | ||
2287 | if (status->flag & RX_FLAG_INTERNAL_CMTR) | 2296 | /* |
2297 | * If cooked monitor has been processed already, then | ||
2298 | * don't do it again. If not, set the flag. | ||
2299 | */ | ||
2300 | if (rx->flags & IEEE80211_RX_CMNTR) | ||
2288 | goto out_free_skb; | 2301 | goto out_free_skb; |
2302 | rx->flags |= IEEE80211_RX_CMNTR; | ||
2289 | 2303 | ||
2290 | if (skb_headroom(skb) < sizeof(*rthdr) && | 2304 | if (skb_headroom(skb) < sizeof(*rthdr) && |
2291 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) | 2305 | pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) |
@@ -2341,12 +2355,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, | |||
2341 | if (prev_dev) { | 2355 | if (prev_dev) { |
2342 | skb->dev = prev_dev; | 2356 | skb->dev = prev_dev; |
2343 | netif_receive_skb(skb); | 2357 | netif_receive_skb(skb); |
2344 | skb = NULL; | 2358 | return; |
2345 | } else | 2359 | } |
2346 | goto out_free_skb; | ||
2347 | |||
2348 | status->flag |= RX_FLAG_INTERNAL_CMTR; | ||
2349 | return; | ||
2350 | 2360 | ||
2351 | out_free_skb: | 2361 | out_free_skb: |
2352 | dev_kfree_skb(skb); | 2362 | dev_kfree_skb(skb); |
@@ -2407,6 +2417,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx, | |||
2407 | * same TID from the same station | 2417 | * same TID from the same station |
2408 | */ | 2418 | */ |
2409 | rx->skb = skb; | 2419 | rx->skb = skb; |
2420 | rx->flags = 0; | ||
2410 | 2421 | ||
2411 | CALL_RXH(ieee80211_rx_h_decrypt) | 2422 | CALL_RXH(ieee80211_rx_h_decrypt) |
2412 | CALL_RXH(ieee80211_rx_h_check_more_data) | 2423 | CALL_RXH(ieee80211_rx_h_check_more_data) |
@@ -2477,7 +2488,12 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) | |||
2477 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | 2488 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) |
2478 | { | 2489 | { |
2479 | struct sk_buff_head frames; | 2490 | struct sk_buff_head frames; |
2480 | struct ieee80211_rx_data rx = { }; | 2491 | struct ieee80211_rx_data rx = { |
2492 | .sta = sta, | ||
2493 | .sdata = sta->sdata, | ||
2494 | .local = sta->local, | ||
2495 | .queue = tid, | ||
2496 | }; | ||
2481 | struct tid_ampdu_rx *tid_agg_rx; | 2497 | struct tid_ampdu_rx *tid_agg_rx; |
2482 | 2498 | ||
2483 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); | 2499 | tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); |
@@ -2486,13 +2502,6 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
2486 | 2502 | ||
2487 | __skb_queue_head_init(&frames); | 2503 | __skb_queue_head_init(&frames); |
2488 | 2504 | ||
2489 | /* construct rx struct */ | ||
2490 | rx.sta = sta; | ||
2491 | rx.sdata = sta->sdata; | ||
2492 | rx.local = sta->local; | ||
2493 | rx.queue = tid; | ||
2494 | rx.flags |= IEEE80211_RX_RA_MATCH; | ||
2495 | |||
2496 | spin_lock(&tid_agg_rx->reorder_lock); | 2505 | spin_lock(&tid_agg_rx->reorder_lock); |
2497 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); | 2506 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames); |
2498 | spin_unlock(&tid_agg_rx->reorder_lock); | 2507 | spin_unlock(&tid_agg_rx->reorder_lock); |
@@ -2519,7 +2528,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2519 | compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { | 2528 | compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) { |
2520 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2529 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2521 | return 0; | 2530 | return 0; |
2522 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2531 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2523 | } | 2532 | } |
2524 | break; | 2533 | break; |
2525 | case NL80211_IFTYPE_ADHOC: | 2534 | case NL80211_IFTYPE_ADHOC: |
@@ -2529,15 +2538,15 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2529 | return 1; | 2538 | return 1; |
2530 | } | 2539 | } |
2531 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 2540 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
2532 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2541 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) |
2533 | return 0; | 2542 | return 0; |
2534 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2543 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2535 | } else if (!multicast && | 2544 | } else if (!multicast && |
2536 | compare_ether_addr(sdata->vif.addr, | 2545 | compare_ether_addr(sdata->vif.addr, |
2537 | hdr->addr1) != 0) { | 2546 | hdr->addr1) != 0) { |
2538 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2547 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2539 | return 0; | 2548 | return 0; |
2540 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2549 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2541 | } else if (!rx->sta) { | 2550 | } else if (!rx->sta) { |
2542 | int rate_idx; | 2551 | int rate_idx; |
2543 | if (status->flag & RX_FLAG_HT) | 2552 | if (status->flag & RX_FLAG_HT) |
@@ -2555,7 +2564,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2555 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2564 | if (!(sdata->dev->flags & IFF_PROMISC)) |
2556 | return 0; | 2565 | return 0; |
2557 | 2566 | ||
2558 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2567 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2559 | } | 2568 | } |
2560 | break; | 2569 | break; |
2561 | case NL80211_IFTYPE_AP_VLAN: | 2570 | case NL80211_IFTYPE_AP_VLAN: |
@@ -2566,9 +2575,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2566 | return 0; | 2575 | return 0; |
2567 | } else if (!ieee80211_bssid_match(bssid, | 2576 | } else if (!ieee80211_bssid_match(bssid, |
2568 | sdata->vif.addr)) { | 2577 | sdata->vif.addr)) { |
2569 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 2578 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) |
2570 | return 0; | 2579 | return 0; |
2571 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 2580 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2572 | } | 2581 | } |
2573 | break; | 2582 | break; |
2574 | case NL80211_IFTYPE_WDS: | 2583 | case NL80211_IFTYPE_WDS: |
@@ -2602,14 +2611,14 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
2602 | int prepares; | 2611 | int prepares; |
2603 | 2612 | ||
2604 | rx->skb = skb; | 2613 | rx->skb = skb; |
2605 | rx->flags |= IEEE80211_RX_RA_MATCH; | 2614 | status->rx_flags |= IEEE80211_RX_RA_MATCH; |
2606 | prepares = prepare_for_handlers(rx, hdr); | 2615 | prepares = prepare_for_handlers(rx, hdr); |
2607 | 2616 | ||
2608 | if (!prepares) | 2617 | if (!prepares) |
2609 | return false; | 2618 | return false; |
2610 | 2619 | ||
2611 | if (status->flag & RX_FLAG_MMIC_ERROR) { | 2620 | if (status->flag & RX_FLAG_MMIC_ERROR) { |
2612 | if (rx->flags & IEEE80211_RX_RA_MATCH) | 2621 | if (status->rx_flags & IEEE80211_RX_RA_MATCH) |
2613 | ieee80211_rx_michael_mic_report(hdr, rx); | 2622 | ieee80211_rx_michael_mic_report(hdr, rx); |
2614 | return false; | 2623 | return false; |
2615 | } | 2624 | } |
@@ -2638,6 +2647,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
2638 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 2647 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
2639 | struct sk_buff *skb) | 2648 | struct sk_buff *skb) |
2640 | { | 2649 | { |
2650 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2641 | struct ieee80211_local *local = hw_to_local(hw); | 2651 | struct ieee80211_local *local = hw_to_local(hw); |
2642 | struct ieee80211_sub_if_data *sdata; | 2652 | struct ieee80211_sub_if_data *sdata; |
2643 | struct ieee80211_hdr *hdr; | 2653 | struct ieee80211_hdr *hdr; |
@@ -2657,7 +2667,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2657 | 2667 | ||
2658 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 2668 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
2659 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) | 2669 | test_bit(SCAN_OFF_CHANNEL, &local->scanning))) |
2660 | rx.flags |= IEEE80211_RX_IN_SCAN; | 2670 | status->rx_flags |= IEEE80211_RX_IN_SCAN; |
2661 | 2671 | ||
2662 | if (ieee80211_is_mgmt(fc)) | 2672 | if (ieee80211_is_mgmt(fc)) |
2663 | err = skb_linearize(skb); | 2673 | err = skb_linearize(skb); |
@@ -2808,6 +2818,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2808 | } | 2818 | } |
2809 | } | 2819 | } |
2810 | 2820 | ||
2821 | status->rx_flags = 0; | ||
2822 | |||
2811 | /* | 2823 | /* |
2812 | * key references and virtual interfaces are protected using RCU | 2824 | * key references and virtual interfaces are protected using RCU |
2813 | * and this requires that we are in a read-side RCU section during | 2825 | * and this requires that we are in a read-side RCU section during |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 43882b36da55..bee230d8fd11 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -117,7 +117,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
117 | key = &rx->key->conf.key[key_offset]; | 117 | key = &rx->key->conf.key[key_offset]; |
118 | michael_mic(key, hdr, data, data_len, mic); | 118 | michael_mic(key, hdr, data, data_len, mic); |
119 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { | 119 | if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { |
120 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 120 | if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) |
121 | return RX_DROP_UNUSABLE; | 121 | return RX_DROP_UNUSABLE; |
122 | 122 | ||
123 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | 123 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, |