Blame view
net/wireless/ibss.c
12.2 KB
b24413180 License cleanup: ... |
1 |
// SPDX-License-Identifier: GPL-2.0 |
04a773ade cfg80211/nl80211:... |
2 3 4 5 6 7 8 9 |
/* * Some IBSS support code for cfg80211. * * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> */ #include <linux/etherdevice.h> #include <linux/if_arp.h> |
5a0e3ad6a include cleanup: ... |
10 |
#include <linux/slab.h> |
bc3b2d7fb net: Add export.h... |
11 |
#include <linux/export.h> |
04a773ade cfg80211/nl80211:... |
12 |
#include <net/cfg80211.h> |
0e82ffe3b cfg80211: combine... |
13 |
#include "wext-compat.h" |
04a773ade cfg80211/nl80211:... |
14 |
#include "nl80211.h" |
e35e4d28b cfg80211: add wra... |
15 |
#include "rdev-ops.h" |
04a773ade cfg80211/nl80211:... |
16 |
|
fe94f3a4f cfg80211: fix cha... |
17 18 |
void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, struct ieee80211_channel *channel) |
04a773ade cfg80211/nl80211:... |
19 20 21 |
{ struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_bss *bss; |
3d23e349d wext: refactor |
22 |
#ifdef CONFIG_CFG80211_WEXT |
04a773ade cfg80211/nl80211:... |
23 24 25 26 27 |
union iwreq_data wrqu; #endif if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return; |
f7969969f cfg80211: make sp... |
28 |
if (!wdev->ssid_len) |
04a773ade cfg80211/nl80211:... |
29 |
return; |
fe94f3a4f cfg80211: fix cha... |
30 |
bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, NULL, 0, |
6eb181376 cfg80211: add bss... |
31 |
IEEE80211_BSS_TYPE_IBSS, IEEE80211_PRIVACY_ANY); |
04a773ade cfg80211/nl80211:... |
32 33 34 35 36 37 |
if (WARN_ON(!bss)) return; if (wdev->current_bss) { cfg80211_unhold_bss(wdev->current_bss); |
5b112d3d0 cfg80211: pass wi... |
38 |
cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); |
04a773ade cfg80211/nl80211:... |
39 |
} |
19957bb39 cfg80211: keep tr... |
40 41 |
cfg80211_hold_bss(bss_from_pub(bss)); wdev->current_bss = bss_from_pub(bss); |
04a773ade cfg80211/nl80211:... |
42 |
|
b8676221f cfg80211: Add sup... |
43 44 |
if (!(wdev->wiphy->flags & WIPHY_FLAG_HAS_STATIC_WEP)) cfg80211_upload_connect_keys(wdev); |
fffd0934b cfg80211: rework ... |
45 |
|
f26cbf401 cfg80211: change ... |
46 |
nl80211_send_ibss_bssid(wiphy_to_rdev(wdev->wiphy), dev, bssid, |
667503ddc cfg80211: fix loc... |
47 |
GFP_KERNEL); |
3d23e349d wext: refactor |
48 |
#ifdef CONFIG_CFG80211_WEXT |
04a773ade cfg80211/nl80211:... |
49 50 51 52 53 |
memset(&wrqu, 0, sizeof(wrqu)); memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); #endif } |
667503ddc cfg80211: fix loc... |
54 |
|
fe94f3a4f cfg80211: fix cha... |
55 56 |
void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, struct ieee80211_channel *channel, gfp_t gfp) |
667503ddc cfg80211: fix loc... |
57 58 |
{ struct wireless_dev *wdev = dev->ieee80211_ptr; |
f26cbf401 cfg80211: change ... |
59 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
667503ddc cfg80211: fix loc... |
60 61 |
struct cfg80211_event *ev; unsigned long flags; |
fe94f3a4f cfg80211: fix cha... |
62 63 64 65 |
trace_cfg80211_ibss_joined(dev, bssid, channel); if (WARN_ON(!channel)) return; |
4ee3e063f cfg80211: add cfg... |
66 |
|
667503ddc cfg80211: fix loc... |
67 68 69 70 71 |
ev = kzalloc(sizeof(*ev), gfp); if (!ev) return; ev->type = EVENT_IBSS_JOINED; |
fe94f3a4f cfg80211: fix cha... |
72 73 |
memcpy(ev->ij.bssid, bssid, ETH_ALEN); ev->ij.channel = channel; |
667503ddc cfg80211: fix loc... |
74 75 76 77 |
spin_lock_irqsave(&wdev->event_lock, flags); list_add_tail(&ev->list, &wdev->event_list); spin_unlock_irqrestore(&wdev->event_lock, flags); |
e60d7443e wireless : use a ... |
78 |
queue_work(cfg80211_wq, &rdev->event_work); |
667503ddc cfg80211: fix loc... |
79 |
} |
04a773ade cfg80211/nl80211:... |
80 |
EXPORT_SYMBOL(cfg80211_ibss_joined); |
f8d16d3ed nl80211: Add SOCK... |
81 82 83 84 |
int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, struct net_device *dev, struct cfg80211_ibss_params *params, struct cfg80211_cached_keys *connkeys) |
04a773ade cfg80211/nl80211:... |
85 86 87 |
{ struct wireless_dev *wdev = dev->ieee80211_ptr; int err; |
f8d16d3ed nl80211: Add SOCK... |
88 |
ASSERT_RTNL(); |
667503ddc cfg80211: fix loc... |
89 |
ASSERT_WDEV_LOCK(wdev); |
04a773ade cfg80211/nl80211:... |
90 91 |
if (wdev->ssid_len) return -EALREADY; |
93b052380 cfg80211: always ... |
92 93 94 95 96 97 |
if (!params->basic_rates) { /* * If no rates were explicitly configured, * use the mandatory rate set for 11b or * 11a for maximum compatibility. */ |
5ea4e7802 cfg80211: ibss: u... |
98 99 100 |
struct ieee80211_supported_band *sband; enum nl80211_band band; u32 flag; |
93b052380 cfg80211: always ... |
101 |
int j; |
93b052380 cfg80211: always ... |
102 |
|
5ea4e7802 cfg80211: ibss: u... |
103 104 105 106 107 108 109 110 |
band = params->chandef.chan->band; if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) flag = IEEE80211_RATE_MANDATORY_A; else flag = IEEE80211_RATE_MANDATORY_B; sband = rdev->wiphy.bands[band]; |
93b052380 cfg80211: always ... |
111 112 113 114 115 |
for (j = 0; j < sband->n_bitrates; j++) { if (sband->bitrates[j].flags & flag) params->basic_rates |= BIT(j); } } |
f1c1f17ac cfg80211: allow c... |
116 117 |
if (WARN_ON(connkeys && connkeys->def < 0)) return -EINVAL; |
fffd0934b cfg80211: rework ... |
118 |
if (WARN_ON(wdev->connect_keys)) |
453431a54 mm, treewide: ren... |
119 |
kfree_sensitive(wdev->connect_keys); |
fffd0934b cfg80211: rework ... |
120 |
wdev->connect_keys = connkeys; |
c30a3d386 cfg80211: track i... |
121 |
wdev->ibss_fixed = params->channel_fixed; |
5336fa88e nl80211/cfg80211:... |
122 |
wdev->ibss_dfs_possible = params->userspace_handles_dfs; |
9e0e29615 cfg80211: conside... |
123 |
wdev->chandef = params->chandef; |
9ae3b172e cfg80211: IBSS: A... |
124 125 126 127 |
if (connkeys) { params->wep_keys = connkeys->params; params->wep_tx_key = connkeys->def; } |
3d23e349d wext: refactor |
128 |
#ifdef CONFIG_CFG80211_WEXT |
683b6d3b3 cfg80211: pass a ... |
129 |
wdev->wext.ibss.chandef = params->chandef; |
04a773ade cfg80211/nl80211:... |
130 |
#endif |
e35e4d28b cfg80211: add wra... |
131 |
err = rdev_join_ibss(rdev, dev, params); |
fffd0934b cfg80211: rework ... |
132 133 |
if (err) { wdev->connect_keys = NULL; |
04a773ade cfg80211/nl80211:... |
134 |
return err; |
fffd0934b cfg80211: rework ... |
135 |
} |
04a773ade cfg80211/nl80211:... |
136 137 138 139 140 141 |
memcpy(wdev->ssid, params->ssid, params->ssid_len); wdev->ssid_len = params->ssid_len; return 0; } |
667503ddc cfg80211: fix loc... |
142 |
static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) |
04a773ade cfg80211/nl80211:... |
143 144 |
{ struct wireless_dev *wdev = dev->ieee80211_ptr; |
f26cbf401 cfg80211: change ... |
145 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
fffd0934b cfg80211: rework ... |
146 |
int i; |
04a773ade cfg80211/nl80211:... |
147 |
|
667503ddc cfg80211: fix loc... |
148 |
ASSERT_WDEV_LOCK(wdev); |
453431a54 mm, treewide: ren... |
149 |
kfree_sensitive(wdev->connect_keys); |
fffd0934b cfg80211: rework ... |
150 |
wdev->connect_keys = NULL; |
fa9ffc745 cfg80211: Add sup... |
151 |
rdev_set_qos_map(rdev, dev, NULL); |
fffd0934b cfg80211: rework ... |
152 153 154 155 156 157 |
/* * Delete all the keys ... pairwise keys can't really * exist any more anyway, but default keys might. */ if (rdev->ops->del_key) for (i = 0; i < 6; i++) |
e35e4d28b cfg80211: add wra... |
158 |
rdev_del_key(rdev, dev, i, false, NULL); |
fffd0934b cfg80211: rework ... |
159 |
|
04a773ade cfg80211/nl80211:... |
160 161 |
if (wdev->current_bss) { cfg80211_unhold_bss(wdev->current_bss); |
5b112d3d0 cfg80211: pass wi... |
162 |
cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); |
04a773ade cfg80211/nl80211:... |
163 164 165 166 |
} wdev->current_bss = NULL; wdev->ssid_len = 0; |
9e0e29615 cfg80211: conside... |
167 |
memset(&wdev->chandef, 0, sizeof(wdev->chandef)); |
3d23e349d wext: refactor |
168 |
#ifdef CONFIG_CFG80211_WEXT |
9d308429a cfg80211: clear W... |
169 |
if (!nowext) |
cbe8fa9c5 cfg80211: put wex... |
170 |
wdev->wext.ibss.ssid_len = 0; |
9d308429a cfg80211: clear W... |
171 |
#endif |
b35a51c7d cfg80211: Make pr... |
172 |
cfg80211_sched_dfs_chan_update(rdev); |
04a773ade cfg80211/nl80211:... |
173 |
} |
667503ddc cfg80211: fix loc... |
174 175 176 177 178 179 180 181 |
void cfg80211_clear_ibss(struct net_device *dev, bool nowext) { struct wireless_dev *wdev = dev->ieee80211_ptr; wdev_lock(wdev); __cfg80211_clear_ibss(dev, nowext); wdev_unlock(wdev); } |
98d3a7ca9 cfg80211: re-join... |
182 183 |
int __cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, struct net_device *dev, bool nowext) |
04a773ade cfg80211/nl80211:... |
184 |
{ |
784854756 cfg80211: fix net... |
185 |
struct wireless_dev *wdev = dev->ieee80211_ptr; |
04a773ade cfg80211/nl80211:... |
186 |
int err; |
667503ddc cfg80211: fix loc... |
187 |
ASSERT_WDEV_LOCK(wdev); |
784854756 cfg80211: fix net... |
188 189 |
if (!wdev->ssid_len) return -ENOLINK; |
e35e4d28b cfg80211: add wra... |
190 |
err = rdev_leave_ibss(rdev, dev); |
04a773ade cfg80211/nl80211:... |
191 192 193 |
if (err) return err; |
f8d16d3ed nl80211: Add SOCK... |
194 |
wdev->conn_owner_nlportid = 0; |
667503ddc cfg80211: fix loc... |
195 |
__cfg80211_clear_ibss(dev, nowext); |
04a773ade cfg80211/nl80211:... |
196 197 198 |
return 0; } |
667503ddc cfg80211: fix loc... |
199 200 201 202 203 204 205 206 207 208 209 210 |
int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, struct net_device *dev, bool nowext) { struct wireless_dev *wdev = dev->ieee80211_ptr; int err; wdev_lock(wdev); err = __cfg80211_leave_ibss(rdev, dev, nowext); wdev_unlock(wdev); return err; } |
3d23e349d wext: refactor |
211 |
#ifdef CONFIG_CFG80211_WEXT |
fffd0934b cfg80211: rework ... |
212 213 |
int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev) |
04a773ade cfg80211/nl80211:... |
214 |
{ |
fffd0934b cfg80211: rework ... |
215 |
struct cfg80211_cached_keys *ck = NULL; |
57fbcce37 cfg80211: remove ... |
216 |
enum nl80211_band band; |
fffd0934b cfg80211: rework ... |
217 218 219 |
int i, err; ASSERT_WDEV_LOCK(wdev); |
04a773ade cfg80211/nl80211:... |
220 |
|
cbe8fa9c5 cfg80211: put wex... |
221 222 |
if (!wdev->wext.ibss.beacon_interval) wdev->wext.ibss.beacon_interval = 100; |
8e30bc55d nl80211: allow co... |
223 |
|
04a773ade cfg80211/nl80211:... |
224 |
/* try to find an IBSS channel if none requested ... */ |
683b6d3b3 cfg80211: pass a ... |
225 |
if (!wdev->wext.ibss.chandef.chan) { |
1fe4517ce cfg80211: fix ibs... |
226 |
struct ieee80211_channel *new_chan = NULL; |
683b6d3b3 cfg80211: pass a ... |
227 |
|
57fbcce37 cfg80211: remove ... |
228 |
for (band = 0; band < NUM_NL80211_BANDS; band++) { |
04a773ade cfg80211/nl80211:... |
229 230 231 232 233 234 235 236 237 |
struct ieee80211_supported_band *sband; struct ieee80211_channel *chan; sband = rdev->wiphy.bands[band]; if (!sband) continue; for (i = 0; i < sband->n_channels; i++) { chan = &sband->channels[i]; |
8fe02e167 cfg80211: consoli... |
238 |
if (chan->flags & IEEE80211_CHAN_NO_IR) |
04a773ade cfg80211/nl80211:... |
239 240 241 |
continue; if (chan->flags & IEEE80211_CHAN_DISABLED) continue; |
1fe4517ce cfg80211: fix ibs... |
242 |
new_chan = chan; |
04a773ade cfg80211/nl80211:... |
243 244 |
break; } |
1fe4517ce cfg80211: fix ibs... |
245 |
if (new_chan) |
04a773ade cfg80211/nl80211:... |
246 247 |
break; } |
1fe4517ce cfg80211: fix ibs... |
248 |
if (!new_chan) |
04a773ade cfg80211/nl80211:... |
249 |
return -EINVAL; |
1fe4517ce cfg80211: fix ibs... |
250 251 252 |
cfg80211_chandef_create(&wdev->wext.ibss.chandef, new_chan, NL80211_CHAN_NO_HT); |
04a773ade cfg80211/nl80211:... |
253 254 255 |
} /* don't join -- SSID is not there */ |
cbe8fa9c5 cfg80211: put wex... |
256 |
if (!wdev->wext.ibss.ssid_len) |
04a773ade cfg80211/nl80211:... |
257 258 259 260 |
return 0; if (!netif_running(wdev->netdev)) return 0; |
89b706fb2 cfg80211: reduce ... |
261 |
if (wdev->wext.keys) |
fffd0934b cfg80211: rework ... |
262 263 264 |
wdev->wext.keys->def = wdev->wext.default_key; wdev->wext.ibss.privacy = wdev->wext.default_key != -1; |
f1c1f17ac cfg80211: allow c... |
265 |
if (wdev->wext.keys && wdev->wext.keys->def != -1) { |
fffd0934b cfg80211: rework ... |
266 267 268 |
ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL); if (!ck) return -ENOMEM; |
b8676221f cfg80211: Add sup... |
269 |
for (i = 0; i < CFG80211_MAX_WEP_KEYS; i++) |
fffd0934b cfg80211: rework ... |
270 271 272 273 274 275 276 277 |
ck->params[i].key = ck->data[i]; } err = __cfg80211_join_ibss(rdev, wdev->netdev, &wdev->wext.ibss, ck); if (err) kfree(ck); return err; |
04a773ade cfg80211/nl80211:... |
278 279 280 281 |
} int cfg80211_ibss_wext_siwfreq(struct net_device *dev, struct iw_request_info *info, |
59bbb6f75 cfg80211: validat... |
282 |
struct iw_freq *wextfreq, char *extra) |
04a773ade cfg80211/nl80211:... |
283 284 |
{ struct wireless_dev *wdev = dev->ieee80211_ptr; |
f26cbf401 cfg80211: change ... |
285 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
59bbb6f75 cfg80211: validat... |
286 287 |
struct ieee80211_channel *chan = NULL; int err, freq; |
04a773ade cfg80211/nl80211:... |
288 289 290 291 |
/* call only for ibss! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return -EINVAL; |
59bbb6f75 cfg80211: validat... |
292 |
if (!rdev->ops->join_ibss) |
04a773ade cfg80211/nl80211:... |
293 |
return -EOPNOTSUPP; |
96998e3a2 cfg80211: remove ... |
294 |
freq = cfg80211_wext_freq(wextfreq); |
59bbb6f75 cfg80211: validat... |
295 296 |
if (freq < 0) return freq; |
04a773ade cfg80211/nl80211:... |
297 |
|
59bbb6f75 cfg80211: validat... |
298 299 300 301 |
if (freq) { chan = ieee80211_get_channel(wdev->wiphy, freq); if (!chan) return -EINVAL; |
8fe02e167 cfg80211: consoli... |
302 |
if (chan->flags & IEEE80211_CHAN_NO_IR || |
59bbb6f75 cfg80211: validat... |
303 304 305 |
chan->flags & IEEE80211_CHAN_DISABLED) return -EINVAL; } |
04a773ade cfg80211/nl80211:... |
306 |
|
683b6d3b3 cfg80211: pass a ... |
307 |
if (wdev->wext.ibss.chandef.chan == chan) |
04a773ade cfg80211/nl80211:... |
308 |
return 0; |
667503ddc cfg80211: fix loc... |
309 310 311 |
wdev_lock(wdev); err = 0; if (wdev->ssid_len) |
59bbb6f75 cfg80211: validat... |
312 |
err = __cfg80211_leave_ibss(rdev, dev, true); |
667503ddc cfg80211: fix loc... |
313 314 315 316 |
wdev_unlock(wdev); if (err) return err; |
04a773ade cfg80211/nl80211:... |
317 318 |
if (chan) { |
1fe4517ce cfg80211: fix ibs... |
319 320 |
cfg80211_chandef_create(&wdev->wext.ibss.chandef, chan, NL80211_CHAN_NO_HT); |
cbe8fa9c5 cfg80211: put wex... |
321 |
wdev->wext.ibss.channel_fixed = true; |
04a773ade cfg80211/nl80211:... |
322 323 |
} else { /* cfg80211_ibss_wext_join will pick one if needed */ |
cbe8fa9c5 cfg80211: put wex... |
324 |
wdev->wext.ibss.channel_fixed = false; |
04a773ade cfg80211/nl80211:... |
325 |
} |
fffd0934b cfg80211: rework ... |
326 |
wdev_lock(wdev); |
59bbb6f75 cfg80211: validat... |
327 |
err = cfg80211_ibss_wext_join(rdev, wdev); |
fffd0934b cfg80211: rework ... |
328 329 330 |
wdev_unlock(wdev); return err; |
04a773ade cfg80211/nl80211:... |
331 |
} |
04a773ade cfg80211/nl80211:... |
332 333 334 335 336 337 338 339 340 341 342 |
int cfg80211_ibss_wext_giwfreq(struct net_device *dev, struct iw_request_info *info, struct iw_freq *freq, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; struct ieee80211_channel *chan = NULL; /* call only for ibss! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return -EINVAL; |
667503ddc cfg80211: fix loc... |
343 |
wdev_lock(wdev); |
04a773ade cfg80211/nl80211:... |
344 |
if (wdev->current_bss) |
19957bb39 cfg80211: keep tr... |
345 |
chan = wdev->current_bss->pub.channel; |
683b6d3b3 cfg80211: pass a ... |
346 347 |
else if (wdev->wext.ibss.chandef.chan) chan = wdev->wext.ibss.chandef.chan; |
667503ddc cfg80211: fix loc... |
348 |
wdev_unlock(wdev); |
04a773ade cfg80211/nl80211:... |
349 350 351 352 353 354 355 356 357 358 |
if (chan) { freq->m = chan->center_freq; freq->e = 6; return 0; } /* no channel if not joining */ return -EINVAL; } |
04a773ade cfg80211/nl80211:... |
359 360 361 362 363 364 |
int cfg80211_ibss_wext_siwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) { struct wireless_dev *wdev = dev->ieee80211_ptr; |
f26cbf401 cfg80211: change ... |
365 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
04a773ade cfg80211/nl80211:... |
366 367 368 369 370 371 |
size_t len = data->length; int err; /* call only for ibss! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return -EINVAL; |
59bbb6f75 cfg80211: validat... |
372 |
if (!rdev->ops->join_ibss) |
04a773ade cfg80211/nl80211:... |
373 |
return -EOPNOTSUPP; |
667503ddc cfg80211: fix loc... |
374 375 376 |
wdev_lock(wdev); err = 0; if (wdev->ssid_len) |
59bbb6f75 cfg80211: validat... |
377 |
err = __cfg80211_leave_ibss(rdev, dev, true); |
667503ddc cfg80211: fix loc... |
378 379 380 381 |
wdev_unlock(wdev); if (err) return err; |
04a773ade cfg80211/nl80211:... |
382 383 384 385 |
/* iwconfig uses nul termination in SSID.. */ if (len > 0 && ssid[len - 1] == '\0') len--; |
c1e5f4714 cfg80211: constif... |
386 |
memcpy(wdev->ssid, ssid, len); |
cbe8fa9c5 cfg80211: put wex... |
387 |
wdev->wext.ibss.ssid = wdev->ssid; |
cbe8fa9c5 cfg80211: put wex... |
388 |
wdev->wext.ibss.ssid_len = len; |
04a773ade cfg80211/nl80211:... |
389 |
|
fffd0934b cfg80211: rework ... |
390 |
wdev_lock(wdev); |
59bbb6f75 cfg80211: validat... |
391 |
err = cfg80211_ibss_wext_join(rdev, wdev); |
fffd0934b cfg80211: rework ... |
392 393 394 |
wdev_unlock(wdev); return err; |
04a773ade cfg80211/nl80211:... |
395 |
} |
04a773ade cfg80211/nl80211:... |
396 397 398 399 400 401 402 403 404 405 406 407 |
int cfg80211_ibss_wext_giwessid(struct net_device *dev, struct iw_request_info *info, struct iw_point *data, char *ssid) { struct wireless_dev *wdev = dev->ieee80211_ptr; /* call only for ibss! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return -EINVAL; data->flags = 0; |
667503ddc cfg80211: fix loc... |
408 |
wdev_lock(wdev); |
04a773ade cfg80211/nl80211:... |
409 410 411 412 |
if (wdev->ssid_len) { data->flags = 1; data->length = wdev->ssid_len; memcpy(ssid, wdev->ssid, data->length); |
cbe8fa9c5 cfg80211: put wex... |
413 |
} else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) { |
04a773ade cfg80211/nl80211:... |
414 |
data->flags = 1; |
cbe8fa9c5 cfg80211: put wex... |
415 416 |
data->length = wdev->wext.ibss.ssid_len; memcpy(ssid, wdev->wext.ibss.ssid, data->length); |
04a773ade cfg80211/nl80211:... |
417 |
} |
667503ddc cfg80211: fix loc... |
418 |
wdev_unlock(wdev); |
04a773ade cfg80211/nl80211:... |
419 420 421 |
return 0; } |
04a773ade cfg80211/nl80211:... |
422 423 424 425 426 427 |
int cfg80211_ibss_wext_siwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; |
f26cbf401 cfg80211: change ... |
428 |
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
04a773ade cfg80211/nl80211:... |
429 430 431 432 433 434 |
u8 *bssid = ap_addr->sa_data; int err; /* call only for ibss! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return -EINVAL; |
59bbb6f75 cfg80211: validat... |
435 |
if (!rdev->ops->join_ibss) |
04a773ade cfg80211/nl80211:... |
436 437 438 439 440 441 442 443 |
return -EOPNOTSUPP; if (ap_addr->sa_family != ARPHRD_ETHER) return -EINVAL; /* automatic mode */ if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid)) bssid = NULL; |
74f827410 cfg80211: reject ... |
444 445 |
if (bssid && !is_valid_ether_addr(bssid)) return -EINVAL; |
04a773ade cfg80211/nl80211:... |
446 |
/* both automatic */ |
cbe8fa9c5 cfg80211: put wex... |
447 |
if (!bssid && !wdev->wext.ibss.bssid) |
04a773ade cfg80211/nl80211:... |
448 449 450 |
return 0; /* fixed already - and no change */ |
cbe8fa9c5 cfg80211: put wex... |
451 |
if (wdev->wext.ibss.bssid && bssid && |
ac422d3cc wireless: Convert... |
452 |
ether_addr_equal(bssid, wdev->wext.ibss.bssid)) |
04a773ade cfg80211/nl80211:... |
453 |
return 0; |
667503ddc cfg80211: fix loc... |
454 455 456 |
wdev_lock(wdev); err = 0; if (wdev->ssid_len) |
59bbb6f75 cfg80211: validat... |
457 |
err = __cfg80211_leave_ibss(rdev, dev, true); |
667503ddc cfg80211: fix loc... |
458 459 460 461 |
wdev_unlock(wdev); if (err) return err; |
04a773ade cfg80211/nl80211:... |
462 463 |
if (bssid) { |
cbe8fa9c5 cfg80211: put wex... |
464 465 |
memcpy(wdev->wext.bssid, bssid, ETH_ALEN); wdev->wext.ibss.bssid = wdev->wext.bssid; |
04a773ade cfg80211/nl80211:... |
466 |
} else |
cbe8fa9c5 cfg80211: put wex... |
467 |
wdev->wext.ibss.bssid = NULL; |
04a773ade cfg80211/nl80211:... |
468 |
|
fffd0934b cfg80211: rework ... |
469 |
wdev_lock(wdev); |
59bbb6f75 cfg80211: validat... |
470 |
err = cfg80211_ibss_wext_join(rdev, wdev); |
fffd0934b cfg80211: rework ... |
471 472 473 |
wdev_unlock(wdev); return err; |
04a773ade cfg80211/nl80211:... |
474 |
} |
04a773ade cfg80211/nl80211:... |
475 476 477 478 479 480 481 482 483 484 485 486 |
int cfg80211_ibss_wext_giwap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *ap_addr, char *extra) { struct wireless_dev *wdev = dev->ieee80211_ptr; /* call only for ibss! */ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC)) return -EINVAL; ap_addr->sa_family = ARPHRD_ETHER; |
667503ddc cfg80211: fix loc... |
487 |
wdev_lock(wdev); |
7ebbe6bd5 cfg80211: remove ... |
488 |
if (wdev->current_bss) |
19957bb39 cfg80211: keep tr... |
489 |
memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); |
80e5b06a1 cfg80211: fix NUL... |
490 |
else if (wdev->wext.ibss.bssid) |
cbe8fa9c5 cfg80211: put wex... |
491 |
memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN); |
80e5b06a1 cfg80211: fix NUL... |
492 |
else |
d2beae107 wireless: Use eth... |
493 |
eth_zero_addr(ap_addr->sa_data); |
80e5b06a1 cfg80211: fix NUL... |
494 |
|
667503ddc cfg80211: fix loc... |
495 |
wdev_unlock(wdev); |
04a773ade cfg80211/nl80211:... |
496 497 |
return 0; } |
04a773ade cfg80211/nl80211:... |
498 |
#endif |