diff options
author | Sara Sharon <sara.sharon@intel.com> | 2019-02-06 06:17:10 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2019-02-22 07:43:53 -0500 |
commit | b9cc81d827ed13502ca9c8523361be26ca1d7220 (patch) | |
tree | 557b5204ff9b7cfea170afa9379fbdb1ecb4230b /net/mac80211/mlme.c | |
parent | ee145775c1eb84bb76e71639425ec44c654fb868 (diff) |
mac80211: abort CSA if beacon does not include CSA IEs
In case we receive a beacon without CSA IE while we are in
the middle of channel switch - abort the operation.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@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 | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 1b4938d100d5..28a275ec6700 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1259,6 +1259,32 @@ static void ieee80211_chswitch_timer(struct timer_list *t) | |||
1259 | } | 1259 | } |
1260 | 1260 | ||
1261 | static void | 1261 | static void |
1262 | ieee80211_sta_abort_chanswitch(struct ieee80211_sub_if_data *sdata) | ||
1263 | { | ||
1264 | struct ieee80211_local *local = sdata->local; | ||
1265 | |||
1266 | if (!local->ops->abort_channel_switch) | ||
1267 | return; | ||
1268 | |||
1269 | mutex_lock(&local->mtx); | ||
1270 | |||
1271 | mutex_lock(&local->chanctx_mtx); | ||
1272 | ieee80211_vif_unreserve_chanctx(sdata); | ||
1273 | mutex_unlock(&local->chanctx_mtx); | ||
1274 | |||
1275 | if (sdata->csa_block_tx) | ||
1276 | ieee80211_wake_vif_queues(local, sdata, | ||
1277 | IEEE80211_QUEUE_STOP_REASON_CSA); | ||
1278 | |||
1279 | sdata->csa_block_tx = false; | ||
1280 | sdata->vif.csa_active = false; | ||
1281 | |||
1282 | mutex_unlock(&local->mtx); | ||
1283 | |||
1284 | drv_abort_channel_switch(sdata); | ||
1285 | } | ||
1286 | |||
1287 | static void | ||
1262 | ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 1288 | ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
1263 | u64 timestamp, u32 device_timestamp, | 1289 | u64 timestamp, u32 device_timestamp, |
1264 | struct ieee802_11_elems *elems, | 1290 | struct ieee802_11_elems *elems, |
@@ -1282,19 +1308,24 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1282 | if (local->scanning) | 1308 | if (local->scanning) |
1283 | return; | 1309 | return; |
1284 | 1310 | ||
1285 | /* disregard subsequent announcements if we are already processing */ | ||
1286 | if (sdata->vif.csa_active) | ||
1287 | return; | ||
1288 | |||
1289 | current_band = cbss->channel->band; | 1311 | current_band = cbss->channel->band; |
1290 | res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, | 1312 | res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band, |
1291 | ifmgd->flags, | 1313 | ifmgd->flags, |
1292 | ifmgd->associated->bssid, &csa_ie); | 1314 | ifmgd->associated->bssid, &csa_ie); |
1293 | if (res < 0) | 1315 | if (res < 0) { |
1294 | ieee80211_queue_work(&local->hw, | 1316 | ieee80211_queue_work(&local->hw, |
1295 | &ifmgd->csa_connection_drop_work); | 1317 | &ifmgd->csa_connection_drop_work); |
1296 | if (res) | ||
1297 | return; | 1318 | return; |
1319 | } | ||
1320 | |||
1321 | if (res && beacon && sdata->vif.csa_active && | ||
1322 | !ifmgd->csa_waiting_bcn) { | ||
1323 | ieee80211_sta_abort_chanswitch(sdata); | ||
1324 | return; | ||
1325 | } else if (sdata->vif.csa_active || res) { | ||
1326 | /* disregard subsequent announcements if already processing */ | ||
1327 | return; | ||
1328 | } | ||
1298 | 1329 | ||
1299 | if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, | 1330 | if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef, |
1300 | IEEE80211_CHAN_DISABLED)) { | 1331 | IEEE80211_CHAN_DISABLED)) { |