Skip to content

Commit 3831f6d

Browse files
Miriam-Racheljmberg-intel
authored andcommitted
wifi: mac80211: purge TX queues in flush_queues flow
When this flow is invoked with the "drop" parameter as true, we only drop the frames from the hw queues, but not from the sw queues. So when we call wake_queues() after hw queue purging, all the frames from the sw queues will be TX'ed, when what we actually want to do is to purge all queues in order to not TX anything... This can cause, for example, TXing data frames to the peer after the deauth frame was sent. Fix this by purging the sw queues in addition to the hw queues if the drop parameter is true. Signed-off-by: Miri Korenblit <[email protected]> Signed-off-by: Gregory Greenman <[email protected]> Link: https://lore.kernel.org/r/20230928172905.8fc2ee23e56f.I8b3f6def9c28ea96261e2d31df8786986fb5385b@changeid Signed-off-by: Johannes Berg <[email protected]>
1 parent c7d91cc commit 3831f6d

File tree

3 files changed

+32
-10
lines changed

3 files changed

+32
-10
lines changed

net/mac80211/ieee80211_i.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,7 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
23902390
struct txq_info *txq, int tid);
23912391
void ieee80211_txq_purge(struct ieee80211_local *local,
23922392
struct txq_info *txqi);
2393+
void ieee80211_purge_sta_txqs(struct sta_info *sta);
23932394
void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
23942395
struct ieee80211_sub_if_data *sdata);
23952396
void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats,

net/mac80211/sta_info.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@ static int link_sta_info_hash_del(struct ieee80211_local *local,
113113
&link_sta->link_hash_node, link_sta_rht_params);
114114
}
115115

116+
void ieee80211_purge_sta_txqs(struct sta_info *sta)
117+
{
118+
struct ieee80211_local *local = sta->sdata->local;
119+
int i;
120+
121+
for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
122+
struct txq_info *txqi;
123+
124+
if (!sta->sta.txq[i])
125+
continue;
126+
127+
txqi = to_txq_info(sta->sta.txq[i]);
128+
129+
ieee80211_txq_purge(local, txqi);
130+
}
131+
}
132+
116133
static void __cleanup_single_sta(struct sta_info *sta)
117134
{
118135
int ac, i;
@@ -139,16 +156,7 @@ static void __cleanup_single_sta(struct sta_info *sta)
139156
atomic_dec(&ps->num_sta_ps);
140157
}
141158

142-
for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) {
143-
struct txq_info *txqi;
144-
145-
if (!sta->sta.txq[i])
146-
continue;
147-
148-
txqi = to_txq_info(sta->sta.txq[i]);
149-
150-
ieee80211_txq_purge(local, txqi);
151-
}
159+
ieee80211_purge_sta_txqs(sta);
152160

153161
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
154162
local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);

net/mac80211/util.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,19 @@ void __ieee80211_flush_queues(struct ieee80211_local *local,
693693
IEEE80211_QUEUE_STOP_REASON_FLUSH,
694694
false);
695695

696+
if (drop) {
697+
struct sta_info *sta;
698+
699+
/* Purge the queues, so the frames on them won't be
700+
* sent during __ieee80211_wake_queue()
701+
*/
702+
list_for_each_entry(sta, &local->sta_list, list) {
703+
if (sdata != sta->sdata)
704+
continue;
705+
ieee80211_purge_sta_txqs(sta);
706+
}
707+
}
708+
696709
drv_flush(local, sdata, queues, drop);
697710

698711
ieee80211_wake_queues_by_reason(&local->hw, queues,

0 commit comments

Comments
 (0)