]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/mac80211/cfg.c
mac80211: split sta_info_add
[mirror_ubuntu-bionic-kernel.git] / net / mac80211 / cfg.c
index e9ba6fcc0e45754a42cc27ec7cd93d2744a5399a..6263cfc148c029efa5b7572535869e060c1975d3 100644 (file)
@@ -571,6 +571,12 @@ static void sta_apply_parameters(struct ieee80211_local *local,
        struct ieee80211_supported_band *sband;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
 
+       /*
+        * FIXME: updating the flags is racy when this function is
+        *        called from ieee80211_change_station(), this will
+        *        be resolved in a future patch.
+        */
+
        if (params->station_flags & STATION_FLAG_CHANGED) {
                sta->flags &= ~WLAN_STA_AUTHORIZED;
                if (params->station_flags & STATION_FLAG_AUTHORIZED)
@@ -585,6 +591,13 @@ static void sta_apply_parameters(struct ieee80211_local *local,
                        sta->flags |= WLAN_STA_WME;
        }
 
+       /*
+        * FIXME: updating the following information is racy when this
+        *        function is called from ieee80211_change_station().
+        *        However, all this information should be static so
+        *        maybe we should just reject attemps to change it.
+        */
+
        if (params->aid) {
                sta->aid = params->aid;
                if (sta->aid > IEEE80211_MAX_AID)
@@ -626,6 +639,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct sta_info *sta;
        struct ieee80211_sub_if_data *sdata;
+       int err;
 
        /* Prevent a race with changing the rate control algorithm */
        if (!netif_running(dev))
@@ -641,16 +655,11 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
                sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (ieee80211_vif_is_mesh(&sdata->vif))
-               sta = mesh_plink_add(mac, DEFAULT_RATES, sdata);
+               sta = mesh_plink_alloc(sdata, mac, DEFAULT_RATES, GFP_KERNEL);
        else
-               sta = sta_info_add(sdata, mac);
-
-       if (IS_ERR(sta))
-               return PTR_ERR(sta);
-
-       if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN ||
-           sdata->vif.type == IEEE80211_IF_TYPE_AP)
-               ieee80211_send_layer2_update(sta);
+               sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
+       if (!sta)
+               return -ENOMEM;
 
        sta->flags = WLAN_STA_AUTH | WLAN_STA_ASSOC;
 
@@ -658,6 +667,21 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
 
        rate_control_rate_init(sta, local);
 
+       rcu_read_lock();
+
+       err = sta_info_insert(sta);
+       if (err) {
+               sta_info_destroy(sta);
+               rcu_read_unlock();
+               return err;
+       }
+
+       if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN ||
+           sdata->vif.type == IEEE80211_IF_TYPE_AP)
+               ieee80211_send_layer2_update(sta);
+
+       rcu_read_unlock();
+
        return 0;
 }