|
@@ -315,6 +315,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
|
|
static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
|
|
|
{
|
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
int tid;
|
|
|
|
|
|
/* does the frame have a qos control field? */
|
|
@@ -323,9 +324,7 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx)
|
|
|
/* frame has qos control */
|
|
|
tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
|
|
|
if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
|
|
|
- rx->flags |= IEEE80211_RX_AMSDU;
|
|
|
- else
|
|
|
- rx->flags &= ~IEEE80211_RX_AMSDU;
|
|
|
+ status->rx_flags |= IEEE80211_RX_AMSDU;
|
|
|
} else {
|
|
|
/*
|
|
|
* IEEE 802.11-2007, 7.1.3.4.1 ("Sequence Number field"):
|
|
@@ -387,9 +386,10 @@ static ieee80211_rx_result debug_noinline
|
|
|
ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
|
|
|
{
|
|
|
struct ieee80211_local *local = rx->local;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
struct sk_buff *skb = rx->skb;
|
|
|
|
|
|
- if (likely(!(rx->flags & IEEE80211_RX_IN_SCAN)))
|
|
|
+ if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN)))
|
|
|
return RX_CONTINUE;
|
|
|
|
|
|
if (test_bit(SCAN_HW_SCANNING, &local->scanning))
|
|
@@ -783,13 +783,14 @@ static ieee80211_rx_result debug_noinline
|
|
|
ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
|
|
|
{
|
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
|
|
|
if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
|
|
|
if (unlikely(ieee80211_has_retry(hdr->frame_control) &&
|
|
|
rx->sta->last_seq_ctrl[rx->queue] ==
|
|
|
hdr->seq_ctrl)) {
|
|
|
- if (rx->flags & IEEE80211_RX_RA_MATCH) {
|
|
|
+ if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
|
|
|
rx->local->dot11FrameDuplicateCount++;
|
|
|
rx->sta->num_duplicates++;
|
|
|
}
|
|
@@ -822,7 +823,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
|
|
|
if ((!ieee80211_has_fromds(hdr->frame_control) &&
|
|
|
!ieee80211_has_tods(hdr->frame_control) &&
|
|
|
ieee80211_is_data(hdr->frame_control)) ||
|
|
|
- !(rx->flags & IEEE80211_RX_RA_MATCH)) {
|
|
|
+ !(status->rx_flags & IEEE80211_RX_RA_MATCH)) {
|
|
|
/* Drop IBSS frames and frames for other hosts
|
|
|
* silently. */
|
|
|
return RX_DROP_MONITOR;
|
|
@@ -879,7 +880,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
|
|
|
* No point in finding a key and decrypting if the frame is neither
|
|
|
* addressed to us nor a multicast frame.
|
|
|
*/
|
|
|
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
|
|
|
return RX_CONTINUE;
|
|
|
|
|
|
/* start without a key */
|
|
@@ -1112,7 +1113,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
|
|
sta->last_rx = jiffies;
|
|
|
}
|
|
|
|
|
|
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
|
|
|
return RX_CONTINUE;
|
|
|
|
|
|
if (rx->sdata->vif.type == NL80211_IFTYPE_STATION)
|
|
@@ -1269,6 +1270,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
|
|
unsigned int frag, seq;
|
|
|
struct ieee80211_fragment_entry *entry;
|
|
|
struct sk_buff *skb;
|
|
|
+ struct ieee80211_rx_status *status;
|
|
|
|
|
|
hdr = (struct ieee80211_hdr *)rx->skb->data;
|
|
|
fc = hdr->frame_control;
|
|
@@ -1368,7 +1370,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
|
|
}
|
|
|
|
|
|
/* Complete frame has been reassembled - process it now */
|
|
|
- rx->flags |= IEEE80211_RX_FRAGMENTED;
|
|
|
+ status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
+ status->rx_flags |= IEEE80211_RX_FRAGMENTED;
|
|
|
|
|
|
out:
|
|
|
if (rx->sta)
|
|
@@ -1385,9 +1388,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
|
|
|
{
|
|
|
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
|
|
__le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
|
|
|
- !(rx->flags & IEEE80211_RX_RA_MATCH)))
|
|
|
+ !(status->rx_flags & IEEE80211_RX_RA_MATCH)))
|
|
|
return RX_CONTINUE;
|
|
|
|
|
|
if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
|
|
@@ -1548,6 +1552,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
|
|
|
struct sk_buff *skb, *xmit_skb;
|
|
|
struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
|
|
|
struct sta_info *dsta;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
skb = rx->skb;
|
|
|
xmit_skb = NULL;
|
|
@@ -1555,7 +1560,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
|
|
|
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
|
|
|
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
|
|
|
!(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
|
|
|
- (rx->flags & IEEE80211_RX_RA_MATCH) &&
|
|
|
+ (status->rx_flags & IEEE80211_RX_RA_MATCH) &&
|
|
|
(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) {
|
|
|
if (is_multicast_ether_addr(ehdr->h_dest)) {
|
|
|
/*
|
|
@@ -1632,6 +1637,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
|
|
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
|
|
__le16 fc = hdr->frame_control;
|
|
|
struct sk_buff_head frame_list;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
if (unlikely(!ieee80211_is_data(fc)))
|
|
|
return RX_CONTINUE;
|
|
@@ -1639,7 +1645,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
|
|
|
if (unlikely(!ieee80211_is_data_present(fc)))
|
|
|
return RX_DROP_MONITOR;
|
|
|
|
|
|
- if (!(rx->flags & IEEE80211_RX_AMSDU))
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_AMSDU))
|
|
|
return RX_CONTINUE;
|
|
|
|
|
|
if (ieee80211_has_a4(hdr->frame_control) &&
|
|
@@ -1690,6 +1696,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
|
|
struct sk_buff *skb = rx->skb, *fwd_skb;
|
|
|
struct ieee80211_local *local = rx->local;
|
|
|
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
|
|
|
|
|
hdr = (struct ieee80211_hdr *) skb->data;
|
|
|
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
|
@@ -1735,7 +1742,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
|
|
|
|
|
|
mesh_hdr->ttl--;
|
|
|
|
|
|
- if (rx->flags & IEEE80211_RX_RA_MATCH) {
|
|
|
+ if (status->rx_flags & IEEE80211_RX_RA_MATCH) {
|
|
|
if (!mesh_hdr->ttl)
|
|
|
IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh,
|
|
|
dropped_frames_ttl);
|
|
@@ -1945,6 +1952,7 @@ static ieee80211_rx_result debug_noinline
|
|
|
ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
|
|
|
{
|
|
|
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
/*
|
|
|
* From here on, look only at management frames.
|
|
@@ -1957,7 +1965,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
|
|
|
if (!ieee80211_is_mgmt(mgmt->frame_control))
|
|
|
return RX_DROP_MONITOR;
|
|
|
|
|
|
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
|
|
|
return RX_DROP_MONITOR;
|
|
|
|
|
|
if (ieee80211_drop_unencrypted_mgmt(rx))
|
|
@@ -1972,6 +1980,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|
|
struct ieee80211_local *local = rx->local;
|
|
|
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
|
|
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
int len = rx->skb->len;
|
|
|
|
|
|
if (!ieee80211_is_action(mgmt->frame_control))
|
|
@@ -1984,7 +1993,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|
|
if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)
|
|
|
return RX_DROP_UNUSABLE;
|
|
|
|
|
|
- if (!(rx->flags & IEEE80211_RX_RA_MATCH))
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
|
|
|
return RX_DROP_UNUSABLE;
|
|
|
|
|
|
switch (mgmt->u.action.category) {
|
|
@@ -2080,7 +2089,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|
|
return RX_CONTINUE;
|
|
|
|
|
|
invalid:
|
|
|
- rx->flags |= IEEE80211_MALFORMED_ACTION_FRM;
|
|
|
+ status->rx_flags |= IEEE80211_RX_MALFORMED_ACTION_FRM;
|
|
|
/* will return in the next handlers */
|
|
|
return RX_CONTINUE;
|
|
|
|
|
@@ -2102,10 +2111,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
|
|
|
static ieee80211_rx_result debug_noinline
|
|
|
ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
|
|
|
{
|
|
|
- struct ieee80211_rx_status *status;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
/* skip known-bad action frames and return them in the next handler */
|
|
|
- if (rx->flags & IEEE80211_MALFORMED_ACTION_FRM)
|
|
|
+ if (status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM)
|
|
|
return RX_CONTINUE;
|
|
|
|
|
|
/*
|
|
@@ -2114,7 +2123,6 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
|
|
|
* so userspace can register for those to know whether ones
|
|
|
* it transmitted were processed or returned.
|
|
|
*/
|
|
|
- status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq,
|
|
|
rx->skb->data, rx->skb->len,
|
|
@@ -2136,6 +2144,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
|
|
|
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
|
|
|
struct sk_buff *nskb;
|
|
|
struct ieee80211_sub_if_data *sdata = rx->sdata;
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
|
|
|
|
if (!ieee80211_is_action(mgmt->frame_control))
|
|
|
return RX_CONTINUE;
|
|
@@ -2150,7 +2159,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
|
|
|
* registration mechanisms, but older ones still use cooked
|
|
|
* monitor interfaces so push all frames there.
|
|
|
*/
|
|
|
- if (!(rx->flags & IEEE80211_MALFORMED_ACTION_FRM) &&
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) &&
|
|
|
(sdata->vif.type == NL80211_IFTYPE_AP ||
|
|
|
sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
|
|
|
return RX_DROP_MONITOR;
|
|
@@ -2284,8 +2293,13 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
|
|
struct net_device *prev_dev = NULL;
|
|
|
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
|
|
|
|
|
- if (status->flag & RX_FLAG_INTERNAL_CMTR)
|
|
|
+ /*
|
|
|
+ * If cooked monitor has been processed already, then
|
|
|
+ * don't do it again. If not, set the flag.
|
|
|
+ */
|
|
|
+ if (rx->flags & IEEE80211_RX_CMNTR)
|
|
|
goto out_free_skb;
|
|
|
+ rx->flags |= IEEE80211_RX_CMNTR;
|
|
|
|
|
|
if (skb_headroom(skb) < sizeof(*rthdr) &&
|
|
|
pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC))
|
|
@@ -2341,12 +2355,8 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
|
|
|
if (prev_dev) {
|
|
|
skb->dev = prev_dev;
|
|
|
netif_receive_skb(skb);
|
|
|
- skb = NULL;
|
|
|
- } else
|
|
|
- goto out_free_skb;
|
|
|
-
|
|
|
- status->flag |= RX_FLAG_INTERNAL_CMTR;
|
|
|
- return;
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
out_free_skb:
|
|
|
dev_kfree_skb(skb);
|
|
@@ -2407,6 +2417,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
|
|
|
* same TID from the same station
|
|
|
*/
|
|
|
rx->skb = skb;
|
|
|
+ rx->flags = 0;
|
|
|
|
|
|
CALL_RXH(ieee80211_rx_h_decrypt)
|
|
|
CALL_RXH(ieee80211_rx_h_check_more_data)
|
|
@@ -2477,7 +2488,12 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
|
|
|
void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
|
|
|
{
|
|
|
struct sk_buff_head frames;
|
|
|
- struct ieee80211_rx_data rx = { };
|
|
|
+ struct ieee80211_rx_data rx = {
|
|
|
+ .sta = sta,
|
|
|
+ .sdata = sta->sdata,
|
|
|
+ .local = sta->local,
|
|
|
+ .queue = tid,
|
|
|
+ };
|
|
|
struct tid_ampdu_rx *tid_agg_rx;
|
|
|
|
|
|
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)
|
|
|
|
|
|
__skb_queue_head_init(&frames);
|
|
|
|
|
|
- /* construct rx struct */
|
|
|
- rx.sta = sta;
|
|
|
- rx.sdata = sta->sdata;
|
|
|
- rx.local = sta->local;
|
|
|
- rx.queue = tid;
|
|
|
- rx.flags |= IEEE80211_RX_RA_MATCH;
|
|
|
-
|
|
|
spin_lock(&tid_agg_rx->reorder_lock);
|
|
|
ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx, &frames);
|
|
|
spin_unlock(&tid_agg_rx->reorder_lock);
|
|
@@ -2519,7 +2528,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
|
|
|
compare_ether_addr(sdata->vif.addr, hdr->addr1) != 0) {
|
|
|
if (!(sdata->dev->flags & IFF_PROMISC))
|
|
|
return 0;
|
|
|
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
}
|
|
|
break;
|
|
|
case NL80211_IFTYPE_ADHOC:
|
|
@@ -2529,15 +2538,15 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
|
|
|
return 1;
|
|
|
}
|
|
|
else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) {
|
|
|
- if (!(rx->flags & IEEE80211_RX_IN_SCAN))
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_IN_SCAN))
|
|
|
return 0;
|
|
|
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
} else if (!multicast &&
|
|
|
compare_ether_addr(sdata->vif.addr,
|
|
|
hdr->addr1) != 0) {
|
|
|
if (!(sdata->dev->flags & IFF_PROMISC))
|
|
|
return 0;
|
|
|
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
} else if (!rx->sta) {
|
|
|
int rate_idx;
|
|
|
if (status->flag & RX_FLAG_HT)
|
|
@@ -2555,7 +2564,7 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
|
|
|
if (!(sdata->dev->flags & IFF_PROMISC))
|
|
|
return 0;
|
|
|
|
|
|
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
}
|
|
|
break;
|
|
|
case NL80211_IFTYPE_AP_VLAN:
|
|
@@ -2566,9 +2575,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx,
|
|
|
return 0;
|
|
|
} else if (!ieee80211_bssid_match(bssid,
|
|
|
sdata->vif.addr)) {
|
|
|
- if (!(rx->flags & IEEE80211_RX_IN_SCAN))
|
|
|
+ if (!(status->rx_flags & IEEE80211_RX_IN_SCAN))
|
|
|
return 0;
|
|
|
- rx->flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
+ status->rx_flags &= ~IEEE80211_RX_RA_MATCH;
|
|
|
}
|
|
|
break;
|
|
|
case NL80211_IFTYPE_WDS:
|
|
@@ -2602,14 +2611,14 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
|
|
int prepares;
|
|
|
|
|
|
rx->skb = skb;
|
|
|
- rx->flags |= IEEE80211_RX_RA_MATCH;
|
|
|
+ status->rx_flags |= IEEE80211_RX_RA_MATCH;
|
|
|
prepares = prepare_for_handlers(rx, hdr);
|
|
|
|
|
|
if (!prepares)
|
|
|
return false;
|
|
|
|
|
|
if (status->flag & RX_FLAG_MMIC_ERROR) {
|
|
|
- if (rx->flags & IEEE80211_RX_RA_MATCH)
|
|
|
+ if (status->rx_flags & IEEE80211_RX_RA_MATCH)
|
|
|
ieee80211_rx_michael_mic_report(hdr, rx);
|
|
|
return false;
|
|
|
}
|
|
@@ -2638,6 +2647,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
|
|
|
static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
|
|
struct ieee80211_local *local = hw_to_local(hw);
|
|
|
struct ieee80211_sub_if_data *sdata;
|
|
|
struct ieee80211_hdr *hdr;
|
|
@@ -2657,7 +2667,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
|
|
|
|
|
|
if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
|
|
|
test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
|
|
|
- rx.flags |= IEEE80211_RX_IN_SCAN;
|
|
|
+ status->rx_flags |= IEEE80211_RX_IN_SCAN;
|
|
|
|
|
|
if (ieee80211_is_mgmt(fc))
|
|
|
err = skb_linearize(skb);
|
|
@@ -2808,6 +2818,8 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ status->rx_flags = 0;
|
|
|
+
|
|
|
/*
|
|
|
* key references and virtual interfaces are protected using RCU
|
|
|
* and this requires that we are in a read-side RCU section during
|