aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-01-20 07:55:19 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-02-06 14:48:24 -0500
commit89c91caeccf45bbeb86104445125fe1eaec12079 (patch)
tree55c39a8b8e4e4515995e3c8e86369433a7b291c1 /net/mac80211
parent077f49392819608084c6d8d20e3dcca230afe07d (diff)
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>
Diffstat (limited to 'net/mac80211')
-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)
54 lockdep_assert_held(&local->key_mtx); 54 lockdep_assert_held(&local->key_mtx);
55} 55}
56 56
57static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
58{
59 if (key->sta)
60 return &key->sta->sta;
61
62 return NULL;
63}
64
65static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata) 57static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
66{ 58{
67 /* 59 /*
@@ -95,7 +87,7 @@ static void increment_tailroom_need_count(struct ieee80211_sub_if_data *sdata)
95static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) 87static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
96{ 88{
97 struct ieee80211_sub_if_data *sdata; 89 struct ieee80211_sub_if_data *sdata;
98 struct ieee80211_sta *sta; 90 struct sta_info *sta;
99 int ret; 91 int ret;
100 92
101 might_sleep(); 93 might_sleep();
@@ -105,7 +97,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
105 97
106 assert_key_lock(key->local); 98 assert_key_lock(key->local);
107 99
108 sta = get_sta_for_key(key); 100 sta = key->sta;
109 101
110 /* 102 /*
111 * If this is a per-STA GTK, check if it 103 * 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)
115 !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK)) 107 !(key->local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK))
116 goto out_unsupported; 108 goto out_unsupported;
117 109
110 if (sta && !sta->uploaded)
111 goto out_unsupported;
112
118 sdata = key->sdata; 113 sdata = key->sdata;
119 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { 114 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
120 /* 115 /*
@@ -125,7 +120,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
125 goto out_unsupported; 120 goto out_unsupported;
126 } 121 }
127 122
128 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); 123 ret = drv_set_key(key->local, SET_KEY, sdata,
124 sta ? &sta->sta : NULL, &key->conf);
129 125
130 if (!ret) { 126 if (!ret) {
131 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 127 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
@@ -144,7 +140,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
144 if (ret != -ENOSPC && ret != -EOPNOTSUPP) 140 if (ret != -ENOSPC && ret != -EOPNOTSUPP)
145 wiphy_err(key->local->hw.wiphy, 141 wiphy_err(key->local->hw.wiphy,
146 "failed to set key (%d, %pM) to hardware (%d)\n", 142 "failed to set key (%d, %pM) to hardware (%d)\n",
147 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); 143 key->conf.keyidx,
144 sta ? sta->sta.addr : bcast_addr, ret);
148 145
149 out_unsupported: 146 out_unsupported:
150 switch (key->conf.cipher) { 147 switch (key->conf.cipher) {
@@ -163,7 +160,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
163static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) 160static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
164{ 161{
165 struct ieee80211_sub_if_data *sdata; 162 struct ieee80211_sub_if_data *sdata;
166 struct ieee80211_sta *sta; 163 struct sta_info *sta;
167 int ret; 164 int ret;
168 165
169 might_sleep(); 166 might_sleep();
@@ -176,7 +173,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
176 if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) 173 if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
177 return; 174 return;
178 175
179 sta = get_sta_for_key(key); 176 sta = key->sta;
180 sdata = key->sdata; 177 sdata = key->sdata;
181 178
182 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || 179 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
@@ -185,12 +182,13 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
185 increment_tailroom_need_count(sdata); 182 increment_tailroom_need_count(sdata);
186 183
187 ret = drv_set_key(key->local, DISABLE_KEY, sdata, 184 ret = drv_set_key(key->local, DISABLE_KEY, sdata,
188 sta, &key->conf); 185 sta ? &sta->sta : NULL, &key->conf);
189 186
190 if (ret) 187 if (ret)
191 wiphy_err(key->local->hw.wiphy, 188 wiphy_err(key->local->hw.wiphy,
192 "failed to remove key (%d, %pM) from hardware (%d)\n", 189 "failed to remove key (%d, %pM) from hardware (%d)\n",
193 key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); 190 key->conf.keyidx,
191 sta ? sta->sta.addr : bcast_addr, ret);
194 192
195 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 193 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
196} 194}