aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/ibss.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/ibss.c')
-rw-r--r--net/wireless/ibss.c79
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
72int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 74int __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
98int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 106int 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,
112static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) 121static 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
175static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, 197int 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
223int cfg80211_ibss_wext_siwfreq(struct net_device *dev, 264int 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 */
271EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); 316EXPORT_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 */
339EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); 388EXPORT_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 */
420EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); 473EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);