aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-04 06:18:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:13:53 -0500
commite7f4a940bb5eecd07cf0039e7d9201badc332ae0 (patch)
tree49ae5164a9f2f247a6c33d24f27033e1db2f5ba5
parentb92ab5d86dafc2b3733c5fdd5def40c8fe7ea7c9 (diff)
mac80211: send unexpected 4addr event
Implement the cfg80211 notification but only send one event per associated station to avoid having tons of events if the station thinks it should be allowed to use 4addr frames but it isn't. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-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 2ed882f8a9f8..5f6751a07405 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 8c8ce05ad26f..c5923ab8a070 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