aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-03-06 22:53:52 +0100
committerJohannes Berg <johannes.berg@intel.com>2013-03-11 15:16:41 +0200
commit79cf2dfa362f3e6368ad8ecb10aa82b39678fedc (patch)
treea31ef2bc191d189378fc3520df7e8d303b65c0d1
parentmac80211: Call drv_set_tim only if there is a change (diff)
downloadlinux-dev-79cf2dfa362f3e6368ad8ecb10aa82b39678fedc.tar.xz
linux-dev-79cf2dfa362f3e6368ad8ecb10aa82b39678fedc.zip
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,
* 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);
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,
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;
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,
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,