diff options
author | Arik Nemtsov <arik@wizery.com> | 2015-05-19 07:36:48 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2015-05-20 09:14:54 -0400 |
commit | c5a71688e1e56e155fb79b8d699322f4f0793cc8 (patch) | |
tree | 3baf7a265ccf7c832fcef9ad604836cbafb57e2b /net/mac80211/mlme.c | |
parent | 464daaf04cb633ae1530652fd23cdea0f0d21dd5 (diff) |
mac80211: disconnect TDLS stations on STA CSA
When a station does a channel switch, it's not well defined what its TDLS
peers would do. Avoid a situation when the local side marks a potentially
disconnected peer as a TDLS peer.
Keeping peers connected through CSA is doubly problematic with the upcoming
TDLS WIDER-BW feature which allows peers to widen the BSS channel. The
new channel transitioned-to might not be compatible and would require
a re-negotiation anyway.
Make sure to disallow new TDLS link during CSA.
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 3294666f599c..387fe70ab126 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1098,6 +1098,24 @@ static void ieee80211_chswitch_timer(unsigned long data) | |||
1098 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work); | 1098 | ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work); |
1099 | } | 1099 | } |
1100 | 1100 | ||
1101 | static void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata) | ||
1102 | { | ||
1103 | struct sta_info *sta; | ||
1104 | u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; | ||
1105 | |||
1106 | rcu_read_lock(); | ||
1107 | list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { | ||
1108 | if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || | ||
1109 | !test_sta_flag(sta, WLAN_STA_AUTHORIZED)) | ||
1110 | continue; | ||
1111 | |||
1112 | ieee80211_tdls_oper_request(&sdata->vif, sta->sta.addr, | ||
1113 | NL80211_TDLS_TEARDOWN, reason, | ||
1114 | GFP_ATOMIC); | ||
1115 | } | ||
1116 | rcu_read_unlock(); | ||
1117 | } | ||
1118 | |||
1101 | static void | 1119 | static void |
1102 | ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 1120 | ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
1103 | u64 timestamp, u32 device_timestamp, | 1121 | u64 timestamp, u32 device_timestamp, |
@@ -1161,6 +1179,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1161 | return; | 1179 | return; |
1162 | } | 1180 | } |
1163 | 1181 | ||
1182 | /* | ||
1183 | * Drop all TDLS peers - either we disconnect or move to a different | ||
1184 | * channel from this point on. There's no telling what our peer will do. | ||
1185 | * The TDLS WIDER_BW scenario is also problematic, as peers might now | ||
1186 | * have an incompatible wider chandef. | ||
1187 | */ | ||
1188 | ieee80211_teardown_tdls_peers(sdata); | ||
1189 | |||
1164 | mutex_lock(&local->mtx); | 1190 | mutex_lock(&local->mtx); |
1165 | mutex_lock(&local->chanctx_mtx); | 1191 | mutex_lock(&local->chanctx_mtx); |
1166 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | 1192 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, |