diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-10-05 13:39:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-06 16:30:40 -0400 |
commit | e31b82136d1adc7a599b6e99d3321e5831841f5a (patch) | |
tree | c72d78d4cccfd08587e909c7efe59956f1cbc23e /net/mac80211/cfg.c | |
parent | 53f73c09d64f1fa7d7e6e8b6bb7468d42eddc92d (diff) |
cfg80211/mac80211: allow per-station GTKs
This adds API to allow adding per-station GTKs,
updates mac80211 to support it, and also allows
drivers to remove a key from hwaccel again when
this may be necessary due to multiple GTKs.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r-- | net/mac80211/cfg.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 94bf550bd4c9..8b0e874a3d65 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -103,7 +103,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
103 | } | 103 | } |
104 | 104 | ||
105 | static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | 105 | static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, |
106 | u8 key_idx, const u8 *mac_addr, | 106 | u8 key_idx, bool pairwise, const u8 *mac_addr, |
107 | struct key_params *params) | 107 | struct key_params *params) |
108 | { | 108 | { |
109 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 109 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
@@ -131,6 +131,9 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
131 | if (IS_ERR(key)) | 131 | if (IS_ERR(key)) |
132 | return PTR_ERR(key); | 132 | return PTR_ERR(key); |
133 | 133 | ||
134 | if (pairwise) | ||
135 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; | ||
136 | |||
134 | mutex_lock(&sdata->local->sta_mtx); | 137 | mutex_lock(&sdata->local->sta_mtx); |
135 | 138 | ||
136 | if (mac_addr) { | 139 | if (mac_addr) { |
@@ -153,7 +156,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
153 | } | 156 | } |
154 | 157 | ||
155 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | 158 | static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, |
156 | u8 key_idx, const u8 *mac_addr) | 159 | u8 key_idx, bool pairwise, const u8 *mac_addr) |
157 | { | 160 | { |
158 | struct ieee80211_sub_if_data *sdata; | 161 | struct ieee80211_sub_if_data *sdata; |
159 | struct sta_info *sta; | 162 | struct sta_info *sta; |
@@ -170,10 +173,17 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
170 | if (!sta) | 173 | if (!sta) |
171 | goto out_unlock; | 174 | goto out_unlock; |
172 | 175 | ||
173 | if (sta->key) { | 176 | if (pairwise) { |
174 | ieee80211_key_free(sdata->local, sta->key); | 177 | if (sta->ptk) { |
175 | WARN_ON(sta->key); | 178 | ieee80211_key_free(sdata->local, sta->ptk); |
176 | ret = 0; | 179 | ret = 0; |
180 | } | ||
181 | } else { | ||
182 | if (sta->gtk[key_idx]) { | ||
183 | ieee80211_key_free(sdata->local, | ||
184 | sta->gtk[key_idx]); | ||
185 | ret = 0; | ||
186 | } | ||
177 | } | 187 | } |
178 | 188 | ||
179 | goto out_unlock; | 189 | goto out_unlock; |
@@ -195,7 +205,8 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
195 | } | 205 | } |
196 | 206 | ||
197 | static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | 207 | static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, |
198 | u8 key_idx, const u8 *mac_addr, void *cookie, | 208 | u8 key_idx, bool pairwise, const u8 *mac_addr, |
209 | void *cookie, | ||
199 | void (*callback)(void *cookie, | 210 | void (*callback)(void *cookie, |
200 | struct key_params *params)) | 211 | struct key_params *params)) |
201 | { | 212 | { |
@@ -203,7 +214,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
203 | struct sta_info *sta = NULL; | 214 | struct sta_info *sta = NULL; |
204 | u8 seq[6] = {0}; | 215 | u8 seq[6] = {0}; |
205 | struct key_params params; | 216 | struct key_params params; |
206 | struct ieee80211_key *key; | 217 | struct ieee80211_key *key = NULL; |
207 | u32 iv32; | 218 | u32 iv32; |
208 | u16 iv16; | 219 | u16 iv16; |
209 | int err = -ENOENT; | 220 | int err = -ENOENT; |
@@ -217,7 +228,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
217 | if (!sta) | 228 | if (!sta) |
218 | goto out; | 229 | goto out; |
219 | 230 | ||
220 | key = sta->key; | 231 | if (pairwise) |
232 | key = sta->ptk; | ||
233 | else if (key_idx < NUM_DEFAULT_KEYS) | ||
234 | key = sta->gtk[key_idx]; | ||
221 | } else | 235 | } else |
222 | key = sdata->keys[key_idx]; | 236 | key = sdata->keys[key_idx]; |
223 | 237 | ||