43724aee1aeb847ba1a2ed3d10f5c87c5556db5f
[openwrt/staging/linusw.git] /
1 From ee0db868ee4d88493dfdc82f59e3b4e449ddddd5 Mon Sep 17 00:00:00 2001
2 From: Oldřich Jedlička <oldium.pro@gmail.com>
3 Date: Sat, 4 Nov 2023 15:13:33 +0100
4 Subject: wifi: mac80211: do not pass AP_VLAN vif pointer to drivers during
5 flush
6 MIME-Version: 1.0
7 Content-Type: text/plain; charset=UTF-8
8 Content-Transfer-Encoding: 8bit
9
10 [ Upstream commit 3e3a2b645c043f7e3e488d5011478cefb69bbe8b ]
11
12 This fixes WARN_ONs when using AP_VLANs after station removal. The flush
13 call passed AP_VLAN vif to driver, but because these vifs are virtual and
14 not registered with drivers, we need to translate to the correct AP vif
15 first.
16
17 Closes: https://github.com/openwrt/openwrt/issues/12420
18 Fixes: 0b75a1b1e42e ("wifi: mac80211: flush queues on STA removal")
19 Fixes: d00800a289c9 ("wifi: mac80211: add flush_sta method")
20 Tested-by: Konstantin Demin <rockdrilla@gmail.com>
21 Tested-by: Koen Vandeputte <koen.vandeputte@citymesh.com>
22 Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com>
23 Link: https://lore.kernel.org/r/20231104141333.3710-1-oldium.pro@gmail.com
24 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
25 Signed-off-by: Sasha Levin <sashal@kernel.org>
26 ---
27 net/mac80211/driver-ops.h | 9 +++++++--
28 1 file changed, 7 insertions(+), 2 deletions(-)
29
30 --- a/net/mac80211/driver-ops.h
31 +++ b/net/mac80211/driver-ops.h
32 @@ -23,7 +23,7 @@
33 static inline struct ieee80211_sub_if_data *
34 get_bss_sdata(struct ieee80211_sub_if_data *sdata)
35 {
36 - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
37 + if (sdata && sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
38 sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
39 u.ap);
40
41 @@ -638,10 +638,13 @@ static inline void drv_flush(struct ieee
42 struct ieee80211_sub_if_data *sdata,
43 u32 queues, bool drop)
44 {
45 - struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
46 + struct ieee80211_vif *vif;
47
48 might_sleep();
49
50 + sdata = get_bss_sdata(sdata);
51 + vif = sdata ? &sdata->vif : NULL;
52 +
53 if (sdata && !check_sdata_in_driver(sdata))
54 return;
55
56 @@ -657,6 +660,8 @@ static inline void drv_flush_sta(struct
57 {
58 might_sleep();
59
60 + sdata = get_bss_sdata(sdata);
61 +
62 if (sdata && !check_sdata_in_driver(sdata))
63 return;
64