浏览代码

mac80211: clean up key freeing a bit

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>
Johannes Berg 12 年之前
父节点
当前提交
79cf2dfa36
共有 3 个文件被更改,包括 25 次插入22 次删除
  1. 1 3
      net/mac80211/cfg.c
  2. 19 13
      net/mac80211/key.c
  3. 5 6
      net/mac80211/key.h

+ 1 - 3
net/mac80211/cfg.c

@@ -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);

+ 19 - 13
net/mac80211/key.c

@@ -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;

+ 5 - 6
net/mac80211/key.h

@@ -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,