diff options
Diffstat (limited to 'net/wireless/ibss.c')
-rw-r--r-- | net/wireless/ibss.c | 79 |
1 files changed, 66 insertions, 13 deletions
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 99ef9364b7e8..9394e78cd11f 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -39,6 +39,8 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid) | |||
39 | cfg80211_hold_bss(bss_from_pub(bss)); | 39 | cfg80211_hold_bss(bss_from_pub(bss)); |
40 | wdev->current_bss = bss_from_pub(bss); | 40 | wdev->current_bss = bss_from_pub(bss); |
41 | 41 | ||
42 | cfg80211_upload_connect_keys(wdev); | ||
43 | |||
42 | nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, | 44 | nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, |
43 | GFP_KERNEL); | 45 | GFP_KERNEL); |
44 | #ifdef CONFIG_WIRELESS_EXT | 46 | #ifdef CONFIG_WIRELESS_EXT |
@@ -71,7 +73,8 @@ EXPORT_SYMBOL(cfg80211_ibss_joined); | |||
71 | 73 | ||
72 | int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | 74 | int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, |
73 | struct net_device *dev, | 75 | struct net_device *dev, |
74 | struct cfg80211_ibss_params *params) | 76 | struct cfg80211_ibss_params *params, |
77 | struct cfg80211_cached_keys *connkeys) | ||
75 | { | 78 | { |
76 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 79 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
77 | int err; | 80 | int err; |
@@ -81,13 +84,18 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
81 | if (wdev->ssid_len) | 84 | if (wdev->ssid_len) |
82 | return -EALREADY; | 85 | return -EALREADY; |
83 | 86 | ||
87 | if (WARN_ON(wdev->connect_keys)) | ||
88 | kfree(wdev->connect_keys); | ||
89 | wdev->connect_keys = connkeys; | ||
90 | |||
84 | #ifdef CONFIG_WIRELESS_EXT | 91 | #ifdef CONFIG_WIRELESS_EXT |
85 | wdev->wext.ibss.channel = params->channel; | 92 | wdev->wext.ibss.channel = params->channel; |
86 | #endif | 93 | #endif |
87 | err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); | 94 | err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); |
88 | 95 | if (err) { | |
89 | if (err) | 96 | wdev->connect_keys = NULL; |
90 | return err; | 97 | return err; |
98 | } | ||
91 | 99 | ||
92 | memcpy(wdev->ssid, params->ssid, params->ssid_len); | 100 | memcpy(wdev->ssid, params->ssid, params->ssid_len); |
93 | wdev->ssid_len = params->ssid_len; | 101 | wdev->ssid_len = params->ssid_len; |
@@ -97,13 +105,14 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
97 | 105 | ||
98 | int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | 106 | int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, |
99 | struct net_device *dev, | 107 | struct net_device *dev, |
100 | struct cfg80211_ibss_params *params) | 108 | struct cfg80211_ibss_params *params, |
109 | struct cfg80211_cached_keys *connkeys) | ||
101 | { | 110 | { |
102 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 111 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
103 | int err; | 112 | int err; |
104 | 113 | ||
105 | wdev_lock(wdev); | 114 | wdev_lock(wdev); |
106 | err = __cfg80211_join_ibss(rdev, dev, params); | 115 | err = __cfg80211_join_ibss(rdev, dev, params, connkeys); |
107 | wdev_unlock(wdev); | 116 | wdev_unlock(wdev); |
108 | 117 | ||
109 | return err; | 118 | return err; |
@@ -112,9 +121,22 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
112 | static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | 121 | static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) |
113 | { | 122 | { |
114 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 123 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | ||
125 | int i; | ||
115 | 126 | ||
116 | ASSERT_WDEV_LOCK(wdev); | 127 | ASSERT_WDEV_LOCK(wdev); |
117 | 128 | ||
129 | kfree(wdev->connect_keys); | ||
130 | wdev->connect_keys = NULL; | ||
131 | |||
132 | /* | ||
133 | * Delete all the keys ... pairwise keys can't really | ||
134 | * exist any more anyway, but default keys might. | ||
135 | */ | ||
136 | if (rdev->ops->del_key) | ||
137 | for (i = 0; i < 6; i++) | ||
138 | rdev->ops->del_key(wdev->wiphy, dev, i, NULL); | ||
139 | |||
118 | if (wdev->current_bss) { | 140 | if (wdev->current_bss) { |
119 | cfg80211_unhold_bss(wdev->current_bss); | 141 | cfg80211_unhold_bss(wdev->current_bss); |
120 | cfg80211_put_bss(&wdev->current_bss->pub); | 142 | cfg80211_put_bss(&wdev->current_bss->pub); |
@@ -172,11 +194,14 @@ int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, | |||
172 | } | 194 | } |
173 | 195 | ||
174 | #ifdef CONFIG_WIRELESS_EXT | 196 | #ifdef CONFIG_WIRELESS_EXT |
175 | static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | 197 | int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, |
176 | struct wireless_dev *wdev) | 198 | struct wireless_dev *wdev) |
177 | { | 199 | { |
200 | struct cfg80211_cached_keys *ck = NULL; | ||
178 | enum ieee80211_band band; | 201 | enum ieee80211_band band; |
179 | int i; | 202 | int i, err; |
203 | |||
204 | ASSERT_WDEV_LOCK(wdev); | ||
180 | 205 | ||
181 | if (!wdev->wext.ibss.beacon_interval) | 206 | if (!wdev->wext.ibss.beacon_interval) |
182 | wdev->wext.ibss.beacon_interval = 100; | 207 | wdev->wext.ibss.beacon_interval = 100; |
@@ -216,8 +241,24 @@ static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, | |||
216 | if (!netif_running(wdev->netdev)) | 241 | if (!netif_running(wdev->netdev)) |
217 | return 0; | 242 | return 0; |
218 | 243 | ||
219 | return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), | 244 | if (wdev->wext.keys) |
220 | wdev->netdev, &wdev->wext.ibss); | 245 | wdev->wext.keys->def = wdev->wext.default_key; |
246 | |||
247 | wdev->wext.ibss.privacy = wdev->wext.default_key != -1; | ||
248 | |||
249 | if (wdev->wext.keys) { | ||
250 | ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); | ||
251 | if (!ck) | ||
252 | return -ENOMEM; | ||
253 | for (i = 0; i < 6; i++) | ||
254 | ck->params[i].key = ck->data[i]; | ||
255 | } | ||
256 | err = __cfg80211_join_ibss(rdev, wdev->netdev, | ||
257 | &wdev->wext.ibss, ck); | ||
258 | if (err) | ||
259 | kfree(ck); | ||
260 | |||
261 | return err; | ||
221 | } | 262 | } |
222 | 263 | ||
223 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | 264 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, |
@@ -265,7 +306,11 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | |||
265 | wdev->wext.ibss.channel_fixed = false; | 306 | wdev->wext.ibss.channel_fixed = false; |
266 | } | 307 | } |
267 | 308 | ||
268 | return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | 309 | wdev_lock(wdev); |
310 | err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | ||
311 | wdev_unlock(wdev); | ||
312 | |||
313 | return err; | ||
269 | } | 314 | } |
270 | /* temporary symbol - mark GPL - in the future the handler won't be */ | 315 | /* temporary symbol - mark GPL - in the future the handler won't be */ |
271 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); | 316 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); |
@@ -333,7 +378,11 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev, | |||
333 | memcpy(wdev->wext.ibss.ssid, ssid, len); | 378 | memcpy(wdev->wext.ibss.ssid, ssid, len); |
334 | wdev->wext.ibss.ssid_len = len; | 379 | wdev->wext.ibss.ssid_len = len; |
335 | 380 | ||
336 | return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | 381 | wdev_lock(wdev); |
382 | err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | ||
383 | wdev_unlock(wdev); | ||
384 | |||
385 | return err; | ||
337 | } | 386 | } |
338 | /* temporary symbol - mark GPL - in the future the handler won't be */ | 387 | /* temporary symbol - mark GPL - in the future the handler won't be */ |
339 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); | 388 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); |
@@ -414,7 +463,11 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev, | |||
414 | } else | 463 | } else |
415 | wdev->wext.ibss.bssid = NULL; | 464 | wdev->wext.ibss.bssid = NULL; |
416 | 465 | ||
417 | return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | 466 | wdev_lock(wdev); |
467 | err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); | ||
468 | wdev_unlock(wdev); | ||
469 | |||
470 | return err; | ||
418 | } | 471 | } |
419 | /* temporary symbol - mark GPL - in the future the handler won't be */ | 472 | /* temporary symbol - mark GPL - in the future the handler won't be */ |
420 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); | 473 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); |