diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-12-14 06:20:31 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-12-15 14:46:34 -0500 |
commit | 29623892e185b65a503c925236ff73894a842d38 (patch) | |
tree | a159e711035d4003ea64b52d3601a0be6f77e61b /net | |
parent | d9a7ddb05e5419ca5e4b54f57074dc33c7ea991c (diff) |
mac80211: count authorized stations per BSS
Currently, each AP interface will send multicast
traffic if any interface has a station entry even
if that station entry is allocated only. With the
new station state management we can easily fix it
by adding a counter that counts each authorized
station only and send multicast traffic only when
the correct interface has at least one authorized
station.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 14 | ||||
-rw-r--r-- | net/mac80211/tx.c | 19 |
4 files changed, 20 insertions, 16 deletions
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 8df28910b8ee..176c08ffb13c 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -321,6 +321,7 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( | |||
321 | __IEEE80211_IF_FILE_W(tkip_mic_test); | 321 | __IEEE80211_IF_FILE_W(tkip_mic_test); |
322 | 322 | ||
323 | /* AP attributes */ | 323 | /* AP attributes */ |
324 | IEEE80211_IF_FILE(num_sta_authorized, u.ap.num_sta_authorized, ATOMIC); | ||
324 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); | 325 | IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); |
325 | IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); | 326 | IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); |
326 | 327 | ||
@@ -458,6 +459,7 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata) | |||
458 | DEBUGFS_ADD(rc_rateidx_mask_2ghz); | 459 | DEBUGFS_ADD(rc_rateidx_mask_2ghz); |
459 | DEBUGFS_ADD(rc_rateidx_mask_5ghz); | 460 | DEBUGFS_ADD(rc_rateidx_mask_5ghz); |
460 | 461 | ||
462 | DEBUGFS_ADD(num_sta_authorized); | ||
461 | DEBUGFS_ADD(num_sta_ps); | 463 | DEBUGFS_ADD(num_sta_ps); |
462 | DEBUGFS_ADD(dtim_count); | 464 | DEBUGFS_ADD(dtim_count); |
463 | DEBUGFS_ADD(num_buffered_multicast); | 465 | DEBUGFS_ADD(num_buffered_multicast); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 96fe75410bbe..9516c3088fba 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -243,6 +243,7 @@ struct ieee80211_if_ap { | |||
243 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; | 243 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; |
244 | struct sk_buff_head ps_bc_buf; | 244 | struct sk_buff_head ps_bc_buf; |
245 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 245 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
246 | atomic_t num_sta_authorized; /* number of authorized stations */ | ||
246 | int dtim_count; | 247 | int dtim_count; |
247 | bool dtim_bc_mc; | 248 | bool dtim_bc_mc; |
248 | }; | 249 | }; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index b22775cdcdf5..141315ce17d8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1567,17 +1567,21 @@ int sta_info_move_state_checked(struct sta_info *sta, | |||
1567 | return -EINVAL; | 1567 | return -EINVAL; |
1568 | break; | 1568 | break; |
1569 | case IEEE80211_STA_ASSOC: | 1569 | case IEEE80211_STA_ASSOC: |
1570 | if (sta->sta_state == IEEE80211_STA_AUTH) | 1570 | if (sta->sta_state == IEEE80211_STA_AUTH) { |
1571 | set_bit(WLAN_STA_ASSOC, &sta->_flags); | 1571 | set_bit(WLAN_STA_ASSOC, &sta->_flags); |
1572 | else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) | 1572 | } else if (sta->sta_state == IEEE80211_STA_AUTHORIZED) { |
1573 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP) | ||
1574 | atomic_dec(&sta->sdata->u.ap.num_sta_authorized); | ||
1573 | clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags); | 1575 | clear_bit(WLAN_STA_AUTHORIZED, &sta->_flags); |
1574 | else | 1576 | } else |
1575 | return -EINVAL; | 1577 | return -EINVAL; |
1576 | break; | 1578 | break; |
1577 | case IEEE80211_STA_AUTHORIZED: | 1579 | case IEEE80211_STA_AUTHORIZED: |
1578 | if (sta->sta_state == IEEE80211_STA_ASSOC) | 1580 | if (sta->sta_state == IEEE80211_STA_ASSOC) { |
1581 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP) | ||
1582 | atomic_inc(&sta->sdata->u.ap.num_sta_authorized); | ||
1579 | set_bit(WLAN_STA_AUTHORIZED, &sta->_flags); | 1583 | set_bit(WLAN_STA_AUTHORIZED, &sta->_flags); |
1580 | else | 1584 | } else |
1581 | return -EINVAL; | 1585 | return -EINVAL; |
1582 | break; | 1586 | break; |
1583 | default: | 1587 | default: |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 50c4be9a6404..6bbd6cccb4a0 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -304,17 +304,14 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
304 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); | 304 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); |
305 | return TX_DROP; | 305 | return TX_DROP; |
306 | } | 306 | } |
307 | } else { | 307 | } else if (unlikely(tx->sdata->vif.type == NL80211_IFTYPE_AP && |
308 | if (unlikely(ieee80211_is_data(hdr->frame_control) && | 308 | ieee80211_is_data(hdr->frame_control) && |
309 | tx->local->num_sta == 0 && | 309 | !atomic_read(&tx->sdata->u.ap.num_sta_authorized))) { |
310 | tx->sdata->vif.type != NL80211_IFTYPE_ADHOC)) { | 310 | /* |
311 | /* | 311 | * No associated STAs - no need to send multicast |
312 | * No associated STAs - no need to send multicast | 312 | * frames. |
313 | * frames. | 313 | */ |
314 | */ | 314 | return TX_DROP; |
315 | return TX_DROP; | ||
316 | } | ||
317 | return TX_CONTINUE; | ||
318 | } | 315 | } |
319 | 316 | ||
320 | return TX_CONTINUE; | 317 | return TX_CONTINUE; |