Commit 554891e63a29af35cc6bb403ef34e319518114d0

Authored by Johannes Berg
Committed by John W. Linville
1 parent 4080c7cdc2

mac80211: move packet flags into packet

commit 8c0c709eea5cbab97fb464cd68b06f24acc58ee1
Author: Johannes Berg <johannes@sipsolutions.net>
Date:   Wed Nov 25 17:46:15 2009 +0100

    mac80211: move cmntr flag out of rx flags

moved the CMNTR flag into the skb RX flags for
some aggregation cleanups, but this was wrong
since the optimisation this flag tried to make
requires that it is kept across the processing
of multiple interfaces -- which isn't true for
flags in the skb. The patch not only broke the
optimisation, it also introduced a bug: under
some (common!) circumstances the flag will be
set on an already freed skb!

However, investigating this in more detail, I
found that most of the flags that we set should
be per packet, _except_ for this one, due to
a-MPDU processing. Additionally, the flags used
for processing (currently just this one) need
to be reset before processing a new packet.

Since we haven't actually seen bugs reported as
a result of the wrong flags handling (which is
not too surprising -- the only real bug case I
can come up with is an a-MSDU contained in an
a-MPDU), I'll make a different fix for rc.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 4 changed files with 91 additions and 57 deletions Side-by-side Diff

include/net/mac80211.h
... ... @@ -581,9 +581,6 @@
581 581 * @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
582 582 * @RX_FLAG_40MHZ: HT40 (40 MHz) was used
583 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 585 enum mac80211_rx_flags {
589 586 RX_FLAG_MMIC_ERROR = 1<<0,
... ... @@ -597,7 +594,6 @@
597 594 RX_FLAG_HT = 1<<9,
598 595 RX_FLAG_40MHZ = 1<<10,
599 596 RX_FLAG_SHORT_GI = 1<<11,
600   - RX_FLAG_INTERNAL_CMTR = 1<<12,
601 597 };
602 598  
603 599 /**
... ... @@ -618,6 +614,7 @@
618 614 * @rate_idx: index of data rate into band's supported rates or MCS index if
619 615 * HT rates are use (RX_FLAG_HT)
620 616 * @flag: %RX_FLAG_*
  617 + * @rx_flags: internal RX flags for mac80211
621 618 */
622 619 struct ieee80211_rx_status {
623 620 u64 mactime;
... ... @@ -627,6 +624,7 @@
627 624 int antenna;
628 625 int rate_idx;
629 626 int flag;
  627 + unsigned int rx_flags;
630 628 };
631 629  
632 630 /**
net/mac80211/ieee80211_i.h
... ... @@ -159,13 +159,37 @@
159 159 #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u)
160 160 #define RX_QUEUED ((__force ieee80211_rx_result) 3u)
161 161  
162   -#define IEEE80211_RX_IN_SCAN BIT(0)
163   -/* frame is destined to interface currently processed (incl. multicast frames) */
164   -#define IEEE80211_RX_RA_MATCH BIT(1)
165   -#define IEEE80211_RX_AMSDU BIT(2)
166   -#define IEEE80211_RX_FRAGMENTED BIT(3)
167   -#define IEEE80211_MALFORMED_ACTION_FRM BIT(4)
168   -/* only add flags here that do not change with subframes of an aMPDU */
  162 +/**
  163 + * enum ieee80211_packet_rx_flags - packet RX flags
  164 + * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed
  165 + * (incl. multicast frames)
  166 + * @IEEE80211_RX_IN_SCAN: received while scanning
  167 + * @IEEE80211_RX_FRAGMENTED: fragmented frame
  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 194 struct ieee80211_rx_data {
171 195 struct sk_buff *skb;
... ... @@ -315,6 +315,7 @@
315 315 static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
316 316 {
317 317 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
  318 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
318 319 int tid;
319 320  
320 321 /* does the frame have a qos control field? */
... ... @@ -323,9 +324,7 @@
323 324 /* frame has qos control */
324 325 tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
325 326 if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
326   - rx->flags |= IEEE80211_RX_AMSDU;
327   - else
328   - rx->flags &= ~IEEE80211_RX_AMSDU;
  327 + status->rx_flags |= IEEE80211_RX_AMSDU;
329 328 } else {
330 329 /*
331 330 * IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"):
332 331  
... ... @@ -387,9 +386,10 @@
387 386 ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
388 387 {
389 388 struct ieee80211_local *local = rx->local;
  389 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
390 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 393 return RX_CONTINUE;
394 394  
395 395 if (test_bit(SCAN_HW_SCANNING, &local->scanning))
396 396  
... ... @@ -783,13 +783,14 @@
783 783 ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
784 784 {
785 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 788 /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
788 789 if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
789 790 if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
790 791 rx->sta->last_seq_ctrl[rx->queue] ==
791 792 hdr->seq_ctrl)) {
792   - if (rx->flags & IEEE80211_RX_RA_MATCH) {
  793 + if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
793 794 rx->local->dot11FrameDuplicateCount++;
794 795 rx->sta->num_duplicates++;
795 796 }
... ... @@ -822,7 +823,7 @@
822 823 if ((!ieee80211_has_fromds(hdr->frame_control) &&
823 824 !ieee80211_has_tods(hdr->frame_control) &&
824 825 ieee80211_is_data(hdr->frame_control)) ||
825   - !(rx->flags & IEEE80211_RX_RA_MATCH)) {
  826 + !(status->rx_flags & IEEE80211_RX_RA_MATCH)) {
826 827 /* Drop IBSS frames and frames for other hosts
827 828 * silently. */
828 829 return RX_DROP_MONITOR;
... ... @@ -879,7 +880,7 @@
879 880 * No point in finding a key and decrypting if the frame is neither
880 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 884 return RX_CONTINUE;
884 885  
885 886 /* start without a key */
... ... @@ -1112,7 +1113,7 @@
1112 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 1117 return RX_CONTINUE;
1117 1118  
1118 1119 if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)
... ... @@ -1269,6 +1270,7 @@
1269 1270 unsigned int frag, seq;
1270 1271 struct ieee80211_fragment_entry *entry;
1271 1272 struct sk_buff *skb;
  1273 + struct ieee80211_rx_status *status;
1272 1274  
1273 1275 hdr = (struct ieee80211_hdr *)rx->skb->data;
1274 1276 fc = hdr->frame_control;
... ... @@ -1368,7 +1370,8 @@
1368 1370 }
1369 1371  
1370 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 1376 out:
1374 1377 if (rx->sta)
1375 1378  
... ... @@ -1385,9 +1388,10 @@
1385 1388 {
1386 1389 struct ieee80211_sub_if_data *sdata = rx->sdata;
1387 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 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 1395 return RX_CONTINUE;
1392 1396  
1393 1397 if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
... ... @@ -1548,6 +1552,7 @@
1548 1552 struct sk_buff *skb, *xmit_skb;
1549 1553 struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
1550 1554 struct sta_info *dsta;
  1555 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1551 1556  
1552 1557 skb = rx->skb;
1553 1558 xmit_skb = NULL;
... ... @@ -1555,7 +1560,7 @@
1555 1560 if ((sdata->vif.type == NL80211_IFTYPE_AP ||
1556 1561 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
1557 1562 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
1558   - (rx->flags & IEEE80211_RX_RA_MATCH) &&
  1563 + (status->rx_flags & IEEE80211_RX_RA_MATCH) &&
1559 1564 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) {
1560 1565 if (is_multicast_ether_addr(ehdr->h_dest)) {
1561 1566 /*
... ... @@ -1632,6 +1637,7 @@
1632 1637 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1633 1638 __le16 fc = hdr->frame_control;
1634 1639 struct sk_buff_head frame_list;
  1640 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1635 1641  
1636 1642 if (unlikely(!ieee80211_is_data(fc)))
1637 1643 return RX_CONTINUE;
... ... @@ -1639,7 +1645,7 @@
1639 1645 if (unlikely(!ieee80211_is_data_present(fc)))
1640 1646 return RX_DROP_MONITOR;
1641 1647  
1642   - if (!(rx->flags & IEEE80211_RX_AMSDU))
  1648 + if (!(status->rx_flags & IEEE80211_RX_AMSDU))
1643 1649 return RX_CONTINUE;
1644 1650  
1645 1651 if (ieee80211_has_a4(hdr->frame_control) &&
... ... @@ -1690,6 +1696,7 @@
1690 1696 struct sk_buff *skb = rx->skb, *fwd_skb;
1691 1697 struct ieee80211_local *local = rx->local;
1692 1698 struct ieee80211_sub_if_data *sdata = rx->sdata;
  1699 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
1693 1700  
1694 1701 hdr = (struct ieee80211_hdr *) skb->data;
1695 1702 hdrlen = ieee80211_hdrlen(hdr->frame_control);
... ... @@ -1735,7 +1742,7 @@
1735 1742  
1736 1743 mesh_hdr->ttl--;
1737 1744  
1738   - if (rx->flags & IEEE80211_RX_RA_MATCH) {
  1745 + if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
1739 1746 if (!mesh_hdr->ttl)
1740 1747 IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh,
1741 1748 dropped_frames_ttl);
... ... @@ -1945,6 +1952,7 @@
1945 1952 ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
1946 1953 {
1947 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 1958 * From here on, look only at management frames.
... ... @@ -1957,7 +1965,7 @@
1957 1965 if (!ieee80211_is_mgmt(mgmt->frame_control))
1958 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 1969 return RX_DROP_MONITOR;
1962 1970  
1963 1971 if (ieee80211_drop_unencrypted_mgmt(rx))
... ... @@ -1972,6 +1980,7 @@
1972 1980 struct ieee80211_local *local = rx->local;
1973 1981 struct ieee80211_sub_if_data *sdata = rx->sdata;
1974 1982 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
  1983 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
1975 1984 int len = rx->skb->len;
1976 1985  
1977 1986 if (!ieee80211_is_action(mgmt->frame_control))
... ... @@ -1984,7 +1993,7 @@
1984 1993 if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
1985 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 1997 return RX_DROP_UNUSABLE;
1989 1998  
1990 1999 switch (mgmt->u.action.category) {
... ... @@ -2080,7 +2089,7 @@
2080 2089 return RX_CONTINUE;
2081 2090  
2082 2091 invalid:
2083   - rx->flags |= IEEE80211_MALFORMED_ACTION_FRM;
  2092 + status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM;
2084 2093 /* will return in the next handlers */
2085 2094 return RX_CONTINUE;
2086 2095  
2087 2096  
... ... @@ -2102,10 +2111,10 @@
2102 2111 static ieee80211_rx_result debug_noinline
2103 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 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 2118 return RX_CONTINUE;
2110 2119  
2111 2120 /*
... ... @@ -2114,7 +2123,6 @@
2114 2123 * so userspace can register for those to know whether ones
2115 2124 * it transmitted were processed or returned.
2116 2125 */
2117   - status = IEEE80211_SKB_RXCB(rx->skb);
2118 2126  
2119 2127 if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq,
2120 2128 rx->skb->data, rx->skb->len,
... ... @@ -2136,6 +2144,7 @@
2136 2144 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
2137 2145 struct sk_buff *nskb;
2138 2146 struct ieee80211_sub_if_data *sdata = rx->sdata;
  2147 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
2139 2148  
2140 2149 if (!ieee80211_is_action(mgmt->frame_control))
2141 2150 return RX_CONTINUE;
... ... @@ -2150,7 +2159,7 @@
2150 2159 * registration mechanisms, but older ones still use cooked
2151 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 2163 (sdata->vif.type == NL80211_IFTYPE_AP ||
2155 2164 sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
2156 2165 return RX_DROP_MONITOR;
2157 2166  
... ... @@ -2284,8 +2293,13 @@
2284 2293 struct net_device *prev_dev = NULL;
2285 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 2301 goto out_free_skb;
  2302 + rx->flags |= IEEE80211_RX_CMNTR;
2289 2303  
2290 2304 if (skb_headroom(skb) < sizeof(*rthdr) &&
2291 2305 pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
2292 2306  
... ... @@ -2341,13 +2355,9 @@
2341 2355 if (prev_dev) {
2342 2356 skb->dev = prev_dev;
2343 2357 netif_receive_skb(skb);
2344   - skb = NULL;
2345   - } else
2346   - goto out_free_skb;
  2358 + return;
  2359 + }
2347 2360  
2348   - status->flag |= RX_FLAG_INTERNAL_CMTR;
2349   - return;
2350   -
2351 2361 out_free_skb:
2352 2362 dev_kfree_skb(skb);
2353 2363 }
... ... @@ -2407,6 +2417,7 @@
2407 2417 * same TID from the same station
2408 2418 */
2409 2419 rx->skb = skb;
  2420 + rx->flags = 0;
2410 2421  
2411 2422 CALL_RXH(ieee80211_rx_h_decrypt)
2412 2423 CALL_RXH(ieee80211_rx_h_check_more_data)
... ... @@ -2477,7 +2488,12 @@
2477 2488 void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
2478 2489 {
2479 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 2497 struct tid_ampdu_rx *tid_agg_rx;
2482 2498  
2483 2499 tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
... ... @@ -2486,13 +2502,6 @@
2486 2502  
2487 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 2505 spin_lock(&tid_agg_rx->reorder_lock);
2497 2506 ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames);
2498 2507 spin_unlock(&tid_agg_rx->reorder_lock);
... ... @@ -2519,7 +2528,7 @@
2519 2528 compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) {
2520 2529 if (!(sdata->dev->flags & IFF_PROMISC))
2521 2530 return 0;
2522   - rx->flags &= ~IEEE80211_RX_RA_MATCH;
  2531 + status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2523 2532 }
2524 2533 break;
2525 2534 case NL80211_IFTYPE_ADHOC:
2526 2535  
2527 2536  
... ... @@ -2529,15 +2538,15 @@
2529 2538 return 1;
2530 2539 }
2531 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 2542 return 0;
2534   - rx->flags &= ~IEEE80211_RX_RA_MATCH;
  2543 + status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2535 2544 } else if (!multicast &&
2536 2545 compare_ether_addr(sdata->vif.addr,
2537 2546 hdr->addr1) != 0) {
2538 2547 if (!(sdata->dev->flags & IFF_PROMISC))
2539 2548 return 0;
2540   - rx->flags &= ~IEEE80211_RX_RA_MATCH;
  2549 + status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2541 2550 } else if (!rx->sta) {
2542 2551 int rate_idx;
2543 2552 if (status->flag & RX_FLAG_HT)
... ... @@ -2555,7 +2564,7 @@
2555 2564 if (!(sdata->dev->flags & IFF_PROMISC))
2556 2565 return 0;
2557 2566  
2558   - rx->flags &= ~IEEE80211_RX_RA_MATCH;
  2567 + status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2559 2568 }
2560 2569 break;
2561 2570 case NL80211_IFTYPE_AP_VLAN:
2562 2571  
... ... @@ -2566,9 +2575,9 @@
2566 2575 return 0;
2567 2576 } else if (!ieee80211_bssid_match(bssid,
2568 2577 sdata->vif.addr)) {
2569   - if (!(rx->flags & IEEE80211_RX_IN_SCAN))
  2578 + if (!(status->rx_flags & IEEE80211_RX_IN_SCAN))
2570 2579 return 0;
2571   - rx->flags &= ~IEEE80211_RX_RA_MATCH;
  2580 + status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
2572 2581 }
2573 2582 break;
2574 2583 case NL80211_IFTYPE_WDS:
2575 2584  
... ... @@ -2602,14 +2611,14 @@
2602 2611 int prepares;
2603 2612  
2604 2613 rx->skb = skb;
2605   - rx->flags |= IEEE80211_RX_RA_MATCH;
  2614 + status->rx_flags |= IEEE80211_RX_RA_MATCH;
2606 2615 prepares = prepare_for_handlers(rx, hdr);
2607 2616  
2608 2617 if (!prepares)
2609 2618 return false;
2610 2619  
2611 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 2622 ieee80211_rx_michael_mic_report(hdr, rx);
2614 2623 return false;
2615 2624 }
... ... @@ -2638,6 +2647,7 @@
2638 2647 static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2639 2648 struct sk_buff *skb)
2640 2649 {
  2650 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
2641 2651 struct ieee80211_local *local = hw_to_local(hw);
2642 2652 struct ieee80211_sub_if_data *sdata;
2643 2653 struct ieee80211_hdr *hdr;
... ... @@ -2657,7 +2667,7 @@
2657 2667  
2658 2668 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2659 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 2672 if (ieee80211_is_mgmt(fc))
2663 2673 err = skb_linearize(skb);
... ... @@ -2807,6 +2817,8 @@
2807 2817 rate = &sband->bitrates[status->rate_idx];
2808 2818 }
2809 2819 }
  2820 +
  2821 + status->rx_flags = 0;
2810 2822  
2811 2823 /*
2812 2824 * key references and virtual interfaces are protected using RCU
... ... @@ -117,7 +117,7 @@
117 117 key = &rx->key->conf.key[key_offset];
118 118 michael_mic(key, hdr, data, data_len, mic);
119 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 121 return RX_DROP_UNUSABLE;
122 122  
123 123 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,