diff options
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r-- | net/mac80211/key.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 84cf9196820f..8c02469b7176 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -30,19 +30,20 @@ | |||
30 | * keys and per-station keys. Since each station belongs to an interface, | 30 | * keys and per-station keys. Since each station belongs to an interface, |
31 | * each station key also belongs to that interface. | 31 | * each station key also belongs to that interface. |
32 | * | 32 | * |
33 | * Hardware acceleration is done on a best-effort basis, for each key | 33 | * Hardware acceleration is done on a best-effort basis for algorithms |
34 | * that is eligible the hardware is asked to enable that key but if | 34 | * that are implemented in software, for each key the hardware is asked |
35 | * it cannot do that they key is simply kept for software encryption. | 35 | * to enable that key for offloading but if it cannot do that the key is |
36 | * There is currently no way of knowing this except by looking into | 36 | * simply kept for software encryption (unless it is for an algorithm |
37 | * debugfs. | 37 | * that isn't implemented in software). |
38 | * There is currently no way of knowing whether a key is handled in SW | ||
39 | * or HW except by looking into debugfs. | ||
38 | * | 40 | * |
39 | * All key operations are protected internally. | 41 | * All key management is internally protected by a mutex. Within all |
40 | * | 42 | * other parts of mac80211, key references are, just as STA structure |
41 | * Within mac80211, key references are, just as STA structure references, | 43 | * references, protected by RCU. Note, however, that some things are |
42 | * protected by RCU. Note, however, that some things are unprotected, | 44 | * unprotected, namely the key->sta dereferences within the hardware |
43 | * namely the key->sta dereferences within the hardware acceleration | 45 | * acceleration functions. This means that sta_info_destroy() must |
44 | * functions. This means that sta_info_destroy() must remove the key | 46 | * remove the key which waits for an RCU grace period. |
45 | * which waits for an RCU grace period. | ||
46 | */ | 47 | */ |
47 | 48 | ||
48 | static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 49 | static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
@@ -279,13 +280,8 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, | |||
279 | new->conf.keyidx); | 280 | new->conf.keyidx); |
280 | } | 281 | } |
281 | 282 | ||
282 | if (old) { | 283 | if (old) |
283 | /* | 284 | list_del(&old->list); |
284 | * We'll use an empty list to indicate that the key | ||
285 | * has already been removed. | ||
286 | */ | ||
287 | list_del_init(&old->list); | ||
288 | } | ||
289 | } | 285 | } |
290 | 286 | ||
291 | struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | 287 | struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, |
@@ -379,6 +375,12 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
379 | if (!key) | 375 | if (!key) |
380 | return; | 376 | return; |
381 | 377 | ||
378 | /* | ||
379 | * Synchronize so the TX path can no longer be using | ||
380 | * this key before we free/remove it. | ||
381 | */ | ||
382 | synchronize_rcu(); | ||
383 | |||
382 | if (key->local) | 384 | if (key->local) |
383 | ieee80211_key_disable_hw_accel(key); | 385 | ieee80211_key_disable_hw_accel(key); |
384 | 386 | ||
@@ -420,8 +422,8 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
420 | struct sta_info *ap; | 422 | struct sta_info *ap; |
421 | 423 | ||
422 | /* | 424 | /* |
423 | * We're getting a sta pointer in, | 425 | * We're getting a sta pointer in, so must be under |
424 | * so must be under RCU read lock. | 426 | * appropriate locking for sta_info_get(). |
425 | */ | 427 | */ |
426 | 428 | ||
427 | /* same here, the AP could be using QoS */ | 429 | /* same here, the AP could be using QoS */ |