diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2008-02-25 10:27:45 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-02-29 15:42:04 -0500 |
commit | db4d1169d0b893bfb7923b6526748fe2c5a7373f (patch) | |
tree | ebd5ac06685bacc069b162b31f99b33c6191b4c3 /net/mac80211/ieee80211_key.h | |
parent | 6f48422a29714ed92f6136d9e7d3ff39c75607d7 (diff) |
mac80211: split ieee80211_key_alloc/free
In order to RCU-ify sta_info, we need to be able to allocate
a key without linking it to an sdata/sta structure (because
allocation cannot be done in an rcu critical section). This
patch splits up ieee80211_key_alloc() and updates all users
appropriately.
While at it, this patch fixes a number of race conditions
such as finally making key replacement atomic, unfortunately
at the expense of more complex code.
Note that this patch documents /existing/ bugs with sta info
and key interaction, there is currently a race condition
when a sta info is freed without holding the RTNL. This will
finally be fixed by a followup patch.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/ieee80211_key.h')
-rw-r--r-- | net/mac80211/ieee80211_key.h | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/net/mac80211/ieee80211_key.h b/net/mac80211/ieee80211_key.h index fc770e98d47b..d670e6dbfa39 100644 --- a/net/mac80211/ieee80211_key.h +++ b/net/mac80211/ieee80211_key.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
15 | #include <linux/crypto.h> | 15 | #include <linux/crypto.h> |
16 | #include <linux/rcupdate.h> | ||
16 | #include <net/mac80211.h> | 17 | #include <net/mac80211.h> |
17 | 18 | ||
18 | /* ALG_TKIP | 19 | /* ALG_TKIP |
@@ -45,7 +46,19 @@ struct ieee80211_local; | |||
45 | struct ieee80211_sub_if_data; | 46 | struct ieee80211_sub_if_data; |
46 | struct sta_info; | 47 | struct sta_info; |
47 | 48 | ||
48 | #define KEY_FLAG_UPLOADED_TO_HARDWARE (1<<0) | 49 | /** |
50 | * enum ieee80211_internal_key_flags - internal key flags | ||
51 | * | ||
52 | * @KEY_FLAG_UPLOADED_TO_HARDWARE: Indicates that this key is present | ||
53 | * in the hardware for TX crypto hardware acceleration. | ||
54 | * @KEY_FLAG_REMOVE_FROM_HARDWARE: Indicates to the key code that this | ||
55 | * key is present in the hardware (but it cannot be used for | ||
56 | * hardware acceleration any more!) | ||
57 | */ | ||
58 | enum ieee80211_internal_key_flags { | ||
59 | KEY_FLAG_UPLOADED_TO_HARDWARE = BIT(0), | ||
60 | KEY_FLAG_REMOVE_FROM_HARDWARE = BIT(1), | ||
61 | }; | ||
49 | 62 | ||
50 | struct ieee80211_key { | 63 | struct ieee80211_key { |
51 | struct ieee80211_local *local; | 64 | struct ieee80211_local *local; |
@@ -112,12 +125,17 @@ struct ieee80211_key { | |||
112 | struct ieee80211_key_conf conf; | 125 | struct ieee80211_key_conf conf; |
113 | }; | 126 | }; |
114 | 127 | ||
115 | struct ieee80211_key *ieee80211_key_alloc(struct ieee80211_sub_if_data *sdata, | 128 | struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, |
116 | struct sta_info *sta, | ||
117 | enum ieee80211_key_alg alg, | ||
118 | int idx, | 129 | int idx, |
119 | size_t key_len, | 130 | size_t key_len, |
120 | const u8 *key_data); | 131 | const u8 *key_data); |
132 | /* | ||
133 | * Insert a key into data structures (sdata, sta if necessary) | ||
134 | * to make it used, free old key. | ||
135 | */ | ||
136 | void ieee80211_key_link(struct ieee80211_key *key, | ||
137 | struct ieee80211_sub_if_data *sdata, | ||
138 | struct sta_info *sta); | ||
121 | void ieee80211_key_free(struct ieee80211_key *key); | 139 | void ieee80211_key_free(struct ieee80211_key *key); |
122 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); | 140 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); |
123 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); | 141 | void ieee80211_free_keys(struct ieee80211_sub_if_data *sdata); |