aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/rx.c24
-rw-r--r--net/mac80211/sta_info.h8
2 files changed, 25 insertions, 7 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 2ed882f8a9f..5f6751a0740 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1342,15 +1342,20 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1342 1342
1343 /* 1343 /*
1344 * If we receive a 4-addr nullfunc frame from a STA 1344 * If we receive a 4-addr nullfunc frame from a STA
1345 * that was not moved to a 4-addr STA vlan yet, drop 1345 * that was not moved to a 4-addr STA vlan yet send
1346 * the frame to the monitor interface, to make sure 1346 * the event to userspace and for older hostapd drop
1347 * that hostapd sees it 1347 * the frame to the monitor interface.
1348 */ 1348 */
1349 if (ieee80211_has_a4(hdr->frame_control) && 1349 if (ieee80211_has_a4(hdr->frame_control) &&
1350 (rx->sdata->vif.type == NL80211_IFTYPE_AP || 1350 (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
1351 (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN && 1351 (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1352 !rx->sdata->u.vlan.sta))) 1352 !rx->sdata->u.vlan.sta))) {
1353 if (!test_and_set_sta_flag(sta, WLAN_STA_4ADDR_EVENT))
1354 cfg80211_rx_unexpected_4addr_frame(
1355 rx->sdata->dev, sta->sta.addr,
1356 GFP_ATOMIC);
1353 return RX_DROP_MONITOR; 1357 return RX_DROP_MONITOR;
1358 }
1354 /* 1359 /*
1355 * Update counter and free packet here to avoid 1360 * Update counter and free packet here to avoid
1356 * counting this as a dropped packed. 1361 * counting this as a dropped packed.
@@ -2028,12 +2033,17 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
2028 return RX_DROP_MONITOR; 2033 return RX_DROP_MONITOR;
2029 2034
2030 /* 2035 /*
2031 * Allow the cooked monitor interface of an AP to see 4-addr frames so 2036 * Send unexpected-4addr-frame event to hostapd. For older versions,
2032 * that a 4-addr station can be detected and moved into a separate VLAN 2037 * also drop the frame to cooked monitor interfaces.
2033 */ 2038 */
2034 if (ieee80211_has_a4(hdr->frame_control) && 2039 if (ieee80211_has_a4(hdr->frame_control) &&
2035 sdata->vif.type == NL80211_IFTYPE_AP) 2040 sdata->vif.type == NL80211_IFTYPE_AP) {
2041 if (rx->sta &&
2042 !test_and_set_sta_flag(rx->sta, WLAN_STA_4ADDR_EVENT))
2043 cfg80211_rx_unexpected_4addr_frame(
2044 rx->sdata->dev, rx->sta->sta.addr, GFP_ATOMIC);
2036 return RX_DROP_MONITOR; 2045 return RX_DROP_MONITOR;
2046 }
2037 2047
2038 err = __ieee80211_data_to_8023(rx, &port_control); 2048 err = __ieee80211_data_to_8023(rx, &port_control);
2039 if (unlikely(err)) 2049 if (unlikely(err))
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 8c8ce05ad26..c5923ab8a07 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -52,6 +52,7 @@
52 * unblocks the station. 52 * unblocks the station.
53 * @WLAN_STA_SP: Station is in a service period, so don't try to 53 * @WLAN_STA_SP: Station is in a service period, so don't try to
54 * reply to other uAPSD trigger frames or PS-Poll. 54 * reply to other uAPSD trigger frames or PS-Poll.
55 * @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
55 */ 56 */
56enum ieee80211_sta_info_flags { 57enum ieee80211_sta_info_flags {
57 WLAN_STA_AUTH, 58 WLAN_STA_AUTH,
@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags {
71 WLAN_STA_TDLS_PEER_AUTH, 72 WLAN_STA_TDLS_PEER_AUTH,
72 WLAN_STA_UAPSD, 73 WLAN_STA_UAPSD,
73 WLAN_STA_SP, 74 WLAN_STA_SP,
75 WLAN_STA_4ADDR_EVENT,
74}; 76};
75 77
76#define STA_TID_NUM 16 78#define STA_TID_NUM 16
@@ -390,6 +392,12 @@ static inline int test_and_clear_sta_flag(struct sta_info *sta,
390 return test_and_clear_bit(flag, &sta->_flags); 392 return test_and_clear_bit(flag, &sta->_flags);
391} 393}
392 394
395static inline int test_and_set_sta_flag(struct sta_info *sta,
396 enum ieee80211_sta_info_flags flag)
397{
398 return test_and_set_bit(flag, &sta->_flags);
399}
400
393void ieee80211_assign_tid_tx(struct sta_info *sta, int tid, 401void ieee80211_assign_tid_tx(struct sta_info *sta, int tid,
394 struct tid_ampdu_tx *tid_tx); 402 struct tid_ampdu_tx *tid_tx);
395 403