]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
wifi: mac80211: call drv_sta_state() under sdata_lock() in reconfig
authorJohannes Berg <johannes.berg@intel.com>
Fri, 2 Sep 2022 14:12:51 +0000 (16:12 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Sat, 3 Sep 2022 15:04:51 +0000 (17:04 +0200)
Currently, other paths calling drv_sta_state() hold the mutex
and therefore drivers can assume that, and look at links with
that protection. Fix that for the reconfig path as well; to
do it more easily use ieee80211_reconfig_stations() for the
AP/AP_VLAN station reconfig as well.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/util.c

index 8b4c6b7abafa7c8279d947c534b443c7c8a18646..3359ab332d7d0a6a63cf70496168b3ce8e109440 100644 (file)
@@ -2530,7 +2530,6 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                        if (link)
                                ieee80211_assign_chanctx(local, sdata, link);
                }
-               sdata_unlock(sdata);
 
                switch (sdata->vif.type) {
                case NL80211_IFTYPE_AP_VLAN:
@@ -2549,6 +2548,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                                            &sdata->deflink.tx_conf[i]);
                        break;
                }
+               sdata_unlock(sdata);
 
                /* common change flags for all interface types */
                changed = BSS_CHANGED_ERP_CTS_PROT |
@@ -2657,23 +2657,21 @@ int ieee80211_reconfig(struct ieee80211_local *local)
        }
 
        /* APs are now beaconing, add back stations */
-       mutex_lock(&local->sta_mtx);
-       list_for_each_entry(sta, &local->sta_list, list) {
-               enum ieee80211_sta_state state;
-
-               if (!sta->uploaded)
-                       continue;
-
-               if (sta->sdata->vif.type != NL80211_IFTYPE_AP &&
-                   sta->sdata->vif.type != NL80211_IFTYPE_AP_VLAN)
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               if (!ieee80211_sdata_running(sdata))
                        continue;
 
-               for (state = IEEE80211_STA_NOTEXIST;
-                    state < sta->sta_state; state++)
-                       WARN_ON(drv_sta_state(local, sta->sdata, sta, state,
-                                             state + 1));
+               sdata_lock(sdata);
+               switch (sdata->vif.type) {
+               case NL80211_IFTYPE_AP_VLAN:
+               case NL80211_IFTYPE_AP:
+                       ieee80211_reconfig_stations(sdata);
+                       break;
+               default:
+                       break;
+               }
+               sdata_unlock(sdata);
        }
-       mutex_unlock(&local->sta_mtx);
 
        /* add back keys */
        list_for_each_entry(sdata, &local->interfaces, list)