summaryrefslogtreecommitdiff
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bfcf09eb64b..5709307fcb9 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1111,6 +1111,18 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
if (ieee80211_is_nullfunc(hdr->frame_control) ||
ieee80211_is_qos_nullfunc(hdr->frame_control)) {
I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc);
+
+ /*
+ * If we receive a 4-addr nullfunc frame from a STA
+ * that was not moved to a 4-addr STA vlan yet, drop
+ * the frame to the monitor interface, to make sure
+ * that hostapd sees it
+ */
+ if (ieee80211_has_a4(hdr->frame_control) &&
+ (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
+ (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+ !rx->sdata->u.vlan.sta)))
+ return RX_DROP_MONITOR;
/*
* Update counter and free packet here to avoid
* counting this as a dropped packed.
@@ -1665,7 +1677,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
memset(info, 0, sizeof(*info));
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
info->control.vif = &rx->sdata->vif;
- ieee80211_select_queue(local, fwd_skb);
+ skb_set_queue_mapping(skb,
+ ieee80211_select_queue(rx->sdata, fwd_skb));
+ ieee80211_set_qos_hdr(local, skb);
if (is_multicast_ether_addr(fwd_hdr->addr1))
IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
fwded_mcast);
@@ -1932,6 +1946,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
}
break;
default:
+ /* do not process rejected action frames */
+ if (mgmt->u.action.category & 0x80)
+ return RX_DROP_MONITOR;
+
return RX_CONTINUE;
}
@@ -2330,22 +2348,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
continue;
- rx.sta = sta_info_get(sdata, hdr->addr2);
-
- rx.flags |= IEEE80211_RX_RA_MATCH;
- prepares = prepare_for_handlers(sdata, &rx, hdr);
-
- if (!prepares)
- continue;
-
- if (status->flag & RX_FLAG_MMIC_ERROR) {
- rx.sdata = sdata;
- if (rx.flags & IEEE80211_RX_RA_MATCH)
- ieee80211_rx_michael_mic_report(hdr,
- &rx);
- continue;
- }
-
/*
* frame is destined for this interface, but if it's
* not also for the previous one we handle that after
@@ -2357,6 +2359,22 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
continue;
}
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
+
+ rx.flags |= IEEE80211_RX_RA_MATCH;
+ prepares = prepare_for_handlers(prev, &rx, hdr);
+
+ if (!prepares)
+ goto next;
+
+ if (status->flag & RX_FLAG_MMIC_ERROR) {
+ rx.sdata = prev;
+ if (rx.flags & IEEE80211_RX_RA_MATCH)
+ ieee80211_rx_michael_mic_report(hdr,
+ &rx);
+ goto next;
+ }
+
/*
* frame was destined for the previous interface
* so invoke RX handlers for it
@@ -2369,11 +2387,22 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
"multicast frame for %s\n",
wiphy_name(local->hw.wiphy),
prev->name);
- continue;
+ goto next;
}
ieee80211_invoke_rx_handlers(prev, &rx, skb_new, rate);
+next:
prev = sdata;
}
+
+ if (prev) {
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
+
+ rx.flags |= IEEE80211_RX_RA_MATCH;
+ prepares = prepare_for_handlers(prev, &rx, hdr);
+
+ if (!prepares)
+ prev = NULL;
+ }
}
if (prev)
ieee80211_invoke_rx_handlers(prev, &rx, skb, rate);