summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2015-05-19 07:36:48 -0400
committerJohannes Berg <johannes.berg@intel.com>2015-05-20 09:14:54 -0400
commitc5a71688e1e56e155fb79b8d699322f4f0793cc8 (patch)
tree3baf7a265ccf7c832fcef9ad604836cbafb57e2b /net/mac80211/mlme.c
parent464daaf04cb633ae1530652fd23cdea0f0d21dd5 (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.c26
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
1101static 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
1101static void 1119static void
1102ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 1120ieee80211_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,