aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/key.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r--net/mac80211/key.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index ccd676b2f599..84cf9196820f 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -84,10 +84,17 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
84 goto out_unsupported; 84 goto out_unsupported;
85 85
86 sdata = key->sdata; 86 sdata = key->sdata;
87 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 87 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
88 /*
89 * The driver doesn't know anything about VLAN interfaces.
90 * Hence, don't send GTKs for VLAN interfaces to the driver.
91 */
92 if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE))
93 goto out_unsupported;
88 sdata = container_of(sdata->bss, 94 sdata = container_of(sdata->bss,
89 struct ieee80211_sub_if_data, 95 struct ieee80211_sub_if_data,
90 u.ap); 96 u.ap);
97 }
91 98
92 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf); 99 ret = drv_set_key(key->local, SET_KEY, sdata, sta, &key->conf);
93 100
@@ -171,7 +178,7 @@ void ieee80211_key_removed(struct ieee80211_key_conf *key_conf)
171EXPORT_SYMBOL_GPL(ieee80211_key_removed); 178EXPORT_SYMBOL_GPL(ieee80211_key_removed);
172 179
173static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, 180static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
174 int idx) 181 int idx, bool uni, bool multi)
175{ 182{
176 struct ieee80211_key *key = NULL; 183 struct ieee80211_key *key = NULL;
177 184
@@ -180,18 +187,19 @@ static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
180 if (idx >= 0 && idx < NUM_DEFAULT_KEYS) 187 if (idx >= 0 && idx < NUM_DEFAULT_KEYS)
181 key = sdata->keys[idx]; 188 key = sdata->keys[idx];
182 189
183 rcu_assign_pointer(sdata->default_key, key); 190 if (uni)
191 rcu_assign_pointer(sdata->default_unicast_key, key);
192 if (multi)
193 rcu_assign_pointer(sdata->default_multicast_key, key);
184 194
185 if (key) { 195 ieee80211_debugfs_key_update_default(sdata);
186 ieee80211_debugfs_key_remove_default(key->sdata);
187 ieee80211_debugfs_key_add_default(key->sdata);
188 }
189} 196}
190 197
191void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx) 198void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx,
199 bool uni, bool multi)
192{ 200{
193 mutex_lock(&sdata->local->key_mtx); 201 mutex_lock(&sdata->local->key_mtx);
194 __ieee80211_set_default_key(sdata, idx); 202 __ieee80211_set_default_key(sdata, idx, uni, multi);
195 mutex_unlock(&sdata->local->key_mtx); 203 mutex_unlock(&sdata->local->key_mtx);
196} 204}
197 205
@@ -208,10 +216,7 @@ __ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, int idx)
208 216
209 rcu_assign_pointer(sdata->default_mgmt_key, key); 217 rcu_assign_pointer(sdata->default_mgmt_key, key);
210 218
211 if (key) { 219 ieee80211_debugfs_key_update_default(sdata);
212 ieee80211_debugfs_key_remove_mgmt_default(key->sdata);
213 ieee80211_debugfs_key_add_mgmt_default(key->sdata);
214 }
215} 220}
216 221
217void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, 222void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
@@ -229,7 +234,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
229 struct ieee80211_key *old, 234 struct ieee80211_key *old,
230 struct ieee80211_key *new) 235 struct ieee80211_key *new)
231{ 236{
232 int idx, defkey, defmgmtkey; 237 int idx;
238 bool defunikey, defmultikey, defmgmtkey;
233 239
234 if (new) 240 if (new)
235 list_add(&new->list, &sdata->key_list); 241 list_add(&new->list, &sdata->key_list);
@@ -250,17 +256,24 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
250 else 256 else
251 idx = new->conf.keyidx; 257 idx = new->conf.keyidx;
252 258
253 defkey = old && sdata->default_key == old; 259 defunikey = old && sdata->default_unicast_key == old;
260 defmultikey = old && sdata->default_multicast_key == old;
254 defmgmtkey = old && sdata->default_mgmt_key == old; 261 defmgmtkey = old && sdata->default_mgmt_key == old;
255 262
256 if (defkey && !new) 263 if (defunikey && !new)
257 __ieee80211_set_default_key(sdata, -1); 264 __ieee80211_set_default_key(sdata, -1, true, false);
265 if (defmultikey && !new)
266 __ieee80211_set_default_key(sdata, -1, false, true);
258 if (defmgmtkey && !new) 267 if (defmgmtkey && !new)
259 __ieee80211_set_default_mgmt_key(sdata, -1); 268 __ieee80211_set_default_mgmt_key(sdata, -1);
260 269
261 rcu_assign_pointer(sdata->keys[idx], new); 270 rcu_assign_pointer(sdata->keys[idx], new);
262 if (defkey && new) 271 if (defunikey && new)
263 __ieee80211_set_default_key(sdata, new->conf.keyidx); 272 __ieee80211_set_default_key(sdata, new->conf.keyidx,
273 true, false);
274 if (defmultikey && new)
275 __ieee80211_set_default_key(sdata, new->conf.keyidx,
276 false, true);
264 if (defmgmtkey && new) 277 if (defmgmtkey && new)
265 __ieee80211_set_default_mgmt_key(sdata, 278 __ieee80211_set_default_mgmt_key(sdata,
266 new->conf.keyidx); 279 new->conf.keyidx);
@@ -502,11 +515,12 @@ void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata)
502 515
503 mutex_lock(&sdata->local->key_mtx); 516 mutex_lock(&sdata->local->key_mtx);
504 517
505 ieee80211_debugfs_key_remove_default(sdata);
506 ieee80211_debugfs_key_remove_mgmt_default(sdata); 518 ieee80211_debugfs_key_remove_mgmt_default(sdata);
507 519
508 list_for_each_entry_safe(key, tmp, &sdata->key_list, list) 520 list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
509 __ieee80211_key_free(key); 521 __ieee80211_key_free(key);
510 522
523 ieee80211_debugfs_key_update_default(sdata);
524
511 mutex_unlock(&sdata->local->key_mtx); 525 mutex_unlock(&sdata->local->key_mtx);
512} 526}