mac80211: clean up key freeing a bit
authorJohannes Berg <johannes.berg@intel.com>
Wed, 6 Mar 2013 21:53:52 +0000 (22:53 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 11 Mar 2013 13:16:41 +0000 (15:16 +0200)
When a key is allocated but not really added, there's no
need to go through the entire teardown process. Also, if
adding a key fails, ieee80211_key_link() can take care of
freeing it instead of the (only) caller.

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

index 61fc9116380daa3f101cf82d8fd6d156d34f1044..c2d4bf24a8c25bd6b06e19584dbc1d86dd0a21e3 100644 (file)
@@ -175,7 +175,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
                 *       add it to the device after the station.
                 */
                if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
-                       ieee80211_key_free(sdata->local, key);
+                       ieee80211_key_free_unused(key);
                        err = -ENOENT;
                        goto out_unlock;
                }
@@ -214,8 +214,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
        }
 
        err = ieee80211_key_link(key, sdata, sta);
-       if (err)
-               ieee80211_key_free(sdata->local, key);
 
  out_unlock:
        mutex_unlock(&sdata->local->sta_mtx);
index 99e9f6ae6a54e835dc79403ef69441dcd87411cb..d86be6466724a80d008de0eb90d123142a54c01e 100644 (file)
@@ -397,6 +397,15 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
        return key;
 }
 
+static void ieee80211_key_free_common(struct ieee80211_key *key)
+{
+       if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
+               ieee80211_aes_key_free(key->u.ccmp.tfm);
+       if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
+               ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
+       kfree(key);
+}
+
 static void __ieee80211_key_destroy(struct ieee80211_key *key,
                                    bool delay_tailroom)
 {
@@ -412,10 +421,6 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
        if (key->local)
                ieee80211_key_disable_hw_accel(key);
 
-       if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
-               ieee80211_aes_key_free(key->u.ccmp.tfm);
-       if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
-               ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
        if (key->local) {
                struct ieee80211_sub_if_data *sdata = key->sdata;
 
@@ -431,7 +436,13 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
                }
        }
 
-       kfree(key);
+       ieee80211_key_free_common(key);
+}
+
+void ieee80211_key_free_unused(struct ieee80211_key *key)
+{
+       WARN_ON(key->sdata || key->local);
+       ieee80211_key_free_common(key);
 }
 
 int ieee80211_key_link(struct ieee80211_key *key,
@@ -469,6 +480,9 @@ int ieee80211_key_link(struct ieee80211_key *key,
 
        ret = ieee80211_key_enable_hw_accel(key);
 
+       if (ret)
+               __ieee80211_key_free(key, true);
+
        mutex_unlock(&sdata->local->key_mtx);
 
        return ret;
@@ -489,14 +503,6 @@ void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
        __ieee80211_key_destroy(key, delay_tailroom);
 }
 
-void ieee80211_key_free(struct ieee80211_local *local,
-                       struct ieee80211_key *key)
-{
-       mutex_lock(&local->key_mtx);
-       __ieee80211_key_free(key, true);
-       mutex_unlock(&local->key_mtx);
-}
-
 void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_key *key;
index 2a682d81cee99261f94b45de77a2e61a1c907bbd..8ef56cdfe3d7f11de943fa7e639566088393705a 100644 (file)
@@ -129,14 +129,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
                                          size_t seq_len, const u8 *seq);
 /*
  * Insert a key into data structures (sdata, sta if necessary)
- * to make it used, free old key.
+ * to make it used, free old key. On failure, also free the new key.
  */
-int __must_check ieee80211_key_link(struct ieee80211_key *key,
-                                   struct ieee80211_sub_if_data *sdata,
-                                   struct sta_info *sta);
+int ieee80211_key_link(struct ieee80211_key *key,
+                      struct ieee80211_sub_if_data *sdata,
+                      struct sta_info *sta);
 void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
-void ieee80211_key_free(struct ieee80211_local *local,
-                       struct ieee80211_key *key);
+void ieee80211_key_free_unused(struct ieee80211_key *key);
 void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
                               bool uni, bool multi);
 void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,