aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-03-06 16:53:52 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-03-11 09:16:41 -0400
commit79cf2dfa362f3e6368ad8ecb10aa82b39678fedc (patch)
treea31ef2bc191d189378fc3520df7e8d303b65c0d1
parent3d5839b6aa6bbf26c04e885956109d1995d01fe2 (diff)
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>
-rw-r--r--net/mac80211/cfg.c4
-rw-r--r--net/mac80211/key.c32
-rw-r--r--net/mac80211/key.h11
3 files changed, 25 insertions, 22 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 61fc9116380d..c2d4bf24a8c2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -175,7 +175,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
175 * add it to the device after the station. 175 * add it to the device after the station.
176 */ 176 */
177 if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) { 177 if (!sta || !test_sta_flag(sta, WLAN_STA_ASSOC)) {
178 ieee80211_key_free(sdata->local, key); 178 ieee80211_key_free_unused(key);
179 err = -ENOENT; 179 err = -ENOENT;
180 goto out_unlock; 180 goto out_unlock;
181 } 181 }
@@ -214,8 +214,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
214 } 214 }
215 215
216 err = ieee80211_key_link(key, sdata, sta); 216 err = ieee80211_key_link(key, sdata, sta);
217 if (err)
218 ieee80211_key_free(sdata->local, key);
219 217
220 out_unlock: 218 out_unlock:
221 mutex_unlock(&sdata->local->sta_mtx); 219 mutex_unlock(&sdata->local->sta_mtx);
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 99e9f6ae6a54..d86be6466724 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -397,6 +397,15 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
397 return key; 397 return key;
398} 398}
399 399
400static void ieee80211_key_free_common(struct ieee80211_key *key)
401{
402 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
403 ieee80211_aes_key_free(key->u.ccmp.tfm);
404 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
405 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
406 kfree(key);
407}
408
400static void __ieee80211_key_destroy(struct ieee80211_key *key, 409static void __ieee80211_key_destroy(struct ieee80211_key *key,
401 bool delay_tailroom) 410 bool delay_tailroom)
402{ 411{
@@ -412,10 +421,6 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
412 if (key->local) 421 if (key->local)
413 ieee80211_key_disable_hw_accel(key); 422 ieee80211_key_disable_hw_accel(key);
414 423
415 if (key->conf.cipher == WLAN_CIPHER_SUITE_CCMP)
416 ieee80211_aes_key_free(key->u.ccmp.tfm);
417 if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC)
418 ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm);
419 if (key->local) { 424 if (key->local) {
420 struct ieee80211_sub_if_data *sdata = key->sdata; 425 struct ieee80211_sub_if_data *sdata = key->sdata;
421 426
@@ -431,7 +436,13 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key,
431 } 436 }
432 } 437 }
433 438
434 kfree(key); 439 ieee80211_key_free_common(key);
440}
441
442void ieee80211_key_free_unused(struct ieee80211_key *key)
443{
444 WARN_ON(key->sdata || key->local);
445 ieee80211_key_free_common(key);
435} 446}
436 447
437int ieee80211_key_link(struct ieee80211_key *key, 448int ieee80211_key_link(struct ieee80211_key *key,
@@ -469,6 +480,9 @@ int ieee80211_key_link(struct ieee80211_key *key,
469 480
470 ret = ieee80211_key_enable_hw_accel(key); 481 ret = ieee80211_key_enable_hw_accel(key);
471 482
483 if (ret)
484 __ieee80211_key_free(key, true);
485
472 mutex_unlock(&sdata->local->key_mtx); 486 mutex_unlock(&sdata->local->key_mtx);
473 487
474 return ret; 488 return ret;
@@ -489,14 +503,6 @@ void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom)
489 __ieee80211_key_destroy(key, delay_tailroom); 503 __ieee80211_key_destroy(key, delay_tailroom);
490} 504}
491 505
492void ieee80211_key_free(struct ieee80211_local *local,
493 struct ieee80211_key *key)
494{
495 mutex_lock(&local->key_mtx);
496 __ieee80211_key_free(key, true);
497 mutex_unlock(&local->key_mtx);
498}
499
500void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) 506void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata)
501{ 507{
502 struct ieee80211_key *key; 508 struct ieee80211_key *key;
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index 2a682d81cee9..8ef56cdfe3d7 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -129,14 +129,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
129 size_t seq_len, const u8 *seq); 129 size_t seq_len, const u8 *seq);
130/* 130/*
131 * Insert a key into data structures (sdata, sta if necessary) 131 * Insert a key into data structures (sdata, sta if necessary)
132 * to make it used, free old key. 132 * to make it used, free old key. On failure, also free the new key.
133 */ 133 */
134int __must_check ieee80211_key_link(struct ieee80211_key *key, 134int ieee80211_key_link(struct ieee80211_key *key,
135 struct ieee80211_sub_if_data *sdata, 135 struct ieee80211_sub_if_data *sdata,
136 struct sta_info *sta); 136 struct sta_info *sta);
137void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom); 137void __ieee80211_key_free(struct ieee80211_key *key, bool delay_tailroom);
138void ieee80211_key_free(struct ieee80211_local *local, 138void ieee80211_key_free_unused(struct ieee80211_key *key);
139 struct ieee80211_key *key);
140void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx, 139void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
141 bool uni, bool multi); 140 bool uni, bool multi);
142void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 141void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,