summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-01-20 13:55:19 +0100
committerJohn W. Linville <linville@tuxdriver.com>2012-02-06 14:48:24 -0500
commit89c91caeccf45bbeb86104445125fe1eaec12079 (patch)
tree55c39a8b8e4e4515995e3c8e86369433a7b291c1
parent077f49392819608084c6d8d20e3dcca230afe07d (diff)
downloadlinux-3.10-89c91caeccf45bbeb86104445125fe1eaec12079.tar.gz
linux-3.10-89c91caeccf45bbeb86104445125fe1eaec12079.tar.bz2
linux-3.10-89c91caeccf45bbeb86104445125fe1eaec12079.zip
mac80211: dont program keys for stations not uploaded
If a station couldn't be uploaded to the driver but is still kept (only in IBSS mode) we still shouldn't try to program the keys for it into hardware; fix this bug by skipping the key upload in this case. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/key.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 94f02b577d4..e8616b3ff63 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -54,14 +54,6 @@ static void assert_key_lock(struct ieee80211_local *local)
lockdep_assert_held(&local->key_mtx);
}
-static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
-{
- if (key->sta)
- return &key->sta->sta;
-
- return NULL;
-}
-
static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
{
/*
@@ -95,7 +87,7 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
{
struct ieee80211_sub_if_data *sdata;
- struct ieee80211_sta *sta;
+ struct sta_info *sta;
int ret;
might_sleep();
@@ -105,7 +97,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
assert_key_lock(key->local);
- sta = get_sta_for_key(key);
+ sta = key->sta;
/*
* If this is a per-STA GTK, check if it
@@ -115,6 +107,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
!(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
goto out_unsupported;
+ if (sta && !sta->uploaded)
+ goto out_unsupported;
+
sdata = key->sdata;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
/*
@@ -125,7 +120,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
goto out_unsupported;
}
- ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
+ ret = drv_set_key(key->local, SET_KEY, sdata,
+ sta ? &sta->sta : NULL, &key->conf);
if (!ret) {
key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
@@ -144,7 +140,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
if (ret != -ENOSPC && ret != -EOPNOTSUPP)
wiphy_err(key->local->hw.wiphy,
"failed to set key (%d, %pM) to hardware (%d)\n",
- key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+ key->conf.keyidx,
+ sta ? sta->sta.addr : bcast_addr, ret);
out_unsupported:
switch (key->conf.cipher) {
@@ -163,7 +160,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
{
struct ieee80211_sub_if_data *sdata;
- struct ieee80211_sta *sta;
+ struct sta_info *sta;
int ret;
might_sleep();
@@ -176,7 +173,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
return;
- sta = get_sta_for_key(key);
+ sta = key->sta;
sdata = key->sdata;
if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
@@ -185,12 +182,13 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
increment_tailroom_need_count(sdata);
ret = drv_set_key(key->local, DISABLE_KEY, sdata,
- sta, &key->conf);
+ sta ? &sta->sta : NULL, &key->conf);
if (ret)
wiphy_err(key->local->hw.wiphy,
"failed to remove key (%d, %pM) from hardware (%d)\n",
- key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
+ key->conf.keyidx,
+ sta ? sta->sta.addr : bcast_addr, ret);
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
}