]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - net/wireless/nl80211.c
cfg80211/mac80211: Use more generic bitrate mask for rate control
[mirror_ubuntu-focal-kernel.git] / net / wireless / nl80211.c
CommitLineData
55682965
JB
1/*
2 * This is the new netlink-based wireless configuration interface.
3 *
08645126 4 * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
55682965
JB
5 */
6
7#include <linux/if.h>
8#include <linux/module.h>
9#include <linux/err.h>
55682965
JB
10#include <linux/list.h>
11#include <linux/if_ether.h>
12#include <linux/ieee80211.h>
13#include <linux/nl80211.h>
14#include <linux/rtnetlink.h>
15#include <linux/netlink.h>
2a519311 16#include <linux/etherdevice.h>
463d0183 17#include <net/net_namespace.h>
55682965
JB
18#include <net/genetlink.h>
19#include <net/cfg80211.h>
463d0183 20#include <net/sock.h>
55682965
JB
21#include "core.h"
22#include "nl80211.h"
b2e1b302 23#include "reg.h"
55682965
JB
24
25/* the netlink family */
26static struct genl_family nl80211_fam = {
27 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
28 .name = "nl80211", /* have users key off the name instead */
29 .hdrsize = 0, /* no private header */
30 .version = 1, /* no particular meaning now */
31 .maxattr = NL80211_ATTR_MAX,
463d0183 32 .netnsok = true,
55682965
JB
33};
34
79c97e97 35/* internal helper: get rdev and dev */
463d0183 36static int get_rdev_dev_by_info_ifindex(struct genl_info *info,
79c97e97 37 struct cfg80211_registered_device **rdev,
55682965
JB
38 struct net_device **dev)
39{
463d0183 40 struct nlattr **attrs = info->attrs;
55682965
JB
41 int ifindex;
42
bba95fef 43 if (!attrs[NL80211_ATTR_IFINDEX])
55682965
JB
44 return -EINVAL;
45
bba95fef 46 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
463d0183 47 *dev = dev_get_by_index(genl_info_net(info), ifindex);
55682965
JB
48 if (!*dev)
49 return -ENODEV;
50
463d0183 51 *rdev = cfg80211_get_dev_from_ifindex(genl_info_net(info), ifindex);
79c97e97 52 if (IS_ERR(*rdev)) {
55682965 53 dev_put(*dev);
79c97e97 54 return PTR_ERR(*rdev);
55682965
JB
55 }
56
57 return 0;
58}
59
60/* policy for the attributes */
61static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
62 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
63 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 64 .len = 20-1 },
31888487 65 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
72bdcf34 66 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 67 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
b9a5f8ca
JM
68 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
69 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
70 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
71 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 72 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
55682965
JB
73
74 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
75 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
76 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f
JB
77
78 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
3e5d7649 79 [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN },
41ade00f 80
b9454e83 81 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
82 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
83 .len = WLAN_MAX_KEY_LEN },
84 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
85 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
86 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
9f26a952 87 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
ed1b6cc7
JB
88
89 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
90 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
91 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
92 .len = IEEE80211_MAX_DATA_LEN },
93 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
94 .len = IEEE80211_MAX_DATA_LEN },
5727ef1b
JB
95 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
96 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
97 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
98 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
99 .len = NL80211_MAX_SUPP_RATES },
2ec600d6 100 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
5727ef1b 101 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 102 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6
LCC
103 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
104 .len = IEEE80211_MAX_MESH_ID_LEN },
105 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 106
b2e1b302
LR
107 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
108 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
109
9f1ba906
JM
110 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
111 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
112 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
113 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
114 .len = NL80211_MAX_SUPP_RATES },
36aedc90 115
93da9cc1 116 [NL80211_ATTR_MESH_PARAMS] = { .type = NLA_NESTED },
117
36aedc90
JM
118 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
119 .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
120
121 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
122 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
123 .len = IEEE80211_MAX_DATA_LEN },
2a519311
JB
124 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
125 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
126
127 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
128 .len = IEEE80211_MAX_SSID_LEN },
129 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
130 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 131 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 132 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
dc6382ce 133 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
eccb8e8f
JB
134 [NL80211_ATTR_STA_FLAGS2] = {
135 .len = sizeof(struct nl80211_sta_flag_update),
136 },
3f77316c 137 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
b23aa676
SO
138 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
139 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
140 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 141 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 142 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
67fbb16b
SO
143 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
144 .len = WLAN_PMKID_LEN },
9588bbd5
JM
145 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
146 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
55682965
JB
147};
148
b9454e83
JB
149/* policy for the attributes */
150static struct nla_policy
151nl80211_key_policy[NL80211_KEY_MAX + 1] __read_mostly = {
fffd0934 152 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
153 [NL80211_KEY_IDX] = { .type = NLA_U8 },
154 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
155 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
156 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
157 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
158};
159
a043897a
HS
160/* ifidx get helper */
161static int nl80211_get_ifidx(struct netlink_callback *cb)
162{
163 int res;
164
165 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
166 nl80211_fam.attrbuf, nl80211_fam.maxattr,
167 nl80211_policy);
168 if (res)
169 return res;
170
171 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
172 return -EINVAL;
173
174 res = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
175 if (!res)
176 return -EINVAL;
177 return res;
178}
179
f4a11bb0
JB
180/* IE validation */
181static bool is_valid_ie_attr(const struct nlattr *attr)
182{
183 const u8 *pos;
184 int len;
185
186 if (!attr)
187 return true;
188
189 pos = nla_data(attr);
190 len = nla_len(attr);
191
192 while (len) {
193 u8 elemlen;
194
195 if (len < 2)
196 return false;
197 len -= 2;
198
199 elemlen = pos[1];
200 if (elemlen > len)
201 return false;
202
203 len -= elemlen;
204 pos += 2 + elemlen;
205 }
206
207 return true;
208}
209
55682965
JB
210/* message building helper */
211static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
212 int flags, u8 cmd)
213{
214 /* since there is no private header just add the generic one */
215 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
216}
217
5dab3b8a
LR
218static int nl80211_msg_put_channel(struct sk_buff *msg,
219 struct ieee80211_channel *chan)
220{
221 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
222 chan->center_freq);
223
224 if (chan->flags & IEEE80211_CHAN_DISABLED)
225 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
226 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
227 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
228 if (chan->flags & IEEE80211_CHAN_NO_IBSS)
229 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
230 if (chan->flags & IEEE80211_CHAN_RADAR)
231 NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
232
233 NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
234 DBM_TO_MBM(chan->max_power));
235
236 return 0;
237
238 nla_put_failure:
239 return -ENOBUFS;
240}
241
55682965
JB
242/* netlink command implementations */
243
b9454e83
JB
244struct key_parse {
245 struct key_params p;
246 int idx;
247 bool def, defmgmt;
248};
249
250static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
251{
252 struct nlattr *tb[NL80211_KEY_MAX + 1];
253 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
254 nl80211_key_policy);
255 if (err)
256 return err;
257
258 k->def = !!tb[NL80211_KEY_DEFAULT];
259 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
260
261 if (tb[NL80211_KEY_IDX])
262 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
263
264 if (tb[NL80211_KEY_DATA]) {
265 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
266 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
267 }
268
269 if (tb[NL80211_KEY_SEQ]) {
270 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
271 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
272 }
273
274 if (tb[NL80211_KEY_CIPHER])
275 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
276
277 return 0;
278}
279
280static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
281{
282 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
283 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
284 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
285 }
286
287 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
288 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
289 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
290 }
291
292 if (info->attrs[NL80211_ATTR_KEY_IDX])
293 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
294
295 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
296 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
297
298 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
299 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
300
301 return 0;
302}
303
304static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
305{
306 int err;
307
308 memset(k, 0, sizeof(*k));
309 k->idx = -1;
310
311 if (info->attrs[NL80211_ATTR_KEY])
312 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
313 else
314 err = nl80211_parse_key_old(info, k);
315
316 if (err)
317 return err;
318
319 if (k->def && k->defmgmt)
320 return -EINVAL;
321
322 if (k->idx != -1) {
323 if (k->defmgmt) {
324 if (k->idx < 4 || k->idx > 5)
325 return -EINVAL;
326 } else if (k->def) {
327 if (k->idx < 0 || k->idx > 3)
328 return -EINVAL;
329 } else {
330 if (k->idx < 0 || k->idx > 5)
331 return -EINVAL;
332 }
333 }
334
335 return 0;
336}
337
fffd0934
JB
338static struct cfg80211_cached_keys *
339nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
340 struct nlattr *keys)
341{
342 struct key_parse parse;
343 struct nlattr *key;
344 struct cfg80211_cached_keys *result;
345 int rem, err, def = 0;
346
347 result = kzalloc(sizeof(*result), GFP_KERNEL);
348 if (!result)
349 return ERR_PTR(-ENOMEM);
350
351 result->def = -1;
352 result->defmgmt = -1;
353
354 nla_for_each_nested(key, keys, rem) {
355 memset(&parse, 0, sizeof(parse));
356 parse.idx = -1;
357
358 err = nl80211_parse_key_new(key, &parse);
359 if (err)
360 goto error;
361 err = -EINVAL;
362 if (!parse.p.key)
363 goto error;
364 if (parse.idx < 0 || parse.idx > 4)
365 goto error;
366 if (parse.def) {
367 if (def)
368 goto error;
369 def = 1;
370 result->def = parse.idx;
371 } else if (parse.defmgmt)
372 goto error;
373 err = cfg80211_validate_key_settings(rdev, &parse.p,
374 parse.idx, NULL);
375 if (err)
376 goto error;
377 result->params[parse.idx].cipher = parse.p.cipher;
378 result->params[parse.idx].key_len = parse.p.key_len;
379 result->params[parse.idx].key = result->data[parse.idx];
380 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
381 }
382
383 return result;
384 error:
385 kfree(result);
386 return ERR_PTR(err);
387}
388
389static int nl80211_key_allowed(struct wireless_dev *wdev)
390{
391 ASSERT_WDEV_LOCK(wdev);
392
393 if (!netif_running(wdev->netdev))
394 return -ENETDOWN;
395
396 switch (wdev->iftype) {
397 case NL80211_IFTYPE_AP:
398 case NL80211_IFTYPE_AP_VLAN:
399 break;
400 case NL80211_IFTYPE_ADHOC:
401 if (!wdev->current_bss)
402 return -ENOLINK;
403 break;
404 case NL80211_IFTYPE_STATION:
405 if (wdev->sme_state != CFG80211_SME_CONNECTED)
406 return -ENOLINK;
407 break;
408 default:
409 return -EINVAL;
410 }
411
412 return 0;
413}
414
55682965
JB
415static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
416 struct cfg80211_registered_device *dev)
417{
418 void *hdr;
ee688b00
JB
419 struct nlattr *nl_bands, *nl_band;
420 struct nlattr *nl_freqs, *nl_freq;
421 struct nlattr *nl_rates, *nl_rate;
f59ac048 422 struct nlattr *nl_modes;
8fdc621d 423 struct nlattr *nl_cmds;
ee688b00
JB
424 enum ieee80211_band band;
425 struct ieee80211_channel *chan;
426 struct ieee80211_rate *rate;
427 int i;
f59ac048 428 u16 ifmodes = dev->wiphy.interface_modes;
55682965
JB
429
430 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
431 if (!hdr)
432 return -1;
433
b5850a7a 434 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
55682965 435 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
b9a5f8ca 436
f5ea9120
JB
437 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
438 cfg80211_rdev_list_generation);
439
b9a5f8ca
JM
440 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
441 dev->wiphy.retry_short);
442 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
443 dev->wiphy.retry_long);
444 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
445 dev->wiphy.frag_threshold);
446 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
447 dev->wiphy.rts_threshold);
81077e82
LT
448 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
449 dev->wiphy.coverage_class);
b9a5f8ca 450
2a519311
JB
451 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
452 dev->wiphy.max_scan_ssids);
18a83659
JB
453 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
454 dev->wiphy.max_scan_ie_len);
ee688b00 455
25e47c18
JB
456 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
457 sizeof(u32) * dev->wiphy.n_cipher_suites,
458 dev->wiphy.cipher_suites);
459
67fbb16b
SO
460 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
461 dev->wiphy.max_num_pmkids);
462
f59ac048
LR
463 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
464 if (!nl_modes)
465 goto nla_put_failure;
466
467 i = 0;
468 while (ifmodes) {
469 if (ifmodes & 1)
470 NLA_PUT_FLAG(msg, i);
471 ifmodes >>= 1;
472 i++;
473 }
474
475 nla_nest_end(msg, nl_modes);
476
ee688b00
JB
477 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
478 if (!nl_bands)
479 goto nla_put_failure;
480
481 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
482 if (!dev->wiphy.bands[band])
483 continue;
484
485 nl_band = nla_nest_start(msg, band);
486 if (!nl_band)
487 goto nla_put_failure;
488
d51626df
JB
489 /* add HT info */
490 if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
491 NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
492 sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
493 &dev->wiphy.bands[band]->ht_cap.mcs);
494 NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
495 dev->wiphy.bands[band]->ht_cap.cap);
496 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
497 dev->wiphy.bands[band]->ht_cap.ampdu_factor);
498 NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
499 dev->wiphy.bands[band]->ht_cap.ampdu_density);
500 }
501
ee688b00
JB
502 /* add frequencies */
503 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
504 if (!nl_freqs)
505 goto nla_put_failure;
506
507 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
508 nl_freq = nla_nest_start(msg, i);
509 if (!nl_freq)
510 goto nla_put_failure;
511
512 chan = &dev->wiphy.bands[band]->channels[i];
5dab3b8a
LR
513
514 if (nl80211_msg_put_channel(msg, chan))
515 goto nla_put_failure;
e2f367f2 516
ee688b00
JB
517 nla_nest_end(msg, nl_freq);
518 }
519
520 nla_nest_end(msg, nl_freqs);
521
522 /* add bitrates */
523 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
524 if (!nl_rates)
525 goto nla_put_failure;
526
527 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
528 nl_rate = nla_nest_start(msg, i);
529 if (!nl_rate)
530 goto nla_put_failure;
531
532 rate = &dev->wiphy.bands[band]->bitrates[i];
533 NLA_PUT_U32(msg, NL80211_BITRATE_ATTR_RATE,
534 rate->bitrate);
535 if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)
536 NLA_PUT_FLAG(msg,
537 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE);
538
539 nla_nest_end(msg, nl_rate);
540 }
541
542 nla_nest_end(msg, nl_rates);
543
544 nla_nest_end(msg, nl_band);
545 }
546 nla_nest_end(msg, nl_bands);
547
8fdc621d
JB
548 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
549 if (!nl_cmds)
550 goto nla_put_failure;
551
552 i = 0;
553#define CMD(op, n) \
554 do { \
555 if (dev->ops->op) { \
556 i++; \
557 NLA_PUT_U32(msg, i, NL80211_CMD_ ## n); \
558 } \
559 } while (0)
560
561 CMD(add_virtual_intf, NEW_INTERFACE);
562 CMD(change_virtual_intf, SET_INTERFACE);
563 CMD(add_key, NEW_KEY);
564 CMD(add_beacon, NEW_BEACON);
565 CMD(add_station, NEW_STATION);
566 CMD(add_mpath, NEW_MPATH);
567 CMD(set_mesh_params, SET_MESH_PARAMS);
568 CMD(change_bss, SET_BSS);
636a5d36
JM
569 CMD(auth, AUTHENTICATE);
570 CMD(assoc, ASSOCIATE);
571 CMD(deauth, DEAUTHENTICATE);
572 CMD(disassoc, DISASSOCIATE);
04a773ad 573 CMD(join_ibss, JOIN_IBSS);
67fbb16b
SO
574 CMD(set_pmksa, SET_PMKSA);
575 CMD(del_pmksa, DEL_PMKSA);
576 CMD(flush_pmksa, FLUSH_PMKSA);
9588bbd5 577 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
5be83de5 578 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
463d0183
JB
579 i++;
580 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
581 }
8fdc621d
JB
582
583#undef CMD
b23aa676 584
6829c878 585 if (dev->ops->connect || dev->ops->auth) {
b23aa676
SO
586 i++;
587 NLA_PUT_U32(msg, i, NL80211_CMD_CONNECT);
588 }
589
6829c878 590 if (dev->ops->disconnect || dev->ops->deauth) {
b23aa676
SO
591 i++;
592 NLA_PUT_U32(msg, i, NL80211_CMD_DISCONNECT);
593 }
594
8fdc621d
JB
595 nla_nest_end(msg, nl_cmds);
596
55682965
JB
597 return genlmsg_end(msg, hdr);
598
599 nla_put_failure:
bc3ed28c
TG
600 genlmsg_cancel(msg, hdr);
601 return -EMSGSIZE;
55682965
JB
602}
603
604static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
605{
606 int idx = 0;
607 int start = cb->args[0];
608 struct cfg80211_registered_device *dev;
609
a1794390 610 mutex_lock(&cfg80211_mutex);
79c97e97 611 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
463d0183
JB
612 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
613 continue;
b4637271 614 if (++idx <= start)
55682965
JB
615 continue;
616 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
617 cb->nlh->nlmsg_seq, NLM_F_MULTI,
b4637271
JV
618 dev) < 0) {
619 idx--;
55682965 620 break;
b4637271 621 }
55682965 622 }
a1794390 623 mutex_unlock(&cfg80211_mutex);
55682965
JB
624
625 cb->args[0] = idx;
626
627 return skb->len;
628}
629
630static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
631{
632 struct sk_buff *msg;
633 struct cfg80211_registered_device *dev;
634
635 dev = cfg80211_get_dev_from_info(info);
636 if (IS_ERR(dev))
637 return PTR_ERR(dev);
638
fd2120ca 639 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
640 if (!msg)
641 goto out_err;
642
643 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0)
644 goto out_free;
645
4d0c8aea 646 cfg80211_unlock_rdev(dev);
55682965 647
134e6375 648 return genlmsg_reply(msg, info);
55682965
JB
649
650 out_free:
651 nlmsg_free(msg);
652 out_err:
4d0c8aea 653 cfg80211_unlock_rdev(dev);
55682965
JB
654 return -ENOBUFS;
655}
656
31888487
JM
657static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
658 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
659 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
660 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
661 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
662 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
663};
664
665static int parse_txq_params(struct nlattr *tb[],
666 struct ieee80211_txq_params *txq_params)
667{
668 if (!tb[NL80211_TXQ_ATTR_QUEUE] || !tb[NL80211_TXQ_ATTR_TXOP] ||
669 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
670 !tb[NL80211_TXQ_ATTR_AIFS])
671 return -EINVAL;
672
673 txq_params->queue = nla_get_u8(tb[NL80211_TXQ_ATTR_QUEUE]);
674 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
675 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
676 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
677 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
678
679 return 0;
680}
681
55682965
JB
682static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
683{
684 struct cfg80211_registered_device *rdev;
31888487
JM
685 int result = 0, rem_txq_params = 0;
686 struct nlattr *nl_txq_params;
b9a5f8ca
JM
687 u32 changed;
688 u8 retry_short = 0, retry_long = 0;
689 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 690 u8 coverage_class = 0;
55682965 691
4bbf4d56 692 rtnl_lock();
55682965 693
4bbf4d56
JB
694 mutex_lock(&cfg80211_mutex);
695
79c97e97 696 rdev = __cfg80211_rdev_from_info(info);
4bbf4d56 697 if (IS_ERR(rdev)) {
1f5fc70a 698 mutex_unlock(&cfg80211_mutex);
4bbf4d56
JB
699 result = PTR_ERR(rdev);
700 goto unlock;
701 }
702
703 mutex_lock(&rdev->mtx);
704
705 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
706 result = cfg80211_dev_rename(
707 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56
JB
708
709 mutex_unlock(&cfg80211_mutex);
710
711 if (result)
712 goto bad_res;
31888487
JM
713
714 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
715 struct ieee80211_txq_params txq_params;
716 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
717
718 if (!rdev->ops->set_txq_params) {
719 result = -EOPNOTSUPP;
720 goto bad_res;
721 }
722
723 nla_for_each_nested(nl_txq_params,
724 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
725 rem_txq_params) {
726 nla_parse(tb, NL80211_TXQ_ATTR_MAX,
727 nla_data(nl_txq_params),
728 nla_len(nl_txq_params),
729 txq_params_policy);
730 result = parse_txq_params(tb, &txq_params);
731 if (result)
732 goto bad_res;
733
734 result = rdev->ops->set_txq_params(&rdev->wiphy,
735 &txq_params);
736 if (result)
737 goto bad_res;
738 }
739 }
55682965 740
72bdcf34 741 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
094d05dc 742 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
294196ab 743 u32 freq;
72bdcf34 744
306d6112
JB
745 result = -EINVAL;
746
094d05dc
S
747 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
748 channel_type = nla_get_u32(info->attrs[
749 NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
750 if (channel_type != NL80211_CHAN_NO_HT &&
751 channel_type != NL80211_CHAN_HT20 &&
752 channel_type != NL80211_CHAN_HT40PLUS &&
753 channel_type != NL80211_CHAN_HT40MINUS)
72bdcf34 754 goto bad_res;
72bdcf34
JM
755 }
756
757 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
306d6112 758
59bbb6f7 759 mutex_lock(&rdev->devlist_mtx);
4b181144 760 result = rdev_set_freq(rdev, NULL, freq, channel_type);
59bbb6f7 761 mutex_unlock(&rdev->devlist_mtx);
72bdcf34
JM
762 if (result)
763 goto bad_res;
764 }
765
b9a5f8ca
JM
766 changed = 0;
767
768 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
769 retry_short = nla_get_u8(
770 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
771 if (retry_short == 0) {
772 result = -EINVAL;
773 goto bad_res;
774 }
775 changed |= WIPHY_PARAM_RETRY_SHORT;
776 }
777
778 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
779 retry_long = nla_get_u8(
780 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
781 if (retry_long == 0) {
782 result = -EINVAL;
783 goto bad_res;
784 }
785 changed |= WIPHY_PARAM_RETRY_LONG;
786 }
787
788 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
789 frag_threshold = nla_get_u32(
790 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
791 if (frag_threshold < 256) {
792 result = -EINVAL;
793 goto bad_res;
794 }
795 if (frag_threshold != (u32) -1) {
796 /*
797 * Fragments (apart from the last one) are required to
798 * have even length. Make the fragmentation code
799 * simpler by stripping LSB should someone try to use
800 * odd threshold value.
801 */
802 frag_threshold &= ~0x1;
803 }
804 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
805 }
806
807 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
808 rts_threshold = nla_get_u32(
809 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
810 changed |= WIPHY_PARAM_RTS_THRESHOLD;
811 }
812
81077e82
LT
813 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
814 coverage_class = nla_get_u8(
815 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
816 changed |= WIPHY_PARAM_COVERAGE_CLASS;
817 }
818
b9a5f8ca
JM
819 if (changed) {
820 u8 old_retry_short, old_retry_long;
821 u32 old_frag_threshold, old_rts_threshold;
81077e82 822 u8 old_coverage_class;
b9a5f8ca
JM
823
824 if (!rdev->ops->set_wiphy_params) {
825 result = -EOPNOTSUPP;
826 goto bad_res;
827 }
828
829 old_retry_short = rdev->wiphy.retry_short;
830 old_retry_long = rdev->wiphy.retry_long;
831 old_frag_threshold = rdev->wiphy.frag_threshold;
832 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 833 old_coverage_class = rdev->wiphy.coverage_class;
b9a5f8ca
JM
834
835 if (changed & WIPHY_PARAM_RETRY_SHORT)
836 rdev->wiphy.retry_short = retry_short;
837 if (changed & WIPHY_PARAM_RETRY_LONG)
838 rdev->wiphy.retry_long = retry_long;
839 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
840 rdev->wiphy.frag_threshold = frag_threshold;
841 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
842 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
843 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
844 rdev->wiphy.coverage_class = coverage_class;
b9a5f8ca
JM
845
846 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
847 if (result) {
848 rdev->wiphy.retry_short = old_retry_short;
849 rdev->wiphy.retry_long = old_retry_long;
850 rdev->wiphy.frag_threshold = old_frag_threshold;
851 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 852 rdev->wiphy.coverage_class = old_coverage_class;
b9a5f8ca
JM
853 }
854 }
72bdcf34 855
306d6112 856 bad_res:
4bbf4d56
JB
857 mutex_unlock(&rdev->mtx);
858 unlock:
859 rtnl_unlock();
55682965
JB
860 return result;
861}
862
863
864static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
d726405a 865 struct cfg80211_registered_device *rdev,
55682965
JB
866 struct net_device *dev)
867{
868 void *hdr;
869
870 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
871 if (!hdr)
872 return -1;
873
874 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
d726405a 875 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
55682965 876 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
60719ffd 877 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
f5ea9120
JB
878
879 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION,
880 rdev->devlist_generation ^
881 (cfg80211_rdev_list_generation << 2));
882
55682965
JB
883 return genlmsg_end(msg, hdr);
884
885 nla_put_failure:
bc3ed28c
TG
886 genlmsg_cancel(msg, hdr);
887 return -EMSGSIZE;
55682965
JB
888}
889
890static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
891{
892 int wp_idx = 0;
893 int if_idx = 0;
894 int wp_start = cb->args[0];
895 int if_start = cb->args[1];
f5ea9120 896 struct cfg80211_registered_device *rdev;
55682965
JB
897 struct wireless_dev *wdev;
898
a1794390 899 mutex_lock(&cfg80211_mutex);
f5ea9120
JB
900 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
901 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 902 continue;
bba95fef
JB
903 if (wp_idx < wp_start) {
904 wp_idx++;
55682965 905 continue;
bba95fef 906 }
55682965
JB
907 if_idx = 0;
908
f5ea9120
JB
909 mutex_lock(&rdev->devlist_mtx);
910 list_for_each_entry(wdev, &rdev->netdev_list, list) {
bba95fef
JB
911 if (if_idx < if_start) {
912 if_idx++;
55682965 913 continue;
bba95fef 914 }
55682965
JB
915 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
916 cb->nlh->nlmsg_seq, NLM_F_MULTI,
f5ea9120
JB
917 rdev, wdev->netdev) < 0) {
918 mutex_unlock(&rdev->devlist_mtx);
bba95fef
JB
919 goto out;
920 }
921 if_idx++;
55682965 922 }
f5ea9120 923 mutex_unlock(&rdev->devlist_mtx);
bba95fef
JB
924
925 wp_idx++;
55682965 926 }
bba95fef 927 out:
a1794390 928 mutex_unlock(&cfg80211_mutex);
55682965
JB
929
930 cb->args[0] = wp_idx;
931 cb->args[1] = if_idx;
932
933 return skb->len;
934}
935
936static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
937{
938 struct sk_buff *msg;
939 struct cfg80211_registered_device *dev;
940 struct net_device *netdev;
941 int err;
942
463d0183 943 err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
55682965
JB
944 if (err)
945 return err;
946
fd2120ca 947 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
948 if (!msg)
949 goto out_err;
950
d726405a
JB
951 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
952 dev, netdev) < 0)
55682965
JB
953 goto out_free;
954
955 dev_put(netdev);
4d0c8aea 956 cfg80211_unlock_rdev(dev);
55682965 957
134e6375 958 return genlmsg_reply(msg, info);
55682965
JB
959
960 out_free:
961 nlmsg_free(msg);
962 out_err:
963 dev_put(netdev);
4d0c8aea 964 cfg80211_unlock_rdev(dev);
55682965
JB
965 return -ENOBUFS;
966}
967
66f7ac50
MW
968static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
969 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
970 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
971 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
972 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
973 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
974};
975
976static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
977{
978 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
979 int flag;
980
981 *mntrflags = 0;
982
983 if (!nla)
984 return -EINVAL;
985
986 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
987 nla, mntr_flags_policy))
988 return -EINVAL;
989
990 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
991 if (flags[flag])
992 *mntrflags |= (1<<flag);
993
994 return 0;
995}
996
9bc383de 997static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
998 struct net_device *netdev, u8 use_4addr,
999 enum nl80211_iftype iftype)
9bc383de 1000{
ad4bb6f8
JB
1001 if (!use_4addr) {
1002 if (netdev && netdev->br_port)
1003 return -EBUSY;
9bc383de 1004 return 0;
ad4bb6f8 1005 }
9bc383de
JB
1006
1007 switch (iftype) {
1008 case NL80211_IFTYPE_AP_VLAN:
1009 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
1010 return 0;
1011 break;
1012 case NL80211_IFTYPE_STATION:
1013 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
1014 return 0;
1015 break;
1016 default:
1017 break;
1018 }
1019
1020 return -EOPNOTSUPP;
1021}
1022
55682965
JB
1023static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1024{
79c97e97 1025 struct cfg80211_registered_device *rdev;
2ec600d6 1026 struct vif_params params;
e36d56b6 1027 int err;
04a773ad 1028 enum nl80211_iftype otype, ntype;
55682965 1029 struct net_device *dev;
92ffe055 1030 u32 _flags, *flags = NULL;
ac7f9cfa 1031 bool change = false;
55682965 1032
2ec600d6
LCC
1033 memset(&params, 0, sizeof(params));
1034
3b85875a
JB
1035 rtnl_lock();
1036
463d0183 1037 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
55682965 1038 if (err)
3b85875a
JB
1039 goto unlock_rtnl;
1040
04a773ad 1041 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 1042
723b038d 1043 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 1044 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 1045 if (otype != ntype)
ac7f9cfa 1046 change = true;
04a773ad 1047 if (ntype > NL80211_IFTYPE_MAX) {
ac7f9cfa 1048 err = -EINVAL;
723b038d 1049 goto unlock;
ac7f9cfa 1050 }
723b038d
JB
1051 }
1052
92ffe055 1053 if (info->attrs[NL80211_ATTR_MESH_ID]) {
04a773ad 1054 if (ntype != NL80211_IFTYPE_MESH_POINT) {
92ffe055
JB
1055 err = -EINVAL;
1056 goto unlock;
1057 }
2ec600d6
LCC
1058 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
1059 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
ac7f9cfa 1060 change = true;
2ec600d6
LCC
1061 }
1062
8b787643
FF
1063 if (info->attrs[NL80211_ATTR_4ADDR]) {
1064 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
1065 change = true;
ad4bb6f8 1066 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de
JB
1067 if (err)
1068 goto unlock;
8b787643
FF
1069 } else {
1070 params.use_4addr = -1;
1071 }
1072
92ffe055 1073 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
04a773ad 1074 if (ntype != NL80211_IFTYPE_MONITOR) {
92ffe055
JB
1075 err = -EINVAL;
1076 goto unlock;
1077 }
1078 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
1079 &_flags);
ac7f9cfa
JB
1080 if (err)
1081 goto unlock;
1082
1083 flags = &_flags;
1084 change = true;
92ffe055 1085 }
3b85875a 1086
ac7f9cfa 1087 if (change)
3d54d255 1088 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
ac7f9cfa
JB
1089 else
1090 err = 0;
60719ffd 1091
9bc383de
JB
1092 if (!err && params.use_4addr != -1)
1093 dev->ieee80211_ptr->use_4addr = params.use_4addr;
1094
55682965 1095 unlock:
e36d56b6 1096 dev_put(dev);
79c97e97 1097 cfg80211_unlock_rdev(rdev);
3b85875a
JB
1098 unlock_rtnl:
1099 rtnl_unlock();
55682965
JB
1100 return err;
1101}
1102
1103static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1104{
79c97e97 1105 struct cfg80211_registered_device *rdev;
2ec600d6 1106 struct vif_params params;
55682965
JB
1107 int err;
1108 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
66f7ac50 1109 u32 flags;
55682965 1110
2ec600d6
LCC
1111 memset(&params, 0, sizeof(params));
1112
55682965
JB
1113 if (!info->attrs[NL80211_ATTR_IFNAME])
1114 return -EINVAL;
1115
1116 if (info->attrs[NL80211_ATTR_IFTYPE]) {
1117 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
1118 if (type > NL80211_IFTYPE_MAX)
1119 return -EINVAL;
1120 }
1121
3b85875a
JB
1122 rtnl_lock();
1123
79c97e97
JB
1124 rdev = cfg80211_get_dev_from_info(info);
1125 if (IS_ERR(rdev)) {
1126 err = PTR_ERR(rdev);
3b85875a
JB
1127 goto unlock_rtnl;
1128 }
55682965 1129
79c97e97
JB
1130 if (!rdev->ops->add_virtual_intf ||
1131 !(rdev->wiphy.interface_modes & (1 << type))) {
55682965
JB
1132 err = -EOPNOTSUPP;
1133 goto unlock;
1134 }
1135
2ec600d6
LCC
1136 if (type == NL80211_IFTYPE_MESH_POINT &&
1137 info->attrs[NL80211_ATTR_MESH_ID]) {
1138 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
1139 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
1140 }
1141
9bc383de 1142 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 1143 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 1144 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de
JB
1145 if (err)
1146 goto unlock;
1147 }
8b787643 1148
66f7ac50
MW
1149 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
1150 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
1151 &flags);
79c97e97 1152 err = rdev->ops->add_virtual_intf(&rdev->wiphy,
66f7ac50 1153 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
2ec600d6 1154 type, err ? NULL : &flags, &params);
2ec600d6 1155
55682965 1156 unlock:
79c97e97 1157 cfg80211_unlock_rdev(rdev);
3b85875a
JB
1158 unlock_rtnl:
1159 rtnl_unlock();
55682965
JB
1160 return err;
1161}
1162
1163static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
1164{
79c97e97 1165 struct cfg80211_registered_device *rdev;
463d0183 1166 int err;
55682965
JB
1167 struct net_device *dev;
1168
3b85875a
JB
1169 rtnl_lock();
1170
463d0183 1171 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
55682965 1172 if (err)
3b85875a 1173 goto unlock_rtnl;
55682965 1174
79c97e97 1175 if (!rdev->ops->del_virtual_intf) {
55682965
JB
1176 err = -EOPNOTSUPP;
1177 goto out;
1178 }
1179
463d0183 1180 err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
55682965
JB
1181
1182 out:
79c97e97 1183 cfg80211_unlock_rdev(rdev);
463d0183 1184 dev_put(dev);
3b85875a
JB
1185 unlock_rtnl:
1186 rtnl_unlock();
55682965
JB
1187 return err;
1188}
1189
41ade00f
JB
1190struct get_key_cookie {
1191 struct sk_buff *msg;
1192 int error;
b9454e83 1193 int idx;
41ade00f
JB
1194};
1195
1196static void get_key_callback(void *c, struct key_params *params)
1197{
b9454e83 1198 struct nlattr *key;
41ade00f
JB
1199 struct get_key_cookie *cookie = c;
1200
1201 if (params->key)
1202 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_DATA,
1203 params->key_len, params->key);
1204
1205 if (params->seq)
1206 NLA_PUT(cookie->msg, NL80211_ATTR_KEY_SEQ,
1207 params->seq_len, params->seq);
1208
1209 if (params->cipher)
1210 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
1211 params->cipher);
1212
b9454e83
JB
1213 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
1214 if (!key)
1215 goto nla_put_failure;
1216
1217 if (params->key)
1218 NLA_PUT(cookie->msg, NL80211_KEY_DATA,
1219 params->key_len, params->key);
1220
1221 if (params->seq)
1222 NLA_PUT(cookie->msg, NL80211_KEY_SEQ,
1223 params->seq_len, params->seq);
1224
1225 if (params->cipher)
1226 NLA_PUT_U32(cookie->msg, NL80211_KEY_CIPHER,
1227 params->cipher);
1228
1229 NLA_PUT_U8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx);
1230
1231 nla_nest_end(cookie->msg, key);
1232
41ade00f
JB
1233 return;
1234 nla_put_failure:
1235 cookie->error = 1;
1236}
1237
1238static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1239{
79c97e97 1240 struct cfg80211_registered_device *rdev;
41ade00f
JB
1241 int err;
1242 struct net_device *dev;
1243 u8 key_idx = 0;
1244 u8 *mac_addr = NULL;
1245 struct get_key_cookie cookie = {
1246 .error = 0,
1247 };
1248 void *hdr;
1249 struct sk_buff *msg;
1250
1251 if (info->attrs[NL80211_ATTR_KEY_IDX])
1252 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1253
3cfcf6ac 1254 if (key_idx > 5)
41ade00f
JB
1255 return -EINVAL;
1256
1257 if (info->attrs[NL80211_ATTR_MAC])
1258 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1259
3b85875a
JB
1260 rtnl_lock();
1261
463d0183 1262 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
41ade00f 1263 if (err)
3b85875a 1264 goto unlock_rtnl;
41ade00f 1265
79c97e97 1266 if (!rdev->ops->get_key) {
41ade00f
JB
1267 err = -EOPNOTSUPP;
1268 goto out;
1269 }
1270
fd2120ca 1271 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
41ade00f
JB
1272 if (!msg) {
1273 err = -ENOMEM;
1274 goto out;
1275 }
1276
1277 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
1278 NL80211_CMD_NEW_KEY);
1279
1280 if (IS_ERR(hdr)) {
1281 err = PTR_ERR(hdr);
6c95e2a2 1282 goto free_msg;
41ade00f
JB
1283 }
1284
1285 cookie.msg = msg;
b9454e83 1286 cookie.idx = key_idx;
41ade00f
JB
1287
1288 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1289 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
1290 if (mac_addr)
1291 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
1292
79c97e97 1293 err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, mac_addr,
41ade00f 1294 &cookie, get_key_callback);
41ade00f
JB
1295
1296 if (err)
6c95e2a2 1297 goto free_msg;
41ade00f
JB
1298
1299 if (cookie.error)
1300 goto nla_put_failure;
1301
1302 genlmsg_end(msg, hdr);
134e6375 1303 err = genlmsg_reply(msg, info);
41ade00f
JB
1304 goto out;
1305
1306 nla_put_failure:
1307 err = -ENOBUFS;
6c95e2a2 1308 free_msg:
41ade00f
JB
1309 nlmsg_free(msg);
1310 out:
79c97e97 1311 cfg80211_unlock_rdev(rdev);
41ade00f 1312 dev_put(dev);
3b85875a
JB
1313 unlock_rtnl:
1314 rtnl_unlock();
1315
41ade00f
JB
1316 return err;
1317}
1318
1319static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1320{
79c97e97 1321 struct cfg80211_registered_device *rdev;
b9454e83 1322 struct key_parse key;
41ade00f
JB
1323 int err;
1324 struct net_device *dev;
3cfcf6ac
JM
1325 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1326 u8 key_index);
41ade00f 1327
b9454e83
JB
1328 err = nl80211_parse_key(info, &key);
1329 if (err)
1330 return err;
41ade00f 1331
b9454e83 1332 if (key.idx < 0)
41ade00f
JB
1333 return -EINVAL;
1334
b9454e83
JB
1335 /* only support setting default key */
1336 if (!key.def && !key.defmgmt)
41ade00f
JB
1337 return -EINVAL;
1338
3b85875a
JB
1339 rtnl_lock();
1340
463d0183 1341 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
41ade00f 1342 if (err)
3b85875a 1343 goto unlock_rtnl;
41ade00f 1344
b9454e83 1345 if (key.def)
79c97e97 1346 func = rdev->ops->set_default_key;
3cfcf6ac 1347 else
79c97e97 1348 func = rdev->ops->set_default_mgmt_key;
3cfcf6ac
JM
1349
1350 if (!func) {
41ade00f
JB
1351 err = -EOPNOTSUPP;
1352 goto out;
1353 }
1354
fffd0934
JB
1355 wdev_lock(dev->ieee80211_ptr);
1356 err = nl80211_key_allowed(dev->ieee80211_ptr);
1357 if (!err)
1358 err = func(&rdev->wiphy, dev, key.idx);
1359
3d23e349 1360#ifdef CONFIG_CFG80211_WEXT
08645126 1361 if (!err) {
79c97e97 1362 if (func == rdev->ops->set_default_key)
b9454e83 1363 dev->ieee80211_ptr->wext.default_key = key.idx;
08645126 1364 else
b9454e83 1365 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126
JB
1366 }
1367#endif
fffd0934 1368 wdev_unlock(dev->ieee80211_ptr);
41ade00f
JB
1369
1370 out:
79c97e97 1371 cfg80211_unlock_rdev(rdev);
41ade00f 1372 dev_put(dev);
3b85875a
JB
1373
1374 unlock_rtnl:
1375 rtnl_unlock();
1376
41ade00f
JB
1377 return err;
1378}
1379
1380static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1381{
79c97e97 1382 struct cfg80211_registered_device *rdev;
fffd0934 1383 int err;
41ade00f 1384 struct net_device *dev;
b9454e83 1385 struct key_parse key;
41ade00f
JB
1386 u8 *mac_addr = NULL;
1387
b9454e83
JB
1388 err = nl80211_parse_key(info, &key);
1389 if (err)
1390 return err;
41ade00f 1391
b9454e83 1392 if (!key.p.key)
41ade00f
JB
1393 return -EINVAL;
1394
41ade00f
JB
1395 if (info->attrs[NL80211_ATTR_MAC])
1396 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1397
3b85875a
JB
1398 rtnl_lock();
1399
463d0183 1400 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
41ade00f 1401 if (err)
3b85875a 1402 goto unlock_rtnl;
41ade00f 1403
fffd0934
JB
1404 if (!rdev->ops->add_key) {
1405 err = -EOPNOTSUPP;
25e47c18
JB
1406 goto out;
1407 }
1408
fffd0934
JB
1409 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) {
1410 err = -EINVAL;
41ade00f
JB
1411 goto out;
1412 }
1413
fffd0934
JB
1414 wdev_lock(dev->ieee80211_ptr);
1415 err = nl80211_key_allowed(dev->ieee80211_ptr);
1416 if (!err)
1417 err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx,
1418 mac_addr, &key.p);
1419 wdev_unlock(dev->ieee80211_ptr);
41ade00f
JB
1420
1421 out:
79c97e97 1422 cfg80211_unlock_rdev(rdev);
41ade00f 1423 dev_put(dev);
3b85875a
JB
1424 unlock_rtnl:
1425 rtnl_unlock();
1426
41ade00f
JB
1427 return err;
1428}
1429
1430static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1431{
79c97e97 1432 struct cfg80211_registered_device *rdev;
41ade00f
JB
1433 int err;
1434 struct net_device *dev;
41ade00f 1435 u8 *mac_addr = NULL;
b9454e83 1436 struct key_parse key;
41ade00f 1437
b9454e83
JB
1438 err = nl80211_parse_key(info, &key);
1439 if (err)
1440 return err;
41ade00f
JB
1441
1442 if (info->attrs[NL80211_ATTR_MAC])
1443 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1444
3b85875a
JB
1445 rtnl_lock();
1446
463d0183 1447 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
41ade00f 1448 if (err)
3b85875a 1449 goto unlock_rtnl;
41ade00f 1450
79c97e97 1451 if (!rdev->ops->del_key) {
41ade00f
JB
1452 err = -EOPNOTSUPP;
1453 goto out;
1454 }
1455
fffd0934
JB
1456 wdev_lock(dev->ieee80211_ptr);
1457 err = nl80211_key_allowed(dev->ieee80211_ptr);
1458 if (!err)
1459 err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr);
41ade00f 1460
3d23e349 1461#ifdef CONFIG_CFG80211_WEXT
08645126 1462 if (!err) {
b9454e83 1463 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 1464 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 1465 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
1466 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
1467 }
1468#endif
fffd0934 1469 wdev_unlock(dev->ieee80211_ptr);
08645126 1470
41ade00f 1471 out:
79c97e97 1472 cfg80211_unlock_rdev(rdev);
41ade00f 1473 dev_put(dev);
3b85875a
JB
1474
1475 unlock_rtnl:
1476 rtnl_unlock();
1477
41ade00f
JB
1478 return err;
1479}
1480
ed1b6cc7
JB
1481static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1482{
1483 int (*call)(struct wiphy *wiphy, struct net_device *dev,
1484 struct beacon_parameters *info);
79c97e97 1485 struct cfg80211_registered_device *rdev;
ed1b6cc7
JB
1486 int err;
1487 struct net_device *dev;
1488 struct beacon_parameters params;
1489 int haveinfo = 0;
1490
f4a11bb0
JB
1491 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
1492 return -EINVAL;
1493
3b85875a
JB
1494 rtnl_lock();
1495
463d0183 1496 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
ed1b6cc7 1497 if (err)
3b85875a 1498 goto unlock_rtnl;
ed1b6cc7 1499
eec60b03
JM
1500 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
1501 err = -EOPNOTSUPP;
1502 goto out;
1503 }
1504
ed1b6cc7
JB
1505 switch (info->genlhdr->cmd) {
1506 case NL80211_CMD_NEW_BEACON:
1507 /* these are required for NEW_BEACON */
1508 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
1509 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
1510 !info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1511 err = -EINVAL;
1512 goto out;
1513 }
1514
79c97e97 1515 call = rdev->ops->add_beacon;
ed1b6cc7
JB
1516 break;
1517 case NL80211_CMD_SET_BEACON:
79c97e97 1518 call = rdev->ops->set_beacon;
ed1b6cc7
JB
1519 break;
1520 default:
1521 WARN_ON(1);
1522 err = -EOPNOTSUPP;
1523 goto out;
1524 }
1525
1526 if (!call) {
1527 err = -EOPNOTSUPP;
1528 goto out;
1529 }
1530
1531 memset(&params, 0, sizeof(params));
1532
1533 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
1534 params.interval =
1535 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
1536 haveinfo = 1;
1537 }
1538
1539 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
1540 params.dtim_period =
1541 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
1542 haveinfo = 1;
1543 }
1544
1545 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
1546 params.head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1547 params.head_len =
1548 nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
1549 haveinfo = 1;
1550 }
1551
1552 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
1553 params.tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
1554 params.tail_len =
1555 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
1556 haveinfo = 1;
1557 }
1558
1559 if (!haveinfo) {
1560 err = -EINVAL;
1561 goto out;
1562 }
1563
79c97e97 1564 err = call(&rdev->wiphy, dev, &params);
ed1b6cc7
JB
1565
1566 out:
79c97e97 1567 cfg80211_unlock_rdev(rdev);
ed1b6cc7 1568 dev_put(dev);
3b85875a
JB
1569 unlock_rtnl:
1570 rtnl_unlock();
1571
ed1b6cc7
JB
1572 return err;
1573}
1574
1575static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1576{
79c97e97 1577 struct cfg80211_registered_device *rdev;
ed1b6cc7
JB
1578 int err;
1579 struct net_device *dev;
1580
3b85875a
JB
1581 rtnl_lock();
1582
463d0183 1583 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
ed1b6cc7 1584 if (err)
3b85875a 1585 goto unlock_rtnl;
ed1b6cc7 1586
79c97e97 1587 if (!rdev->ops->del_beacon) {
ed1b6cc7
JB
1588 err = -EOPNOTSUPP;
1589 goto out;
1590 }
1591
eec60b03
JM
1592 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
1593 err = -EOPNOTSUPP;
1594 goto out;
1595 }
79c97e97 1596 err = rdev->ops->del_beacon(&rdev->wiphy, dev);
ed1b6cc7
JB
1597
1598 out:
79c97e97 1599 cfg80211_unlock_rdev(rdev);
ed1b6cc7 1600 dev_put(dev);
3b85875a
JB
1601 unlock_rtnl:
1602 rtnl_unlock();
1603
ed1b6cc7
JB
1604 return err;
1605}
1606
5727ef1b
JB
1607static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
1608 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
1609 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
1610 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 1611 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
5727ef1b
JB
1612};
1613
eccb8e8f
JB
1614static int parse_station_flags(struct genl_info *info,
1615 struct station_parameters *params)
5727ef1b
JB
1616{
1617 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 1618 struct nlattr *nla;
5727ef1b
JB
1619 int flag;
1620
eccb8e8f
JB
1621 /*
1622 * Try parsing the new attribute first so userspace
1623 * can specify both for older kernels.
1624 */
1625 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
1626 if (nla) {
1627 struct nl80211_sta_flag_update *sta_flags;
1628
1629 sta_flags = nla_data(nla);
1630 params->sta_flags_mask = sta_flags->mask;
1631 params->sta_flags_set = sta_flags->set;
1632 if ((params->sta_flags_mask |
1633 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
1634 return -EINVAL;
1635 return 0;
1636 }
1637
1638 /* if present, parse the old attribute */
5727ef1b 1639
eccb8e8f 1640 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
1641 if (!nla)
1642 return 0;
1643
1644 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
1645 nla, sta_flags_policy))
1646 return -EINVAL;
1647
eccb8e8f
JB
1648 params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
1649 params->sta_flags_mask &= ~1;
5727ef1b
JB
1650
1651 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
1652 if (flags[flag])
eccb8e8f 1653 params->sta_flags_set |= (1<<flag);
5727ef1b
JB
1654
1655 return 0;
1656}
1657
fd5b74dc
JB
1658static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
1659 int flags, struct net_device *dev,
98b62183 1660 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
1661{
1662 void *hdr;
420e7fab
HR
1663 struct nlattr *sinfoattr, *txrate;
1664 u16 bitrate;
fd5b74dc
JB
1665
1666 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
1667 if (!hdr)
1668 return -1;
1669
1670 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1671 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
1672
f5ea9120
JB
1673 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, sinfo->generation);
1674
2ec600d6
LCC
1675 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
1676 if (!sinfoattr)
fd5b74dc 1677 goto nla_put_failure;
2ec600d6
LCC
1678 if (sinfo->filled & STATION_INFO_INACTIVE_TIME)
1679 NLA_PUT_U32(msg, NL80211_STA_INFO_INACTIVE_TIME,
1680 sinfo->inactive_time);
1681 if (sinfo->filled & STATION_INFO_RX_BYTES)
1682 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_BYTES,
1683 sinfo->rx_bytes);
1684 if (sinfo->filled & STATION_INFO_TX_BYTES)
1685 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_BYTES,
1686 sinfo->tx_bytes);
1687 if (sinfo->filled & STATION_INFO_LLID)
1688 NLA_PUT_U16(msg, NL80211_STA_INFO_LLID,
1689 sinfo->llid);
1690 if (sinfo->filled & STATION_INFO_PLID)
1691 NLA_PUT_U16(msg, NL80211_STA_INFO_PLID,
1692 sinfo->plid);
1693 if (sinfo->filled & STATION_INFO_PLINK_STATE)
1694 NLA_PUT_U8(msg, NL80211_STA_INFO_PLINK_STATE,
1695 sinfo->plink_state);
420e7fab
HR
1696 if (sinfo->filled & STATION_INFO_SIGNAL)
1697 NLA_PUT_U8(msg, NL80211_STA_INFO_SIGNAL,
1698 sinfo->signal);
1699 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
1700 txrate = nla_nest_start(msg, NL80211_STA_INFO_TX_BITRATE);
1701 if (!txrate)
1702 goto nla_put_failure;
1703
254416aa
JL
1704 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
1705 bitrate = cfg80211_calculate_bitrate(&sinfo->txrate);
420e7fab
HR
1706 if (bitrate > 0)
1707 NLA_PUT_U16(msg, NL80211_RATE_INFO_BITRATE, bitrate);
2ec600d6 1708
420e7fab
HR
1709 if (sinfo->txrate.flags & RATE_INFO_FLAGS_MCS)
1710 NLA_PUT_U8(msg, NL80211_RATE_INFO_MCS,
1711 sinfo->txrate.mcs);
1712 if (sinfo->txrate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH)
1713 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_40_MHZ_WIDTH);
1714 if (sinfo->txrate.flags & RATE_INFO_FLAGS_SHORT_GI)
1715 NLA_PUT_FLAG(msg, NL80211_RATE_INFO_SHORT_GI);
1716
1717 nla_nest_end(msg, txrate);
1718 }
98c8a60a
JM
1719 if (sinfo->filled & STATION_INFO_RX_PACKETS)
1720 NLA_PUT_U32(msg, NL80211_STA_INFO_RX_PACKETS,
1721 sinfo->rx_packets);
1722 if (sinfo->filled & STATION_INFO_TX_PACKETS)
1723 NLA_PUT_U32(msg, NL80211_STA_INFO_TX_PACKETS,
1724 sinfo->tx_packets);
2ec600d6 1725 nla_nest_end(msg, sinfoattr);
fd5b74dc
JB
1726
1727 return genlmsg_end(msg, hdr);
1728
1729 nla_put_failure:
bc3ed28c
TG
1730 genlmsg_cancel(msg, hdr);
1731 return -EMSGSIZE;
fd5b74dc
JB
1732}
1733
2ec600d6 1734static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 1735 struct netlink_callback *cb)
2ec600d6 1736{
2ec600d6
LCC
1737 struct station_info sinfo;
1738 struct cfg80211_registered_device *dev;
bba95fef 1739 struct net_device *netdev;
2ec600d6 1740 u8 mac_addr[ETH_ALEN];
bba95fef
JB
1741 int ifidx = cb->args[0];
1742 int sta_idx = cb->args[1];
2ec600d6 1743 int err;
2ec600d6 1744
a043897a
HS
1745 if (!ifidx)
1746 ifidx = nl80211_get_ifidx(cb);
1747 if (ifidx < 0)
1748 return ifidx;
2ec600d6 1749
3b85875a
JB
1750 rtnl_lock();
1751
463d0183 1752 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3b85875a
JB
1753 if (!netdev) {
1754 err = -ENODEV;
1755 goto out_rtnl;
1756 }
2ec600d6 1757
463d0183 1758 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
bba95fef
JB
1759 if (IS_ERR(dev)) {
1760 err = PTR_ERR(dev);
3b85875a 1761 goto out_rtnl;
bba95fef
JB
1762 }
1763
1764 if (!dev->ops->dump_station) {
eec60b03 1765 err = -EOPNOTSUPP;
bba95fef
JB
1766 goto out_err;
1767 }
1768
bba95fef
JB
1769 while (1) {
1770 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
1771 mac_addr, &sinfo);
1772 if (err == -ENOENT)
1773 break;
1774 if (err)
3b85875a 1775 goto out_err;
bba95fef
JB
1776
1777 if (nl80211_send_station(skb,
1778 NETLINK_CB(cb->skb).pid,
1779 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1780 netdev, mac_addr,
1781 &sinfo) < 0)
1782 goto out;
1783
1784 sta_idx++;
1785 }
1786
1787
1788 out:
1789 cb->args[1] = sta_idx;
1790 err = skb->len;
bba95fef 1791 out_err:
4d0c8aea 1792 cfg80211_unlock_rdev(dev);
3b85875a
JB
1793 out_rtnl:
1794 rtnl_unlock();
bba95fef
JB
1795
1796 return err;
2ec600d6 1797}
fd5b74dc 1798
5727ef1b
JB
1799static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1800{
79c97e97 1801 struct cfg80211_registered_device *rdev;
fd5b74dc
JB
1802 int err;
1803 struct net_device *dev;
2ec600d6 1804 struct station_info sinfo;
fd5b74dc
JB
1805 struct sk_buff *msg;
1806 u8 *mac_addr = NULL;
1807
2ec600d6 1808 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc
JB
1809
1810 if (!info->attrs[NL80211_ATTR_MAC])
1811 return -EINVAL;
1812
1813 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1814
3b85875a
JB
1815 rtnl_lock();
1816
463d0183 1817 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
fd5b74dc 1818 if (err)
3b85875a 1819 goto out_rtnl;
fd5b74dc 1820
79c97e97 1821 if (!rdev->ops->get_station) {
fd5b74dc
JB
1822 err = -EOPNOTSUPP;
1823 goto out;
1824 }
1825
79c97e97 1826 err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo);
2ec600d6
LCC
1827 if (err)
1828 goto out;
1829
fd2120ca 1830 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
fd5b74dc
JB
1831 if (!msg)
1832 goto out;
1833
1834 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
2ec600d6 1835 dev, mac_addr, &sinfo) < 0)
fd5b74dc
JB
1836 goto out_free;
1837
134e6375 1838 err = genlmsg_reply(msg, info);
fd5b74dc
JB
1839 goto out;
1840
1841 out_free:
1842 nlmsg_free(msg);
fd5b74dc 1843 out:
79c97e97 1844 cfg80211_unlock_rdev(rdev);
fd5b74dc 1845 dev_put(dev);
3b85875a
JB
1846 out_rtnl:
1847 rtnl_unlock();
1848
fd5b74dc 1849 return err;
5727ef1b
JB
1850}
1851
1852/*
c258d2de 1853 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 1854 */
463d0183 1855static int get_vlan(struct genl_info *info,
5727ef1b
JB
1856 struct cfg80211_registered_device *rdev,
1857 struct net_device **vlan)
1858{
463d0183 1859 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
5727ef1b
JB
1860 *vlan = NULL;
1861
1862 if (vlanattr) {
463d0183
JB
1863 *vlan = dev_get_by_index(genl_info_net(info),
1864 nla_get_u32(vlanattr));
5727ef1b
JB
1865 if (!*vlan)
1866 return -ENODEV;
1867 if (!(*vlan)->ieee80211_ptr)
1868 return -EINVAL;
1869 if ((*vlan)->ieee80211_ptr->wiphy != &rdev->wiphy)
1870 return -EINVAL;
c258d2de
FF
1871 if (!netif_running(*vlan))
1872 return -ENETDOWN;
5727ef1b
JB
1873 }
1874 return 0;
1875}
1876
1877static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1878{
79c97e97 1879 struct cfg80211_registered_device *rdev;
5727ef1b
JB
1880 int err;
1881 struct net_device *dev;
1882 struct station_parameters params;
1883 u8 *mac_addr = NULL;
1884
1885 memset(&params, 0, sizeof(params));
1886
1887 params.listen_interval = -1;
1888
1889 if (info->attrs[NL80211_ATTR_STA_AID])
1890 return -EINVAL;
1891
1892 if (!info->attrs[NL80211_ATTR_MAC])
1893 return -EINVAL;
1894
1895 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1896
1897 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
1898 params.supported_rates =
1899 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1900 params.supported_rates_len =
1901 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
1902 }
1903
1904 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
1905 params.listen_interval =
1906 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1907
36aedc90
JM
1908 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1909 params.ht_capa =
1910 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1911
eccb8e8f 1912 if (parse_station_flags(info, &params))
5727ef1b
JB
1913 return -EINVAL;
1914
2ec600d6
LCC
1915 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
1916 params.plink_action =
1917 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
1918
3b85875a
JB
1919 rtnl_lock();
1920
463d0183 1921 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
5727ef1b 1922 if (err)
3b85875a 1923 goto out_rtnl;
5727ef1b 1924
463d0183 1925 err = get_vlan(info, rdev, &params.vlan);
a97f4424 1926 if (err)
034d655e 1927 goto out;
a97f4424
JB
1928
1929 /* validate settings */
1930 err = 0;
1931
1932 switch (dev->ieee80211_ptr->iftype) {
1933 case NL80211_IFTYPE_AP:
1934 case NL80211_IFTYPE_AP_VLAN:
1935 /* disallow mesh-specific things */
1936 if (params.plink_action)
1937 err = -EINVAL;
1938 break;
1939 case NL80211_IFTYPE_STATION:
1940 /* disallow everything but AUTHORIZED flag */
1941 if (params.plink_action)
1942 err = -EINVAL;
1943 if (params.vlan)
1944 err = -EINVAL;
1945 if (params.supported_rates)
1946 err = -EINVAL;
1947 if (params.ht_capa)
1948 err = -EINVAL;
1949 if (params.listen_interval >= 0)
1950 err = -EINVAL;
1951 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
1952 err = -EINVAL;
1953 break;
1954 case NL80211_IFTYPE_MESH_POINT:
1955 /* disallow things mesh doesn't support */
1956 if (params.vlan)
1957 err = -EINVAL;
1958 if (params.ht_capa)
1959 err = -EINVAL;
1960 if (params.listen_interval >= 0)
1961 err = -EINVAL;
1962 if (params.supported_rates)
1963 err = -EINVAL;
1964 if (params.sta_flags_mask)
1965 err = -EINVAL;
1966 break;
1967 default:
1968 err = -EINVAL;
034d655e
JB
1969 }
1970
5727ef1b
JB
1971 if (err)
1972 goto out;
1973
79c97e97 1974 if (!rdev->ops->change_station) {
5727ef1b
JB
1975 err = -EOPNOTSUPP;
1976 goto out;
1977 }
1978
79c97e97 1979 err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, &params);
5727ef1b
JB
1980
1981 out:
1982 if (params.vlan)
1983 dev_put(params.vlan);
79c97e97 1984 cfg80211_unlock_rdev(rdev);
5727ef1b 1985 dev_put(dev);
3b85875a
JB
1986 out_rtnl:
1987 rtnl_unlock();
1988
5727ef1b
JB
1989 return err;
1990}
1991
1992static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1993{
79c97e97 1994 struct cfg80211_registered_device *rdev;
5727ef1b
JB
1995 int err;
1996 struct net_device *dev;
1997 struct station_parameters params;
1998 u8 *mac_addr = NULL;
1999
2000 memset(&params, 0, sizeof(params));
2001
2002 if (!info->attrs[NL80211_ATTR_MAC])
2003 return -EINVAL;
2004
5727ef1b
JB
2005 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
2006 return -EINVAL;
2007
2008 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
2009 return -EINVAL;
2010
2011 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2012 params.supported_rates =
2013 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
2014 params.supported_rates_len =
2015 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
2016 params.listen_interval =
2017 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 2018
a97f4424
JB
2019 if (info->attrs[NL80211_ATTR_STA_AID]) {
2020 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
2021 if (!params.aid || params.aid > IEEE80211_MAX_AID)
2022 return -EINVAL;
2023 }
51b50fbe 2024
36aedc90
JM
2025 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
2026 params.ht_capa =
2027 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 2028
eccb8e8f 2029 if (parse_station_flags(info, &params))
5727ef1b
JB
2030 return -EINVAL;
2031
3b85875a
JB
2032 rtnl_lock();
2033
463d0183 2034 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
5727ef1b 2035 if (err)
3b85875a 2036 goto out_rtnl;
5727ef1b 2037
463d0183 2038 err = get_vlan(info, rdev, &params.vlan);
a97f4424 2039 if (err)
e80cf853 2040 goto out;
a97f4424
JB
2041
2042 /* validate settings */
2043 err = 0;
2044
2045 switch (dev->ieee80211_ptr->iftype) {
2046 case NL80211_IFTYPE_AP:
2047 case NL80211_IFTYPE_AP_VLAN:
2048 /* all ok but must have AID */
2049 if (!params.aid)
2050 err = -EINVAL;
2051 break;
2052 case NL80211_IFTYPE_MESH_POINT:
2053 /* disallow things mesh doesn't support */
2054 if (params.vlan)
2055 err = -EINVAL;
2056 if (params.aid)
2057 err = -EINVAL;
2058 if (params.ht_capa)
2059 err = -EINVAL;
2060 if (params.listen_interval >= 0)
2061 err = -EINVAL;
2062 if (params.supported_rates)
2063 err = -EINVAL;
2064 if (params.sta_flags_mask)
2065 err = -EINVAL;
2066 break;
2067 default:
2068 err = -EINVAL;
e80cf853
JB
2069 }
2070
5727ef1b
JB
2071 if (err)
2072 goto out;
2073
79c97e97 2074 if (!rdev->ops->add_station) {
5727ef1b
JB
2075 err = -EOPNOTSUPP;
2076 goto out;
2077 }
2078
35a8efe1
JM
2079 if (!netif_running(dev)) {
2080 err = -ENETDOWN;
2081 goto out;
2082 }
2083
79c97e97 2084 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
5727ef1b
JB
2085
2086 out:
2087 if (params.vlan)
2088 dev_put(params.vlan);
79c97e97 2089 cfg80211_unlock_rdev(rdev);
5727ef1b 2090 dev_put(dev);
3b85875a
JB
2091 out_rtnl:
2092 rtnl_unlock();
2093
5727ef1b
JB
2094 return err;
2095}
2096
2097static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
2098{
79c97e97 2099 struct cfg80211_registered_device *rdev;
5727ef1b
JB
2100 int err;
2101 struct net_device *dev;
2102 u8 *mac_addr = NULL;
2103
2104 if (info->attrs[NL80211_ATTR_MAC])
2105 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2106
3b85875a
JB
2107 rtnl_lock();
2108
463d0183 2109 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
5727ef1b 2110 if (err)
3b85875a 2111 goto out_rtnl;
5727ef1b 2112
e80cf853 2113 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
155cc9e4
AY
2114 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
2115 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
e80cf853
JB
2116 err = -EINVAL;
2117 goto out;
2118 }
2119
79c97e97 2120 if (!rdev->ops->del_station) {
5727ef1b
JB
2121 err = -EOPNOTSUPP;
2122 goto out;
2123 }
2124
79c97e97 2125 err = rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
5727ef1b
JB
2126
2127 out:
79c97e97 2128 cfg80211_unlock_rdev(rdev);
5727ef1b 2129 dev_put(dev);
3b85875a
JB
2130 out_rtnl:
2131 rtnl_unlock();
2132
5727ef1b
JB
2133 return err;
2134}
2135
2ec600d6
LCC
2136static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
2137 int flags, struct net_device *dev,
2138 u8 *dst, u8 *next_hop,
2139 struct mpath_info *pinfo)
2140{
2141 void *hdr;
2142 struct nlattr *pinfoattr;
2143
2144 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
2145 if (!hdr)
2146 return -1;
2147
2148 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
2149 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
2150 NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
2151
f5ea9120
JB
2152 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, pinfo->generation);
2153
2ec600d6
LCC
2154 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
2155 if (!pinfoattr)
2156 goto nla_put_failure;
2157 if (pinfo->filled & MPATH_INFO_FRAME_QLEN)
2158 NLA_PUT_U32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
2159 pinfo->frame_qlen);
d19b3bf6
RP
2160 if (pinfo->filled & MPATH_INFO_SN)
2161 NLA_PUT_U32(msg, NL80211_MPATH_INFO_SN,
2162 pinfo->sn);
2ec600d6
LCC
2163 if (pinfo->filled & MPATH_INFO_METRIC)
2164 NLA_PUT_U32(msg, NL80211_MPATH_INFO_METRIC,
2165 pinfo->metric);
2166 if (pinfo->filled & MPATH_INFO_EXPTIME)
2167 NLA_PUT_U32(msg, NL80211_MPATH_INFO_EXPTIME,
2168 pinfo->exptime);
2169 if (pinfo->filled & MPATH_INFO_FLAGS)
2170 NLA_PUT_U8(msg, NL80211_MPATH_INFO_FLAGS,
2171 pinfo->flags);
2172 if (pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT)
2173 NLA_PUT_U32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
2174 pinfo->discovery_timeout);
2175 if (pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES)
2176 NLA_PUT_U8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
2177 pinfo->discovery_retries);
2178
2179 nla_nest_end(msg, pinfoattr);
2180
2181 return genlmsg_end(msg, hdr);
2182
2183 nla_put_failure:
bc3ed28c
TG
2184 genlmsg_cancel(msg, hdr);
2185 return -EMSGSIZE;
2ec600d6
LCC
2186}
2187
2188static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 2189 struct netlink_callback *cb)
2ec600d6 2190{
2ec600d6
LCC
2191 struct mpath_info pinfo;
2192 struct cfg80211_registered_device *dev;
bba95fef 2193 struct net_device *netdev;
2ec600d6
LCC
2194 u8 dst[ETH_ALEN];
2195 u8 next_hop[ETH_ALEN];
bba95fef
JB
2196 int ifidx = cb->args[0];
2197 int path_idx = cb->args[1];
2ec600d6 2198 int err;
2ec600d6 2199
a043897a
HS
2200 if (!ifidx)
2201 ifidx = nl80211_get_ifidx(cb);
2202 if (ifidx < 0)
2203 return ifidx;
bba95fef 2204
3b85875a
JB
2205 rtnl_lock();
2206
463d0183 2207 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3b85875a
JB
2208 if (!netdev) {
2209 err = -ENODEV;
2210 goto out_rtnl;
2211 }
bba95fef 2212
463d0183 2213 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
bba95fef
JB
2214 if (IS_ERR(dev)) {
2215 err = PTR_ERR(dev);
3b85875a 2216 goto out_rtnl;
bba95fef
JB
2217 }
2218
2219 if (!dev->ops->dump_mpath) {
eec60b03 2220 err = -EOPNOTSUPP;
bba95fef
JB
2221 goto out_err;
2222 }
2223
eec60b03
JM
2224 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2225 err = -EOPNOTSUPP;
0448b5fc 2226 goto out_err;
eec60b03
JM
2227 }
2228
bba95fef
JB
2229 while (1) {
2230 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
2231 dst, next_hop, &pinfo);
2232 if (err == -ENOENT)
2ec600d6 2233 break;
bba95fef 2234 if (err)
3b85875a 2235 goto out_err;
2ec600d6 2236
bba95fef
JB
2237 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
2238 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2239 netdev, dst, next_hop,
2240 &pinfo) < 0)
2241 goto out;
2ec600d6 2242
bba95fef 2243 path_idx++;
2ec600d6 2244 }
2ec600d6 2245
2ec600d6 2246
bba95fef
JB
2247 out:
2248 cb->args[1] = path_idx;
2249 err = skb->len;
bba95fef 2250 out_err:
4d0c8aea 2251 cfg80211_unlock_rdev(dev);
3b85875a
JB
2252 out_rtnl:
2253 rtnl_unlock();
bba95fef
JB
2254
2255 return err;
2ec600d6
LCC
2256}
2257
2258static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2259{
79c97e97 2260 struct cfg80211_registered_device *rdev;
2ec600d6
LCC
2261 int err;
2262 struct net_device *dev;
2263 struct mpath_info pinfo;
2264 struct sk_buff *msg;
2265 u8 *dst = NULL;
2266 u8 next_hop[ETH_ALEN];
2267
2268 memset(&pinfo, 0, sizeof(pinfo));
2269
2270 if (!info->attrs[NL80211_ATTR_MAC])
2271 return -EINVAL;
2272
2273 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2274
3b85875a
JB
2275 rtnl_lock();
2276
463d0183 2277 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2ec600d6 2278 if (err)
3b85875a 2279 goto out_rtnl;
2ec600d6 2280
79c97e97 2281 if (!rdev->ops->get_mpath) {
2ec600d6
LCC
2282 err = -EOPNOTSUPP;
2283 goto out;
2284 }
2285
eec60b03
JM
2286 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2287 err = -EOPNOTSUPP;
2288 goto out;
2289 }
2290
79c97e97 2291 err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo);
2ec600d6
LCC
2292 if (err)
2293 goto out;
2294
fd2120ca 2295 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6
LCC
2296 if (!msg)
2297 goto out;
2298
2299 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
2300 dev, dst, next_hop, &pinfo) < 0)
2301 goto out_free;
2302
134e6375 2303 err = genlmsg_reply(msg, info);
2ec600d6
LCC
2304 goto out;
2305
2306 out_free:
2307 nlmsg_free(msg);
2ec600d6 2308 out:
79c97e97 2309 cfg80211_unlock_rdev(rdev);
2ec600d6 2310 dev_put(dev);
3b85875a
JB
2311 out_rtnl:
2312 rtnl_unlock();
2313
2ec600d6
LCC
2314 return err;
2315}
2316
2317static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2318{
79c97e97 2319 struct cfg80211_registered_device *rdev;
2ec600d6
LCC
2320 int err;
2321 struct net_device *dev;
2322 u8 *dst = NULL;
2323 u8 *next_hop = NULL;
2324
2325 if (!info->attrs[NL80211_ATTR_MAC])
2326 return -EINVAL;
2327
2328 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
2329 return -EINVAL;
2330
2331 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2332 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
2333
3b85875a
JB
2334 rtnl_lock();
2335
463d0183 2336 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2ec600d6 2337 if (err)
3b85875a 2338 goto out_rtnl;
2ec600d6 2339
79c97e97 2340 if (!rdev->ops->change_mpath) {
2ec600d6
LCC
2341 err = -EOPNOTSUPP;
2342 goto out;
2343 }
2344
eec60b03
JM
2345 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2346 err = -EOPNOTSUPP;
2347 goto out;
2348 }
2349
35a8efe1
JM
2350 if (!netif_running(dev)) {
2351 err = -ENETDOWN;
2352 goto out;
2353 }
2354
79c97e97 2355 err = rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
2ec600d6
LCC
2356
2357 out:
79c97e97 2358 cfg80211_unlock_rdev(rdev);
2ec600d6 2359 dev_put(dev);
3b85875a
JB
2360 out_rtnl:
2361 rtnl_unlock();
2362
2ec600d6
LCC
2363 return err;
2364}
2365static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2366{
79c97e97 2367 struct cfg80211_registered_device *rdev;
2ec600d6
LCC
2368 int err;
2369 struct net_device *dev;
2370 u8 *dst = NULL;
2371 u8 *next_hop = NULL;
2372
2373 if (!info->attrs[NL80211_ATTR_MAC])
2374 return -EINVAL;
2375
2376 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
2377 return -EINVAL;
2378
2379 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2380 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
2381
3b85875a
JB
2382 rtnl_lock();
2383
463d0183 2384 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2ec600d6 2385 if (err)
3b85875a 2386 goto out_rtnl;
2ec600d6 2387
79c97e97 2388 if (!rdev->ops->add_mpath) {
2ec600d6
LCC
2389 err = -EOPNOTSUPP;
2390 goto out;
2391 }
2392
eec60b03
JM
2393 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
2394 err = -EOPNOTSUPP;
2395 goto out;
2396 }
2397
35a8efe1
JM
2398 if (!netif_running(dev)) {
2399 err = -ENETDOWN;
2400 goto out;
2401 }
2402
79c97e97 2403 err = rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
2ec600d6
LCC
2404
2405 out:
79c97e97 2406 cfg80211_unlock_rdev(rdev);
2ec600d6 2407 dev_put(dev);
3b85875a
JB
2408 out_rtnl:
2409 rtnl_unlock();
2410
2ec600d6
LCC
2411 return err;
2412}
2413
2414static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
2415{
79c97e97 2416 struct cfg80211_registered_device *rdev;
2ec600d6
LCC
2417 int err;
2418 struct net_device *dev;
2419 u8 *dst = NULL;
2420
2421 if (info->attrs[NL80211_ATTR_MAC])
2422 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
2423
3b85875a
JB
2424 rtnl_lock();
2425
463d0183 2426 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2ec600d6 2427 if (err)
3b85875a 2428 goto out_rtnl;
2ec600d6 2429
79c97e97 2430 if (!rdev->ops->del_mpath) {
2ec600d6
LCC
2431 err = -EOPNOTSUPP;
2432 goto out;
2433 }
2434
79c97e97 2435 err = rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
2ec600d6
LCC
2436
2437 out:
79c97e97 2438 cfg80211_unlock_rdev(rdev);
2ec600d6 2439 dev_put(dev);
3b85875a
JB
2440 out_rtnl:
2441 rtnl_unlock();
2442
2ec600d6
LCC
2443 return err;
2444}
2445
9f1ba906
JM
2446static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2447{
79c97e97 2448 struct cfg80211_registered_device *rdev;
9f1ba906
JM
2449 int err;
2450 struct net_device *dev;
2451 struct bss_parameters params;
2452
2453 memset(&params, 0, sizeof(params));
2454 /* default to not changing parameters */
2455 params.use_cts_prot = -1;
2456 params.use_short_preamble = -1;
2457 params.use_short_slot_time = -1;
2458
2459 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
2460 params.use_cts_prot =
2461 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
2462 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
2463 params.use_short_preamble =
2464 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
2465 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
2466 params.use_short_slot_time =
2467 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
2468 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
2469 params.basic_rates =
2470 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
2471 params.basic_rates_len =
2472 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
2473 }
9f1ba906 2474
3b85875a
JB
2475 rtnl_lock();
2476
463d0183 2477 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
9f1ba906 2478 if (err)
3b85875a 2479 goto out_rtnl;
9f1ba906 2480
79c97e97 2481 if (!rdev->ops->change_bss) {
9f1ba906
JM
2482 err = -EOPNOTSUPP;
2483 goto out;
2484 }
2485
eec60b03
JM
2486 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP) {
2487 err = -EOPNOTSUPP;
2488 goto out;
2489 }
2490
79c97e97 2491 err = rdev->ops->change_bss(&rdev->wiphy, dev, &params);
9f1ba906
JM
2492
2493 out:
79c97e97 2494 cfg80211_unlock_rdev(rdev);
9f1ba906 2495 dev_put(dev);
3b85875a
JB
2496 out_rtnl:
2497 rtnl_unlock();
2498
9f1ba906
JM
2499 return err;
2500}
2501
b2e1b302
LR
2502static const struct nla_policy
2503 reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
2504 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
2505 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
2506 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
2507 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
2508 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
2509 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
2510};
2511
2512static int parse_reg_rule(struct nlattr *tb[],
2513 struct ieee80211_reg_rule *reg_rule)
2514{
2515 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
2516 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
2517
2518 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
2519 return -EINVAL;
2520 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
2521 return -EINVAL;
2522 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
2523 return -EINVAL;
2524 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
2525 return -EINVAL;
2526 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
2527 return -EINVAL;
2528
2529 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
2530
2531 freq_range->start_freq_khz =
2532 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
2533 freq_range->end_freq_khz =
2534 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
2535 freq_range->max_bandwidth_khz =
2536 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
2537
2538 power_rule->max_eirp =
2539 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
2540
2541 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
2542 power_rule->max_antenna_gain =
2543 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
2544
2545 return 0;
2546}
2547
2548static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
2549{
2550 int r;
2551 char *data = NULL;
2552
80778f18
LR
2553 /*
2554 * You should only get this when cfg80211 hasn't yet initialized
2555 * completely when built-in to the kernel right between the time
2556 * window between nl80211_init() and regulatory_init(), if that is
2557 * even possible.
2558 */
2559 mutex_lock(&cfg80211_mutex);
2560 if (unlikely(!cfg80211_regdomain)) {
fe33eb39
LR
2561 mutex_unlock(&cfg80211_mutex);
2562 return -EINPROGRESS;
80778f18 2563 }
fe33eb39 2564 mutex_unlock(&cfg80211_mutex);
80778f18 2565
fe33eb39
LR
2566 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
2567 return -EINVAL;
b2e1b302
LR
2568
2569 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
2570
fe33eb39
LR
2571 r = regulatory_hint_user(data);
2572
b2e1b302
LR
2573 return r;
2574}
2575
93da9cc1 2576static int nl80211_get_mesh_params(struct sk_buff *skb,
2577 struct genl_info *info)
2578{
79c97e97 2579 struct cfg80211_registered_device *rdev;
93da9cc1 2580 struct mesh_config cur_params;
2581 int err;
2582 struct net_device *dev;
2583 void *hdr;
2584 struct nlattr *pinfoattr;
2585 struct sk_buff *msg;
2586
3b85875a
JB
2587 rtnl_lock();
2588
93da9cc1 2589 /* Look up our device */
463d0183 2590 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
93da9cc1 2591 if (err)
3b85875a 2592 goto out_rtnl;
93da9cc1 2593
79c97e97 2594 if (!rdev->ops->get_mesh_params) {
f3f92586
JM
2595 err = -EOPNOTSUPP;
2596 goto out;
2597 }
2598
93da9cc1 2599 /* Get the mesh params */
79c97e97 2600 err = rdev->ops->get_mesh_params(&rdev->wiphy, dev, &cur_params);
93da9cc1 2601 if (err)
2602 goto out;
2603
2604 /* Draw up a netlink message to send back */
fd2120ca 2605 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
93da9cc1 2606 if (!msg) {
2607 err = -ENOBUFS;
2608 goto out;
2609 }
2610 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2611 NL80211_CMD_GET_MESH_PARAMS);
2612 if (!hdr)
2613 goto nla_put_failure;
2614 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS);
2615 if (!pinfoattr)
2616 goto nla_put_failure;
2617 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
2618 NLA_PUT_U16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
2619 cur_params.dot11MeshRetryTimeout);
2620 NLA_PUT_U16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
2621 cur_params.dot11MeshConfirmTimeout);
2622 NLA_PUT_U16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
2623 cur_params.dot11MeshHoldingTimeout);
2624 NLA_PUT_U16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
2625 cur_params.dot11MeshMaxPeerLinks);
2626 NLA_PUT_U8(msg, NL80211_MESHCONF_MAX_RETRIES,
2627 cur_params.dot11MeshMaxRetries);
2628 NLA_PUT_U8(msg, NL80211_MESHCONF_TTL,
2629 cur_params.dot11MeshTTL);
2630 NLA_PUT_U8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
2631 cur_params.auto_open_plinks);
2632 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
2633 cur_params.dot11MeshHWMPmaxPREQretries);
2634 NLA_PUT_U32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
2635 cur_params.path_refresh_time);
2636 NLA_PUT_U16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
2637 cur_params.min_discovery_timeout);
2638 NLA_PUT_U32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
2639 cur_params.dot11MeshHWMPactivePathTimeout);
2640 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
2641 cur_params.dot11MeshHWMPpreqMinInterval);
2642 NLA_PUT_U16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2643 cur_params.dot11MeshHWMPnetDiameterTraversalTime);
63c5723b
RP
2644 NLA_PUT_U8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
2645 cur_params.dot11MeshHWMPRootMode);
93da9cc1 2646 nla_nest_end(msg, pinfoattr);
2647 genlmsg_end(msg, hdr);
134e6375 2648 err = genlmsg_reply(msg, info);
93da9cc1 2649 goto out;
2650
3b85875a 2651 nla_put_failure:
93da9cc1 2652 genlmsg_cancel(msg, hdr);
2653 err = -EMSGSIZE;
3b85875a 2654 out:
93da9cc1 2655 /* Cleanup */
79c97e97 2656 cfg80211_unlock_rdev(rdev);
93da9cc1 2657 dev_put(dev);
3b85875a
JB
2658 out_rtnl:
2659 rtnl_unlock();
2660
93da9cc1 2661 return err;
2662}
2663
2664#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
2665do {\
2666 if (table[attr_num]) {\
2667 cfg.param = nla_fn(table[attr_num]); \
2668 mask |= (1 << (attr_num - 1)); \
2669 } \
2670} while (0);\
2671
2672static struct nla_policy
2673nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] __read_mostly = {
2674 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
2675 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
2676 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
2677 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
2678 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
2679 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
2680 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
2681
2682 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
2683 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
2684 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
2685 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
2686 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
2687 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
2688};
2689
2690static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2691{
2692 int err;
2693 u32 mask;
79c97e97 2694 struct cfg80211_registered_device *rdev;
93da9cc1 2695 struct net_device *dev;
2696 struct mesh_config cfg;
2697 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
2698 struct nlattr *parent_attr;
2699
2700 parent_attr = info->attrs[NL80211_ATTR_MESH_PARAMS];
2701 if (!parent_attr)
2702 return -EINVAL;
2703 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
2704 parent_attr, nl80211_meshconf_params_policy))
2705 return -EINVAL;
2706
3b85875a
JB
2707 rtnl_lock();
2708
463d0183 2709 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
93da9cc1 2710 if (err)
3b85875a 2711 goto out_rtnl;
93da9cc1 2712
79c97e97 2713 if (!rdev->ops->set_mesh_params) {
f3f92586
JM
2714 err = -EOPNOTSUPP;
2715 goto out;
2716 }
2717
93da9cc1 2718 /* This makes sure that there aren't more than 32 mesh config
2719 * parameters (otherwise our bitfield scheme would not work.) */
2720 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
2721
2722 /* Fill in the params struct */
2723 mask = 0;
2724 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
2725 mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
2726 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
2727 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16);
2728 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
2729 mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16);
2730 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
2731 mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16);
2732 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
2733 mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
2734 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
2735 mask, NL80211_MESHCONF_TTL, nla_get_u8);
2736 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
2737 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8);
2738 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
2739 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
2740 nla_get_u8);
2741 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
2742 mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32);
2743 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
2744 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
2745 nla_get_u16);
2746 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
2747 mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
2748 nla_get_u32);
2749 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
2750 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
2751 nla_get_u16);
2752 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
2753 dot11MeshHWMPnetDiameterTraversalTime,
2754 mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
2755 nla_get_u16);
63c5723b
RP
2756 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
2757 dot11MeshHWMPRootMode, mask,
2758 NL80211_MESHCONF_HWMP_ROOTMODE,
2759 nla_get_u8);
93da9cc1 2760
2761 /* Apply changes */
79c97e97 2762 err = rdev->ops->set_mesh_params(&rdev->wiphy, dev, &cfg, mask);
93da9cc1 2763
f3f92586 2764 out:
93da9cc1 2765 /* cleanup */
79c97e97 2766 cfg80211_unlock_rdev(rdev);
93da9cc1 2767 dev_put(dev);
3b85875a
JB
2768 out_rtnl:
2769 rtnl_unlock();
2770
93da9cc1 2771 return err;
2772}
2773
2774#undef FILL_IN_MESH_PARAM_IF_SET
2775
f130347c
LR
2776static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
2777{
2778 struct sk_buff *msg;
2779 void *hdr = NULL;
2780 struct nlattr *nl_reg_rules;
2781 unsigned int i;
2782 int err = -EINVAL;
2783
a1794390 2784 mutex_lock(&cfg80211_mutex);
f130347c
LR
2785
2786 if (!cfg80211_regdomain)
2787 goto out;
2788
fd2120ca 2789 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
f130347c
LR
2790 if (!msg) {
2791 err = -ENOBUFS;
2792 goto out;
2793 }
2794
2795 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2796 NL80211_CMD_GET_REG);
2797 if (!hdr)
2798 goto nla_put_failure;
2799
2800 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2,
2801 cfg80211_regdomain->alpha2);
2802
2803 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
2804 if (!nl_reg_rules)
2805 goto nla_put_failure;
2806
2807 for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) {
2808 struct nlattr *nl_reg_rule;
2809 const struct ieee80211_reg_rule *reg_rule;
2810 const struct ieee80211_freq_range *freq_range;
2811 const struct ieee80211_power_rule *power_rule;
2812
2813 reg_rule = &cfg80211_regdomain->reg_rules[i];
2814 freq_range = &reg_rule->freq_range;
2815 power_rule = &reg_rule->power_rule;
2816
2817 nl_reg_rule = nla_nest_start(msg, i);
2818 if (!nl_reg_rule)
2819 goto nla_put_failure;
2820
2821 NLA_PUT_U32(msg, NL80211_ATTR_REG_RULE_FLAGS,
2822 reg_rule->flags);
2823 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_START,
2824 freq_range->start_freq_khz);
2825 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_END,
2826 freq_range->end_freq_khz);
2827 NLA_PUT_U32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
2828 freq_range->max_bandwidth_khz);
2829 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
2830 power_rule->max_antenna_gain);
2831 NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
2832 power_rule->max_eirp);
2833
2834 nla_nest_end(msg, nl_reg_rule);
2835 }
2836
2837 nla_nest_end(msg, nl_reg_rules);
2838
2839 genlmsg_end(msg, hdr);
134e6375 2840 err = genlmsg_reply(msg, info);
f130347c
LR
2841 goto out;
2842
2843nla_put_failure:
2844 genlmsg_cancel(msg, hdr);
2845 err = -EMSGSIZE;
2846out:
a1794390 2847 mutex_unlock(&cfg80211_mutex);
f130347c
LR
2848 return err;
2849}
2850
b2e1b302
LR
2851static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
2852{
2853 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
2854 struct nlattr *nl_reg_rule;
2855 char *alpha2 = NULL;
2856 int rem_reg_rules = 0, r = 0;
2857 u32 num_rules = 0, rule_idx = 0, size_of_regd;
2858 struct ieee80211_regdomain *rd = NULL;
2859
2860 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
2861 return -EINVAL;
2862
2863 if (!info->attrs[NL80211_ATTR_REG_RULES])
2864 return -EINVAL;
2865
2866 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
2867
2868 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
2869 rem_reg_rules) {
2870 num_rules++;
2871 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 2872 return -EINVAL;
b2e1b302
LR
2873 }
2874
61405e97
LR
2875 mutex_lock(&cfg80211_mutex);
2876
d0e18f83
LR
2877 if (!reg_is_valid_request(alpha2)) {
2878 r = -EINVAL;
2879 goto bad_reg;
2880 }
b2e1b302
LR
2881
2882 size_of_regd = sizeof(struct ieee80211_regdomain) +
2883 (num_rules * sizeof(struct ieee80211_reg_rule));
2884
2885 rd = kzalloc(size_of_regd, GFP_KERNEL);
d0e18f83
LR
2886 if (!rd) {
2887 r = -ENOMEM;
2888 goto bad_reg;
2889 }
b2e1b302
LR
2890
2891 rd->n_reg_rules = num_rules;
2892 rd->alpha2[0] = alpha2[0];
2893 rd->alpha2[1] = alpha2[1];
2894
2895 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
2896 rem_reg_rules) {
2897 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
2898 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
2899 reg_rule_policy);
2900 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
2901 if (r)
2902 goto bad_reg;
2903
2904 rule_idx++;
2905
d0e18f83
LR
2906 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
2907 r = -EINVAL;
b2e1b302 2908 goto bad_reg;
d0e18f83 2909 }
b2e1b302
LR
2910 }
2911
2912 BUG_ON(rule_idx != num_rules);
2913
b2e1b302 2914 r = set_regdom(rd);
61405e97 2915
a1794390 2916 mutex_unlock(&cfg80211_mutex);
d0e18f83 2917
b2e1b302
LR
2918 return r;
2919
d2372b31 2920 bad_reg:
61405e97 2921 mutex_unlock(&cfg80211_mutex);
b2e1b302 2922 kfree(rd);
d0e18f83 2923 return r;
b2e1b302
LR
2924}
2925
83f5e2cf
JB
2926static int validate_scan_freqs(struct nlattr *freqs)
2927{
2928 struct nlattr *attr1, *attr2;
2929 int n_channels = 0, tmp1, tmp2;
2930
2931 nla_for_each_nested(attr1, freqs, tmp1) {
2932 n_channels++;
2933 /*
2934 * Some hardware has a limited channel list for
2935 * scanning, and it is pretty much nonsensical
2936 * to scan for a channel twice, so disallow that
2937 * and don't require drivers to check that the
2938 * channel list they get isn't longer than what
2939 * they can scan, as long as they can scan all
2940 * the channels they registered at once.
2941 */
2942 nla_for_each_nested(attr2, freqs, tmp2)
2943 if (attr1 != attr2 &&
2944 nla_get_u32(attr1) == nla_get_u32(attr2))
2945 return 0;
2946 }
2947
2948 return n_channels;
2949}
2950
2a519311
JB
2951static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2952{
79c97e97 2953 struct cfg80211_registered_device *rdev;
2a519311
JB
2954 struct net_device *dev;
2955 struct cfg80211_scan_request *request;
2956 struct cfg80211_ssid *ssid;
2957 struct ieee80211_channel *channel;
2958 struct nlattr *attr;
2959 struct wiphy *wiphy;
83f5e2cf 2960 int err, tmp, n_ssids = 0, n_channels, i;
2a519311 2961 enum ieee80211_band band;
70692ad2 2962 size_t ie_len;
2a519311 2963
f4a11bb0
JB
2964 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
2965 return -EINVAL;
2966
3b85875a
JB
2967 rtnl_lock();
2968
463d0183 2969 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2a519311 2970 if (err)
3b85875a 2971 goto out_rtnl;
2a519311 2972
79c97e97 2973 wiphy = &rdev->wiphy;
2a519311 2974
79c97e97 2975 if (!rdev->ops->scan) {
2a519311
JB
2976 err = -EOPNOTSUPP;
2977 goto out;
2978 }
2979
35a8efe1
JM
2980 if (!netif_running(dev)) {
2981 err = -ENETDOWN;
2982 goto out;
2983 }
2984
79c97e97 2985 if (rdev->scan_req) {
2a519311 2986 err = -EBUSY;
3b85875a 2987 goto out;
2a519311
JB
2988 }
2989
2990 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
2991 n_channels = validate_scan_freqs(
2992 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
2a519311
JB
2993 if (!n_channels) {
2994 err = -EINVAL;
3b85875a 2995 goto out;
2a519311
JB
2996 }
2997 } else {
83f5e2cf
JB
2998 n_channels = 0;
2999
2a519311
JB
3000 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
3001 if (wiphy->bands[band])
3002 n_channels += wiphy->bands[band]->n_channels;
3003 }
3004
3005 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
3006 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
3007 n_ssids++;
3008
3009 if (n_ssids > wiphy->max_scan_ssids) {
3010 err = -EINVAL;
3b85875a 3011 goto out;
2a519311
JB
3012 }
3013
70692ad2
JM
3014 if (info->attrs[NL80211_ATTR_IE])
3015 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3016 else
3017 ie_len = 0;
3018
18a83659
JB
3019 if (ie_len > wiphy->max_scan_ie_len) {
3020 err = -EINVAL;
3021 goto out;
3022 }
3023
2a519311
JB
3024 request = kzalloc(sizeof(*request)
3025 + sizeof(*ssid) * n_ssids
70692ad2
JM
3026 + sizeof(channel) * n_channels
3027 + ie_len, GFP_KERNEL);
2a519311
JB
3028 if (!request) {
3029 err = -ENOMEM;
3b85875a 3030 goto out;
2a519311
JB
3031 }
3032
2a519311 3033 if (n_ssids)
5ba63533 3034 request->ssids = (void *)&request->channels[n_channels];
2a519311 3035 request->n_ssids = n_ssids;
70692ad2
JM
3036 if (ie_len) {
3037 if (request->ssids)
3038 request->ie = (void *)(request->ssids + n_ssids);
3039 else
3040 request->ie = (void *)(request->channels + n_channels);
3041 }
2a519311 3042
584991dc 3043 i = 0;
2a519311
JB
3044 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
3045 /* user specified, bail out if channel not found */
2a519311 3046 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
3047 struct ieee80211_channel *chan;
3048
3049 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
3050
3051 if (!chan) {
2a519311
JB
3052 err = -EINVAL;
3053 goto out_free;
3054 }
584991dc
JB
3055
3056 /* ignore disabled channels */
3057 if (chan->flags & IEEE80211_CHAN_DISABLED)
3058 continue;
3059
3060 request->channels[i] = chan;
2a519311
JB
3061 i++;
3062 }
3063 } else {
3064 /* all channels */
2a519311
JB
3065 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
3066 int j;
3067 if (!wiphy->bands[band])
3068 continue;
3069 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
3070 struct ieee80211_channel *chan;
3071
3072 chan = &wiphy->bands[band]->channels[j];
3073
3074 if (chan->flags & IEEE80211_CHAN_DISABLED)
3075 continue;
3076
3077 request->channels[i] = chan;
2a519311
JB
3078 i++;
3079 }
3080 }
3081 }
3082
584991dc
JB
3083 if (!i) {
3084 err = -EINVAL;
3085 goto out_free;
3086 }
3087
3088 request->n_channels = i;
3089
2a519311
JB
3090 i = 0;
3091 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
3092 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
3093 if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
3094 err = -EINVAL;
3095 goto out_free;
3096 }
3097 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
3098 request->ssids[i].ssid_len = nla_len(attr);
3099 i++;
3100 }
3101 }
3102
70692ad2
JM
3103 if (info->attrs[NL80211_ATTR_IE]) {
3104 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
3105 memcpy((void *)request->ie,
3106 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
3107 request->ie_len);
3108 }
3109
463d0183 3110 request->dev = dev;
79c97e97 3111 request->wiphy = &rdev->wiphy;
2a519311 3112
79c97e97
JB
3113 rdev->scan_req = request;
3114 err = rdev->ops->scan(&rdev->wiphy, dev, request);
2a519311 3115
463d0183 3116 if (!err) {
79c97e97 3117 nl80211_send_scan_start(rdev, dev);
463d0183
JB
3118 dev_hold(dev);
3119 }
a538e2d5 3120
2a519311
JB
3121 out_free:
3122 if (err) {
79c97e97 3123 rdev->scan_req = NULL;
2a519311
JB
3124 kfree(request);
3125 }
2a519311 3126 out:
79c97e97 3127 cfg80211_unlock_rdev(rdev);
2a519311 3128 dev_put(dev);
3b85875a
JB
3129 out_rtnl:
3130 rtnl_unlock();
3131
2a519311
JB
3132 return err;
3133}
3134
3135static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
3136 struct cfg80211_registered_device *rdev,
48ab905d
JB
3137 struct wireless_dev *wdev,
3138 struct cfg80211_internal_bss *intbss)
2a519311 3139{
48ab905d 3140 struct cfg80211_bss *res = &intbss->pub;
2a519311
JB
3141 void *hdr;
3142 struct nlattr *bss;
48ab905d
JB
3143 int i;
3144
3145 ASSERT_WDEV_LOCK(wdev);
2a519311
JB
3146
3147 hdr = nl80211hdr_put(msg, pid, seq, flags,
3148 NL80211_CMD_NEW_SCAN_RESULTS);
3149 if (!hdr)
3150 return -1;
3151
f5ea9120 3152 NLA_PUT_U32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation);
48ab905d 3153 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex);
2a519311
JB
3154
3155 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
3156 if (!bss)
3157 goto nla_put_failure;
3158 if (!is_zero_ether_addr(res->bssid))
3159 NLA_PUT(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid);
3160 if (res->information_elements && res->len_information_elements)
3161 NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS,
3162 res->len_information_elements,
3163 res->information_elements);
3164 if (res->tsf)
3165 NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf);
3166 if (res->beacon_interval)
3167 NLA_PUT_U16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval);
3168 NLA_PUT_U16(msg, NL80211_BSS_CAPABILITY, res->capability);
3169 NLA_PUT_U32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq);
7c89606e
HS
3170 NLA_PUT_U32(msg, NL80211_BSS_SEEN_MS_AGO,
3171 jiffies_to_msecs(jiffies - intbss->ts));
2a519311 3172
77965c97 3173 switch (rdev->wiphy.signal_type) {
2a519311
JB
3174 case CFG80211_SIGNAL_TYPE_MBM:
3175 NLA_PUT_U32(msg, NL80211_BSS_SIGNAL_MBM, res->signal);
3176 break;
3177 case CFG80211_SIGNAL_TYPE_UNSPEC:
3178 NLA_PUT_U8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal);
3179 break;
3180 default:
3181 break;
3182 }
3183
48ab905d
JB
3184 switch (wdev->iftype) {
3185 case NL80211_IFTYPE_STATION:
3186 if (intbss == wdev->current_bss)
3187 NLA_PUT_U32(msg, NL80211_BSS_STATUS,
3188 NL80211_BSS_STATUS_ASSOCIATED);
3189 else for (i = 0; i < MAX_AUTH_BSSES; i++) {
3190 if (intbss != wdev->auth_bsses[i])
3191 continue;
3192 NLA_PUT_U32(msg, NL80211_BSS_STATUS,
3193 NL80211_BSS_STATUS_AUTHENTICATED);
3194 break;
3195 }
3196 break;
3197 case NL80211_IFTYPE_ADHOC:
3198 if (intbss == wdev->current_bss)
3199 NLA_PUT_U32(msg, NL80211_BSS_STATUS,
3200 NL80211_BSS_STATUS_IBSS_JOINED);
3201 break;
3202 default:
3203 break;
3204 }
3205
2a519311
JB
3206 nla_nest_end(msg, bss);
3207
3208 return genlmsg_end(msg, hdr);
3209
3210 nla_put_failure:
3211 genlmsg_cancel(msg, hdr);
3212 return -EMSGSIZE;
3213}
3214
3215static int nl80211_dump_scan(struct sk_buff *skb,
3216 struct netlink_callback *cb)
3217{
48ab905d
JB
3218 struct cfg80211_registered_device *rdev;
3219 struct net_device *dev;
2a519311 3220 struct cfg80211_internal_bss *scan;
48ab905d 3221 struct wireless_dev *wdev;
2a519311
JB
3222 int ifidx = cb->args[0];
3223 int start = cb->args[1], idx = 0;
3224 int err;
3225
a043897a
HS
3226 if (!ifidx)
3227 ifidx = nl80211_get_ifidx(cb);
3228 if (ifidx < 0)
3229 return ifidx;
3230 cb->args[0] = ifidx;
2a519311 3231
463d0183 3232 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
48ab905d 3233 if (!dev)
2a519311
JB
3234 return -ENODEV;
3235
463d0183 3236 rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
48ab905d
JB
3237 if (IS_ERR(rdev)) {
3238 err = PTR_ERR(rdev);
2a519311
JB
3239 goto out_put_netdev;
3240 }
3241
48ab905d 3242 wdev = dev->ieee80211_ptr;
2a519311 3243
48ab905d
JB
3244 wdev_lock(wdev);
3245 spin_lock_bh(&rdev->bss_lock);
3246 cfg80211_bss_expire(rdev);
3247
3248 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
3249 if (++idx <= start)
3250 continue;
3251 if (nl80211_send_bss(skb,
3252 NETLINK_CB(cb->skb).pid,
3253 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 3254 rdev, wdev, scan) < 0) {
2a519311
JB
3255 idx--;
3256 goto out;
3257 }
3258 }
3259
3260 out:
48ab905d
JB
3261 spin_unlock_bh(&rdev->bss_lock);
3262 wdev_unlock(wdev);
2a519311
JB
3263
3264 cb->args[1] = idx;
3265 err = skb->len;
48ab905d 3266 cfg80211_unlock_rdev(rdev);
2a519311 3267 out_put_netdev:
48ab905d 3268 dev_put(dev);
2a519311
JB
3269
3270 return err;
3271}
3272
61fa713c
HS
3273static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3274 int flags, struct net_device *dev,
3275 struct survey_info *survey)
3276{
3277 void *hdr;
3278 struct nlattr *infoattr;
3279
3280 /* Survey without a channel doesn't make sense */
3281 if (!survey->channel)
3282 return -EINVAL;
3283
3284 hdr = nl80211hdr_put(msg, pid, seq, flags,
3285 NL80211_CMD_NEW_SURVEY_RESULTS);
3286 if (!hdr)
3287 return -ENOMEM;
3288
3289 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
3290
3291 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
3292 if (!infoattr)
3293 goto nla_put_failure;
3294
3295 NLA_PUT_U32(msg, NL80211_SURVEY_INFO_FREQUENCY,
3296 survey->channel->center_freq);
3297 if (survey->filled & SURVEY_INFO_NOISE_DBM)
3298 NLA_PUT_U8(msg, NL80211_SURVEY_INFO_NOISE,
3299 survey->noise);
3300
3301 nla_nest_end(msg, infoattr);
3302
3303 return genlmsg_end(msg, hdr);
3304
3305 nla_put_failure:
3306 genlmsg_cancel(msg, hdr);
3307 return -EMSGSIZE;
3308}
3309
3310static int nl80211_dump_survey(struct sk_buff *skb,
3311 struct netlink_callback *cb)
3312{
3313 struct survey_info survey;
3314 struct cfg80211_registered_device *dev;
3315 struct net_device *netdev;
3316 int ifidx = cb->args[0];
3317 int survey_idx = cb->args[1];
3318 int res;
3319
3320 if (!ifidx)
3321 ifidx = nl80211_get_ifidx(cb);
3322 if (ifidx < 0)
3323 return ifidx;
3324 cb->args[0] = ifidx;
3325
3326 rtnl_lock();
3327
3328 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3329 if (!netdev) {
3330 res = -ENODEV;
3331 goto out_rtnl;
3332 }
3333
3334 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3335 if (IS_ERR(dev)) {
3336 res = PTR_ERR(dev);
3337 goto out_rtnl;
3338 }
3339
3340 if (!dev->ops->dump_survey) {
3341 res = -EOPNOTSUPP;
3342 goto out_err;
3343 }
3344
3345 while (1) {
3346 res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx,
3347 &survey);
3348 if (res == -ENOENT)
3349 break;
3350 if (res)
3351 goto out_err;
3352
3353 if (nl80211_send_survey(skb,
3354 NETLINK_CB(cb->skb).pid,
3355 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3356 netdev,
3357 &survey) < 0)
3358 goto out;
3359 survey_idx++;
3360 }
3361
3362 out:
3363 cb->args[1] = survey_idx;
3364 res = skb->len;
3365 out_err:
3366 cfg80211_unlock_rdev(dev);
3367 out_rtnl:
3368 rtnl_unlock();
3369
3370 return res;
3371}
3372
255e737e
JM
3373static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type)
3374{
b23aa676
SO
3375 return auth_type <= NL80211_AUTHTYPE_MAX;
3376}
3377
3378static bool nl80211_valid_wpa_versions(u32 wpa_versions)
3379{
3380 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
3381 NL80211_WPA_VERSION_2));
3382}
3383
3384static bool nl80211_valid_akm_suite(u32 akm)
3385{
3386 return akm == WLAN_AKM_SUITE_8021X ||
3387 akm == WLAN_AKM_SUITE_PSK;
3388}
3389
3390static bool nl80211_valid_cipher_suite(u32 cipher)
3391{
3392 return cipher == WLAN_CIPHER_SUITE_WEP40 ||
3393 cipher == WLAN_CIPHER_SUITE_WEP104 ||
3394 cipher == WLAN_CIPHER_SUITE_TKIP ||
3395 cipher == WLAN_CIPHER_SUITE_CCMP ||
3396 cipher == WLAN_CIPHER_SUITE_AES_CMAC;
255e737e
JM
3397}
3398
b23aa676 3399
636a5d36
JM
3400static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3401{
79c97e97 3402 struct cfg80211_registered_device *rdev;
636a5d36 3403 struct net_device *dev;
19957bb3
JB
3404 struct ieee80211_channel *chan;
3405 const u8 *bssid, *ssid, *ie = NULL;
3406 int err, ssid_len, ie_len = 0;
3407 enum nl80211_auth_type auth_type;
fffd0934 3408 struct key_parse key;
636a5d36 3409
f4a11bb0
JB
3410 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3411 return -EINVAL;
3412
3413 if (!info->attrs[NL80211_ATTR_MAC])
3414 return -EINVAL;
3415
1778092e
JM
3416 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
3417 return -EINVAL;
3418
19957bb3
JB
3419 if (!info->attrs[NL80211_ATTR_SSID])
3420 return -EINVAL;
3421
3422 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
3423 return -EINVAL;
3424
fffd0934
JB
3425 err = nl80211_parse_key(info, &key);
3426 if (err)
3427 return err;
3428
3429 if (key.idx >= 0) {
3430 if (!key.p.key || !key.p.key_len)
3431 return -EINVAL;
3432 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
3433 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
3434 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
3435 key.p.key_len != WLAN_KEY_LEN_WEP104))
3436 return -EINVAL;
3437 if (key.idx > 4)
3438 return -EINVAL;
3439 } else {
3440 key.p.key_len = 0;
3441 key.p.key = NULL;
3442 }
3443
636a5d36
JM
3444 rtnl_lock();
3445
463d0183 3446 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
636a5d36
JM
3447 if (err)
3448 goto unlock_rtnl;
3449
79c97e97 3450 if (!rdev->ops->auth) {
636a5d36
JM
3451 err = -EOPNOTSUPP;
3452 goto out;
3453 }
3454
eec60b03
JM
3455 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
3456 err = -EOPNOTSUPP;
3457 goto out;
3458 }
3459
35a8efe1
JM
3460 if (!netif_running(dev)) {
3461 err = -ENETDOWN;
3462 goto out;
3463 }
3464
19957bb3 3465 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
79c97e97 3466 chan = ieee80211_get_channel(&rdev->wiphy,
19957bb3
JB
3467 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3468 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
3469 err = -EINVAL;
3470 goto out;
636a5d36
JM
3471 }
3472
19957bb3
JB
3473 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3474 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
3475
3476 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
3477 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3478 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
3479 }
3480
19957bb3
JB
3481 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
3482 if (!nl80211_valid_auth_type(auth_type)) {
1778092e
JM
3483 err = -EINVAL;
3484 goto out;
636a5d36
JM
3485 }
3486
79c97e97 3487 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
fffd0934
JB
3488 ssid, ssid_len, ie, ie_len,
3489 key.p.key, key.p.key_len, key.idx);
636a5d36
JM
3490
3491out:
79c97e97 3492 cfg80211_unlock_rdev(rdev);
636a5d36
JM
3493 dev_put(dev);
3494unlock_rtnl:
3495 rtnl_unlock();
3496 return err;
3497}
3498
b23aa676 3499static int nl80211_crypto_settings(struct genl_info *info,
3dc27d25
JB
3500 struct cfg80211_crypto_settings *settings,
3501 int cipher_limit)
b23aa676 3502{
c0b2bbd8
JB
3503 memset(settings, 0, sizeof(*settings));
3504
b23aa676
SO
3505 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
3506
3507 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
3508 void *data;
3509 int len, i;
3510
3511 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
3512 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
3513 settings->n_ciphers_pairwise = len / sizeof(u32);
3514
3515 if (len % sizeof(u32))
3516 return -EINVAL;
3517
3dc27d25 3518 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
3519 return -EINVAL;
3520
3521 memcpy(settings->ciphers_pairwise, data, len);
3522
3523 for (i = 0; i < settings->n_ciphers_pairwise; i++)
3524 if (!nl80211_valid_cipher_suite(
3525 settings->ciphers_pairwise[i]))
3526 return -EINVAL;
3527 }
3528
3529 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
3530 settings->cipher_group =
3531 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
3532 if (!nl80211_valid_cipher_suite(settings->cipher_group))
3533 return -EINVAL;
3534 }
3535
3536 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
3537 settings->wpa_versions =
3538 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
3539 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
3540 return -EINVAL;
3541 }
3542
3543 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
3544 void *data;
3545 int len, i;
3546
3547 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
3548 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
3549 settings->n_akm_suites = len / sizeof(u32);
3550
3551 if (len % sizeof(u32))
3552 return -EINVAL;
3553
3554 memcpy(settings->akm_suites, data, len);
3555
3556 for (i = 0; i < settings->n_ciphers_pairwise; i++)
3557 if (!nl80211_valid_akm_suite(settings->akm_suites[i]))
3558 return -EINVAL;
3559 }
3560
3561 return 0;
3562}
3563
636a5d36
JM
3564static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3565{
19957bb3 3566 struct cfg80211_registered_device *rdev;
636a5d36 3567 struct net_device *dev;
19957bb3 3568 struct cfg80211_crypto_settings crypto;
59bbb6f7 3569 struct ieee80211_channel *chan, *fixedchan;
3e5d7649 3570 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
19957bb3
JB
3571 int err, ssid_len, ie_len = 0;
3572 bool use_mfp = false;
636a5d36 3573
f4a11bb0
JB
3574 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3575 return -EINVAL;
3576
3577 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
3578 !info->attrs[NL80211_ATTR_SSID] ||
3579 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
3580 return -EINVAL;
3581
636a5d36
JM
3582 rtnl_lock();
3583
463d0183 3584 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
636a5d36
JM
3585 if (err)
3586 goto unlock_rtnl;
3587
19957bb3 3588 if (!rdev->ops->assoc) {
636a5d36
JM
3589 err = -EOPNOTSUPP;
3590 goto out;
3591 }
3592
eec60b03
JM
3593 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
3594 err = -EOPNOTSUPP;
3595 goto out;
3596 }
3597
35a8efe1
JM
3598 if (!netif_running(dev)) {
3599 err = -ENETDOWN;
3600 goto out;
3601 }
3602
19957bb3 3603 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 3604
19957bb3
JB
3605 chan = ieee80211_get_channel(&rdev->wiphy,
3606 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3607 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) {
3608 err = -EINVAL;
3609 goto out;
636a5d36
JM
3610 }
3611
59bbb6f7
JB
3612 mutex_lock(&rdev->devlist_mtx);
3613 fixedchan = rdev_fixed_channel(rdev, NULL);
3614 if (fixedchan && chan != fixedchan) {
3615 err = -EBUSY;
3616 mutex_unlock(&rdev->devlist_mtx);
3617 goto out;
3618 }
3619 mutex_unlock(&rdev->devlist_mtx);
3620
19957bb3
JB
3621 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3622 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
3623
3624 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
3625 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3626 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
3627 }
3628
dc6382ce 3629 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 3630 enum nl80211_mfp mfp =
dc6382ce 3631 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 3632 if (mfp == NL80211_MFP_REQUIRED)
19957bb3 3633 use_mfp = true;
4f5dadce 3634 else if (mfp != NL80211_MFP_NO) {
dc6382ce
JM
3635 err = -EINVAL;
3636 goto out;
3637 }
3638 }
3639
3e5d7649
JB
3640 if (info->attrs[NL80211_ATTR_PREV_BSSID])
3641 prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3642
3dc27d25 3643 err = nl80211_crypto_settings(info, &crypto, 1);
b23aa676 3644 if (!err)
3e5d7649
JB
3645 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
3646 ssid, ssid_len, ie, ie_len, use_mfp,
19957bb3 3647 &crypto);
636a5d36
JM
3648
3649out:
4d0c8aea 3650 cfg80211_unlock_rdev(rdev);
636a5d36
JM
3651 dev_put(dev);
3652unlock_rtnl:
3653 rtnl_unlock();
3654 return err;
3655}
3656
3657static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3658{
79c97e97 3659 struct cfg80211_registered_device *rdev;
636a5d36 3660 struct net_device *dev;
19957bb3
JB
3661 const u8 *ie = NULL, *bssid;
3662 int err, ie_len = 0;
3663 u16 reason_code;
636a5d36 3664
f4a11bb0
JB
3665 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3666 return -EINVAL;
3667
3668 if (!info->attrs[NL80211_ATTR_MAC])
3669 return -EINVAL;
3670
3671 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3672 return -EINVAL;
3673
636a5d36
JM
3674 rtnl_lock();
3675
463d0183 3676 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
636a5d36
JM
3677 if (err)
3678 goto unlock_rtnl;
3679
79c97e97 3680 if (!rdev->ops->deauth) {
636a5d36
JM
3681 err = -EOPNOTSUPP;
3682 goto out;
3683 }
3684
eec60b03
JM
3685 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
3686 err = -EOPNOTSUPP;
3687 goto out;
3688 }
3689
35a8efe1
JM
3690 if (!netif_running(dev)) {
3691 err = -ENETDOWN;
3692 goto out;
3693 }
3694
19957bb3 3695 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 3696
19957bb3
JB
3697 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
3698 if (reason_code == 0) {
f4a11bb0
JB
3699 /* Reason Code 0 is reserved */
3700 err = -EINVAL;
3701 goto out;
255e737e 3702 }
636a5d36
JM
3703
3704 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
3705 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3706 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
3707 }
3708
79c97e97 3709 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code);
636a5d36
JM
3710
3711out:
79c97e97 3712 cfg80211_unlock_rdev(rdev);
636a5d36
JM
3713 dev_put(dev);
3714unlock_rtnl:
3715 rtnl_unlock();
3716 return err;
3717}
3718
3719static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3720{
79c97e97 3721 struct cfg80211_registered_device *rdev;
636a5d36 3722 struct net_device *dev;
19957bb3
JB
3723 const u8 *ie = NULL, *bssid;
3724 int err, ie_len = 0;
3725 u16 reason_code;
636a5d36 3726
f4a11bb0
JB
3727 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3728 return -EINVAL;
3729
3730 if (!info->attrs[NL80211_ATTR_MAC])
3731 return -EINVAL;
3732
3733 if (!info->attrs[NL80211_ATTR_REASON_CODE])
3734 return -EINVAL;
3735
636a5d36
JM
3736 rtnl_lock();
3737
463d0183 3738 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
636a5d36
JM
3739 if (err)
3740 goto unlock_rtnl;
3741
79c97e97 3742 if (!rdev->ops->disassoc) {
636a5d36
JM
3743 err = -EOPNOTSUPP;
3744 goto out;
3745 }
3746
eec60b03
JM
3747 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
3748 err = -EOPNOTSUPP;
3749 goto out;
3750 }
3751
35a8efe1
JM
3752 if (!netif_running(dev)) {
3753 err = -ENETDOWN;
3754 goto out;
3755 }
3756
19957bb3 3757 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 3758
19957bb3
JB
3759 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
3760 if (reason_code == 0) {
f4a11bb0
JB
3761 /* Reason Code 0 is reserved */
3762 err = -EINVAL;
3763 goto out;
255e737e 3764 }
636a5d36
JM
3765
3766 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
3767 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3768 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
3769 }
3770
79c97e97 3771 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code);
636a5d36
JM
3772
3773out:
79c97e97 3774 cfg80211_unlock_rdev(rdev);
636a5d36
JM
3775 dev_put(dev);
3776unlock_rtnl:
3777 rtnl_unlock();
3778 return err;
3779}
3780
04a773ad
JB
3781static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3782{
79c97e97 3783 struct cfg80211_registered_device *rdev;
04a773ad
JB
3784 struct net_device *dev;
3785 struct cfg80211_ibss_params ibss;
3786 struct wiphy *wiphy;
fffd0934 3787 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
3788 int err;
3789
8e30bc55
JB
3790 memset(&ibss, 0, sizeof(ibss));
3791
04a773ad
JB
3792 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3793 return -EINVAL;
3794
3795 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
3796 !info->attrs[NL80211_ATTR_SSID] ||
3797 !nla_len(info->attrs[NL80211_ATTR_SSID]))
3798 return -EINVAL;
3799
8e30bc55
JB
3800 ibss.beacon_interval = 100;
3801
3802 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
3803 ibss.beacon_interval =
3804 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
3805 if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
3806 return -EINVAL;
3807 }
3808
04a773ad
JB
3809 rtnl_lock();
3810
463d0183 3811 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
04a773ad
JB
3812 if (err)
3813 goto unlock_rtnl;
3814
79c97e97 3815 if (!rdev->ops->join_ibss) {
04a773ad
JB
3816 err = -EOPNOTSUPP;
3817 goto out;
3818 }
3819
3820 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3821 err = -EOPNOTSUPP;
3822 goto out;
3823 }
3824
3825 if (!netif_running(dev)) {
3826 err = -ENETDOWN;
3827 goto out;
3828 }
3829
79c97e97 3830 wiphy = &rdev->wiphy;
04a773ad
JB
3831
3832 if (info->attrs[NL80211_ATTR_MAC])
3833 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3834 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
3835 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
3836
3837 if (info->attrs[NL80211_ATTR_IE]) {
3838 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
3839 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
3840 }
3841
3842 ibss.channel = ieee80211_get_channel(wiphy,
3843 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3844 if (!ibss.channel ||
3845 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
3846 ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
3847 err = -EINVAL;
3848 goto out;
3849 }
3850
3851 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
3852 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
3853
3854 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
3855 connkeys = nl80211_parse_connkeys(rdev,
3856 info->attrs[NL80211_ATTR_KEYS]);
3857 if (IS_ERR(connkeys)) {
3858 err = PTR_ERR(connkeys);
3859 connkeys = NULL;
3860 goto out;
3861 }
3862 }
04a773ad 3863
fffd0934 3864 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
04a773ad
JB
3865
3866out:
79c97e97 3867 cfg80211_unlock_rdev(rdev);
04a773ad
JB
3868 dev_put(dev);
3869unlock_rtnl:
fffd0934
JB
3870 if (err)
3871 kfree(connkeys);
04a773ad
JB
3872 rtnl_unlock();
3873 return err;
3874}
3875
3876static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3877{
79c97e97 3878 struct cfg80211_registered_device *rdev;
04a773ad
JB
3879 struct net_device *dev;
3880 int err;
3881
3882 rtnl_lock();
3883
463d0183 3884 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
04a773ad
JB
3885 if (err)
3886 goto unlock_rtnl;
3887
79c97e97 3888 if (!rdev->ops->leave_ibss) {
04a773ad
JB
3889 err = -EOPNOTSUPP;
3890 goto out;
3891 }
3892
3893 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
3894 err = -EOPNOTSUPP;
3895 goto out;
3896 }
3897
3898 if (!netif_running(dev)) {
3899 err = -ENETDOWN;
3900 goto out;
3901 }
3902
79c97e97 3903 err = cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
3904
3905out:
79c97e97 3906 cfg80211_unlock_rdev(rdev);
04a773ad
JB
3907 dev_put(dev);
3908unlock_rtnl:
3909 rtnl_unlock();
3910 return err;
3911}
3912
aff89a9b
JB
3913#ifdef CONFIG_NL80211_TESTMODE
3914static struct genl_multicast_group nl80211_testmode_mcgrp = {
3915 .name = "testmode",
3916};
3917
3918static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
3919{
3920 struct cfg80211_registered_device *rdev;
3921 int err;
3922
3923 if (!info->attrs[NL80211_ATTR_TESTDATA])
3924 return -EINVAL;
3925
3926 rtnl_lock();
3927
3928 rdev = cfg80211_get_dev_from_info(info);
3929 if (IS_ERR(rdev)) {
3930 err = PTR_ERR(rdev);
3931 goto unlock_rtnl;
3932 }
3933
3934 err = -EOPNOTSUPP;
3935 if (rdev->ops->testmode_cmd) {
3936 rdev->testmode_info = info;
3937 err = rdev->ops->testmode_cmd(&rdev->wiphy,
3938 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
3939 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
3940 rdev->testmode_info = NULL;
3941 }
3942
4d0c8aea 3943 cfg80211_unlock_rdev(rdev);
aff89a9b
JB
3944
3945 unlock_rtnl:
3946 rtnl_unlock();
3947 return err;
3948}
3949
3950static struct sk_buff *
3951__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
3952 int approxlen, u32 pid, u32 seq, gfp_t gfp)
3953{
3954 struct sk_buff *skb;
3955 void *hdr;
3956 struct nlattr *data;
3957
3958 skb = nlmsg_new(approxlen + 100, gfp);
3959 if (!skb)
3960 return NULL;
3961
3962 hdr = nl80211hdr_put(skb, pid, seq, 0, NL80211_CMD_TESTMODE);
3963 if (!hdr) {
3964 kfree_skb(skb);
3965 return NULL;
3966 }
3967
3968 NLA_PUT_U32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
3969 data = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
3970
3971 ((void **)skb->cb)[0] = rdev;
3972 ((void **)skb->cb)[1] = hdr;
3973 ((void **)skb->cb)[2] = data;
3974
3975 return skb;
3976
3977 nla_put_failure:
3978 kfree_skb(skb);
3979 return NULL;
3980}
3981
3982struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
3983 int approxlen)
3984{
3985 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
3986
3987 if (WARN_ON(!rdev->testmode_info))
3988 return NULL;
3989
3990 return __cfg80211_testmode_alloc_skb(rdev, approxlen,
3991 rdev->testmode_info->snd_pid,
3992 rdev->testmode_info->snd_seq,
3993 GFP_KERNEL);
3994}
3995EXPORT_SYMBOL(cfg80211_testmode_alloc_reply_skb);
3996
3997int cfg80211_testmode_reply(struct sk_buff *skb)
3998{
3999 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
4000 void *hdr = ((void **)skb->cb)[1];
4001 struct nlattr *data = ((void **)skb->cb)[2];
4002
4003 if (WARN_ON(!rdev->testmode_info)) {
4004 kfree_skb(skb);
4005 return -EINVAL;
4006 }
4007
4008 nla_nest_end(skb, data);
4009 genlmsg_end(skb, hdr);
4010 return genlmsg_reply(skb, rdev->testmode_info);
4011}
4012EXPORT_SYMBOL(cfg80211_testmode_reply);
4013
4014struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
4015 int approxlen, gfp_t gfp)
4016{
4017 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
4018
4019 return __cfg80211_testmode_alloc_skb(rdev, approxlen, 0, 0, gfp);
4020}
4021EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb);
4022
4023void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
4024{
4025 void *hdr = ((void **)skb->cb)[1];
4026 struct nlattr *data = ((void **)skb->cb)[2];
4027
4028 nla_nest_end(skb, data);
4029 genlmsg_end(skb, hdr);
4030 genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp);
4031}
4032EXPORT_SYMBOL(cfg80211_testmode_event);
4033#endif
4034
b23aa676
SO
4035static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
4036{
79c97e97 4037 struct cfg80211_registered_device *rdev;
b23aa676
SO
4038 struct net_device *dev;
4039 struct cfg80211_connect_params connect;
4040 struct wiphy *wiphy;
fffd0934 4041 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
4042 int err;
4043
4044 memset(&connect, 0, sizeof(connect));
4045
4046 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4047 return -EINVAL;
4048
4049 if (!info->attrs[NL80211_ATTR_SSID] ||
4050 !nla_len(info->attrs[NL80211_ATTR_SSID]))
4051 return -EINVAL;
4052
4053 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
4054 connect.auth_type =
4055 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
4056 if (!nl80211_valid_auth_type(connect.auth_type))
4057 return -EINVAL;
4058 } else
4059 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
4060
4061 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
4062
3dc27d25
JB
4063 err = nl80211_crypto_settings(info, &connect.crypto,
4064 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
4065 if (err)
4066 return err;
4067 rtnl_lock();
4068
463d0183 4069 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
b23aa676
SO
4070 if (err)
4071 goto unlock_rtnl;
4072
4073 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
4074 err = -EOPNOTSUPP;
4075 goto out;
4076 }
4077
4078 if (!netif_running(dev)) {
4079 err = -ENETDOWN;
4080 goto out;
4081 }
4082
79c97e97 4083 wiphy = &rdev->wiphy;
b23aa676 4084
b23aa676
SO
4085 if (info->attrs[NL80211_ATTR_MAC])
4086 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
4087 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4088 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
4089
4090 if (info->attrs[NL80211_ATTR_IE]) {
4091 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
4092 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
4093 }
4094
4095 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
4096 connect.channel =
4097 ieee80211_get_channel(wiphy,
4098 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
4099 if (!connect.channel ||
4100 connect.channel->flags & IEEE80211_CHAN_DISABLED) {
4101 err = -EINVAL;
4102 goto out;
4103 }
4104 }
4105
fffd0934
JB
4106 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
4107 connkeys = nl80211_parse_connkeys(rdev,
4108 info->attrs[NL80211_ATTR_KEYS]);
4109 if (IS_ERR(connkeys)) {
4110 err = PTR_ERR(connkeys);
4111 connkeys = NULL;
4112 goto out;
4113 }
4114 }
4115
4116 err = cfg80211_connect(rdev, dev, &connect, connkeys);
b23aa676
SO
4117
4118out:
79c97e97 4119 cfg80211_unlock_rdev(rdev);
b23aa676
SO
4120 dev_put(dev);
4121unlock_rtnl:
fffd0934
JB
4122 if (err)
4123 kfree(connkeys);
b23aa676
SO
4124 rtnl_unlock();
4125 return err;
4126}
4127
4128static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4129{
79c97e97 4130 struct cfg80211_registered_device *rdev;
b23aa676
SO
4131 struct net_device *dev;
4132 int err;
4133 u16 reason;
4134
4135 if (!info->attrs[NL80211_ATTR_REASON_CODE])
4136 reason = WLAN_REASON_DEAUTH_LEAVING;
4137 else
4138 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
4139
4140 if (reason == 0)
4141 return -EINVAL;
4142
4143 rtnl_lock();
4144
463d0183 4145 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
b23aa676
SO
4146 if (err)
4147 goto unlock_rtnl;
4148
4149 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
4150 err = -EOPNOTSUPP;
4151 goto out;
4152 }
4153
4154 if (!netif_running(dev)) {
4155 err = -ENETDOWN;
4156 goto out;
4157 }
4158
79c97e97 4159 err = cfg80211_disconnect(rdev, dev, reason, true);
b23aa676
SO
4160
4161out:
79c97e97 4162 cfg80211_unlock_rdev(rdev);
b23aa676
SO
4163 dev_put(dev);
4164unlock_rtnl:
4165 rtnl_unlock();
4166 return err;
4167}
4168
463d0183
JB
4169static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4170{
4171 struct cfg80211_registered_device *rdev;
4172 struct net *net;
4173 int err;
4174 u32 pid;
4175
4176 if (!info->attrs[NL80211_ATTR_PID])
4177 return -EINVAL;
4178
4179 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
4180
4181 rtnl_lock();
4182
4183 rdev = cfg80211_get_dev_from_info(info);
4184 if (IS_ERR(rdev)) {
4185 err = PTR_ERR(rdev);
8a8e05e5 4186 goto out_rtnl;
463d0183
JB
4187 }
4188
4189 net = get_net_ns_by_pid(pid);
4190 if (IS_ERR(net)) {
4191 err = PTR_ERR(net);
4192 goto out;
4193 }
4194
4195 err = 0;
4196
4197 /* check if anything to do */
4198 if (net_eq(wiphy_net(&rdev->wiphy), net))
4199 goto out_put_net;
4200
4201 err = cfg80211_switch_netns(rdev, net);
4202 out_put_net:
4203 put_net(net);
4204 out:
4205 cfg80211_unlock_rdev(rdev);
8a8e05e5 4206 out_rtnl:
463d0183
JB
4207 rtnl_unlock();
4208 return err;
4209}
4210
67fbb16b
SO
4211static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
4212{
4213 struct cfg80211_registered_device *rdev;
4214 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
4215 struct cfg80211_pmksa *pmksa) = NULL;
4216 int err;
4217 struct net_device *dev;
4218 struct cfg80211_pmksa pmksa;
4219
4220 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
4221
4222 if (!info->attrs[NL80211_ATTR_MAC])
4223 return -EINVAL;
4224
4225 if (!info->attrs[NL80211_ATTR_PMKID])
4226 return -EINVAL;
4227
4228 rtnl_lock();
4229
4230 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4231 if (err)
4232 goto out_rtnl;
4233
4234 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
4235 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
4236
4237 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
4238 err = -EOPNOTSUPP;
4239 goto out;
4240 }
4241
4242 switch (info->genlhdr->cmd) {
4243 case NL80211_CMD_SET_PMKSA:
4244 rdev_ops = rdev->ops->set_pmksa;
4245 break;
4246 case NL80211_CMD_DEL_PMKSA:
4247 rdev_ops = rdev->ops->del_pmksa;
4248 break;
4249 default:
4250 WARN_ON(1);
4251 break;
4252 }
4253
4254 if (!rdev_ops) {
4255 err = -EOPNOTSUPP;
4256 goto out;
4257 }
4258
4259 err = rdev_ops(&rdev->wiphy, dev, &pmksa);
4260
4261 out:
4262 cfg80211_unlock_rdev(rdev);
4263 dev_put(dev);
4264 out_rtnl:
4265 rtnl_unlock();
4266
4267 return err;
4268}
4269
4270static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
4271{
4272 struct cfg80211_registered_device *rdev;
4273 int err;
4274 struct net_device *dev;
4275
4276 rtnl_lock();
4277
4278 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4279 if (err)
4280 goto out_rtnl;
4281
4282 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) {
4283 err = -EOPNOTSUPP;
4284 goto out;
4285 }
4286
4287 if (!rdev->ops->flush_pmksa) {
4288 err = -EOPNOTSUPP;
4289 goto out;
4290 }
4291
4292 err = rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4293
4294 out:
4295 cfg80211_unlock_rdev(rdev);
4296 dev_put(dev);
4297 out_rtnl:
4298 rtnl_unlock();
4299
4300 return err;
4301
4302}
4303
9588bbd5
JM
4304static int nl80211_remain_on_channel(struct sk_buff *skb,
4305 struct genl_info *info)
4306{
4307 struct cfg80211_registered_device *rdev;
4308 struct net_device *dev;
4309 struct ieee80211_channel *chan;
4310 struct sk_buff *msg;
4311 void *hdr;
4312 u64 cookie;
4313 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
4314 u32 freq, duration;
4315 int err;
4316
4317 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
4318 !info->attrs[NL80211_ATTR_DURATION])
4319 return -EINVAL;
4320
4321 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
4322
4323 /*
4324 * We should be on that channel for at least one jiffie,
4325 * and more than 5 seconds seems excessive.
4326 */
4327 if (!duration || !msecs_to_jiffies(duration) || duration > 5000)
4328 return -EINVAL;
4329
4330 rtnl_lock();
4331
4332 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4333 if (err)
4334 goto unlock_rtnl;
4335
4336 if (!rdev->ops->remain_on_channel) {
4337 err = -EOPNOTSUPP;
4338 goto out;
4339 }
4340
4341 if (!netif_running(dev)) {
4342 err = -ENETDOWN;
4343 goto out;
4344 }
4345
4346 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
4347 channel_type = nla_get_u32(
4348 info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
4349 if (channel_type != NL80211_CHAN_NO_HT &&
4350 channel_type != NL80211_CHAN_HT20 &&
4351 channel_type != NL80211_CHAN_HT40PLUS &&
4352 channel_type != NL80211_CHAN_HT40MINUS)
4353 err = -EINVAL;
4354 goto out;
4355 }
4356
4357 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
4358 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4359 if (chan == NULL) {
4360 err = -EINVAL;
4361 goto out;
4362 }
4363
4364 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4365 if (!msg) {
4366 err = -ENOMEM;
4367 goto out;
4368 }
4369
4370 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
4371 NL80211_CMD_REMAIN_ON_CHANNEL);
4372
4373 if (IS_ERR(hdr)) {
4374 err = PTR_ERR(hdr);
4375 goto free_msg;
4376 }
4377
4378 err = rdev->ops->remain_on_channel(&rdev->wiphy, dev, chan,
4379 channel_type, duration, &cookie);
4380
4381 if (err)
4382 goto free_msg;
4383
4384 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
4385
4386 genlmsg_end(msg, hdr);
4387 err = genlmsg_reply(msg, info);
4388 goto out;
4389
4390 nla_put_failure:
4391 err = -ENOBUFS;
4392 free_msg:
4393 nlmsg_free(msg);
4394 out:
4395 cfg80211_unlock_rdev(rdev);
4396 dev_put(dev);
4397 unlock_rtnl:
4398 rtnl_unlock();
4399 return err;
4400}
4401
4402static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
4403 struct genl_info *info)
4404{
4405 struct cfg80211_registered_device *rdev;
4406 struct net_device *dev;
4407 u64 cookie;
4408 int err;
4409
4410 if (!info->attrs[NL80211_ATTR_COOKIE])
4411 return -EINVAL;
4412
4413 rtnl_lock();
4414
4415 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4416 if (err)
4417 goto unlock_rtnl;
4418
4419 if (!rdev->ops->cancel_remain_on_channel) {
4420 err = -EOPNOTSUPP;
4421 goto out;
4422 }
4423
4424 if (!netif_running(dev)) {
4425 err = -ENETDOWN;
4426 goto out;
4427 }
4428
4429 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
4430
4431 err = rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
4432
4433 out:
4434 cfg80211_unlock_rdev(rdev);
4435 dev_put(dev);
4436 unlock_rtnl:
4437 rtnl_unlock();
4438 return err;
4439}
4440
55682965
JB
4441static struct genl_ops nl80211_ops[] = {
4442 {
4443 .cmd = NL80211_CMD_GET_WIPHY,
4444 .doit = nl80211_get_wiphy,
4445 .dumpit = nl80211_dump_wiphy,
4446 .policy = nl80211_policy,
4447 /* can be retrieved by unprivileged users */
4448 },
4449 {
4450 .cmd = NL80211_CMD_SET_WIPHY,
4451 .doit = nl80211_set_wiphy,
4452 .policy = nl80211_policy,
4453 .flags = GENL_ADMIN_PERM,
4454 },
4455 {
4456 .cmd = NL80211_CMD_GET_INTERFACE,
4457 .doit = nl80211_get_interface,
4458 .dumpit = nl80211_dump_interface,
4459 .policy = nl80211_policy,
4460 /* can be retrieved by unprivileged users */
4461 },
4462 {
4463 .cmd = NL80211_CMD_SET_INTERFACE,
4464 .doit = nl80211_set_interface,
4465 .policy = nl80211_policy,
4466 .flags = GENL_ADMIN_PERM,
4467 },
4468 {
4469 .cmd = NL80211_CMD_NEW_INTERFACE,
4470 .doit = nl80211_new_interface,
4471 .policy = nl80211_policy,
4472 .flags = GENL_ADMIN_PERM,
4473 },
4474 {
4475 .cmd = NL80211_CMD_DEL_INTERFACE,
4476 .doit = nl80211_del_interface,
4477 .policy = nl80211_policy,
41ade00f
JB
4478 .flags = GENL_ADMIN_PERM,
4479 },
4480 {
4481 .cmd = NL80211_CMD_GET_KEY,
4482 .doit = nl80211_get_key,
4483 .policy = nl80211_policy,
4484 .flags = GENL_ADMIN_PERM,
4485 },
4486 {
4487 .cmd = NL80211_CMD_SET_KEY,
4488 .doit = nl80211_set_key,
4489 .policy = nl80211_policy,
4490 .flags = GENL_ADMIN_PERM,
4491 },
4492 {
4493 .cmd = NL80211_CMD_NEW_KEY,
4494 .doit = nl80211_new_key,
4495 .policy = nl80211_policy,
4496 .flags = GENL_ADMIN_PERM,
4497 },
4498 {
4499 .cmd = NL80211_CMD_DEL_KEY,
4500 .doit = nl80211_del_key,
4501 .policy = nl80211_policy,
55682965
JB
4502 .flags = GENL_ADMIN_PERM,
4503 },
ed1b6cc7
JB
4504 {
4505 .cmd = NL80211_CMD_SET_BEACON,
4506 .policy = nl80211_policy,
4507 .flags = GENL_ADMIN_PERM,
4508 .doit = nl80211_addset_beacon,
4509 },
4510 {
4511 .cmd = NL80211_CMD_NEW_BEACON,
4512 .policy = nl80211_policy,
4513 .flags = GENL_ADMIN_PERM,
4514 .doit = nl80211_addset_beacon,
4515 },
4516 {
4517 .cmd = NL80211_CMD_DEL_BEACON,
4518 .policy = nl80211_policy,
4519 .flags = GENL_ADMIN_PERM,
4520 .doit = nl80211_del_beacon,
4521 },
5727ef1b
JB
4522 {
4523 .cmd = NL80211_CMD_GET_STATION,
4524 .doit = nl80211_get_station,
2ec600d6 4525 .dumpit = nl80211_dump_station,
5727ef1b 4526 .policy = nl80211_policy,
5727ef1b
JB
4527 },
4528 {
4529 .cmd = NL80211_CMD_SET_STATION,
4530 .doit = nl80211_set_station,
4531 .policy = nl80211_policy,
4532 .flags = GENL_ADMIN_PERM,
4533 },
4534 {
4535 .cmd = NL80211_CMD_NEW_STATION,
4536 .doit = nl80211_new_station,
4537 .policy = nl80211_policy,
4538 .flags = GENL_ADMIN_PERM,
4539 },
4540 {
4541 .cmd = NL80211_CMD_DEL_STATION,
4542 .doit = nl80211_del_station,
4543 .policy = nl80211_policy,
2ec600d6
LCC
4544 .flags = GENL_ADMIN_PERM,
4545 },
4546 {
4547 .cmd = NL80211_CMD_GET_MPATH,
4548 .doit = nl80211_get_mpath,
4549 .dumpit = nl80211_dump_mpath,
4550 .policy = nl80211_policy,
4551 .flags = GENL_ADMIN_PERM,
4552 },
4553 {
4554 .cmd = NL80211_CMD_SET_MPATH,
4555 .doit = nl80211_set_mpath,
4556 .policy = nl80211_policy,
4557 .flags = GENL_ADMIN_PERM,
4558 },
4559 {
4560 .cmd = NL80211_CMD_NEW_MPATH,
4561 .doit = nl80211_new_mpath,
4562 .policy = nl80211_policy,
4563 .flags = GENL_ADMIN_PERM,
4564 },
4565 {
4566 .cmd = NL80211_CMD_DEL_MPATH,
4567 .doit = nl80211_del_mpath,
4568 .policy = nl80211_policy,
9f1ba906
JM
4569 .flags = GENL_ADMIN_PERM,
4570 },
4571 {
4572 .cmd = NL80211_CMD_SET_BSS,
4573 .doit = nl80211_set_bss,
4574 .policy = nl80211_policy,
b2e1b302
LR
4575 .flags = GENL_ADMIN_PERM,
4576 },
f130347c
LR
4577 {
4578 .cmd = NL80211_CMD_GET_REG,
4579 .doit = nl80211_get_reg,
4580 .policy = nl80211_policy,
4581 /* can be retrieved by unprivileged users */
4582 },
b2e1b302
LR
4583 {
4584 .cmd = NL80211_CMD_SET_REG,
4585 .doit = nl80211_set_reg,
4586 .policy = nl80211_policy,
4587 .flags = GENL_ADMIN_PERM,
4588 },
4589 {
4590 .cmd = NL80211_CMD_REQ_SET_REG,
4591 .doit = nl80211_req_set_reg,
4592 .policy = nl80211_policy,
93da9cc1 4593 .flags = GENL_ADMIN_PERM,
4594 },
4595 {
4596 .cmd = NL80211_CMD_GET_MESH_PARAMS,
4597 .doit = nl80211_get_mesh_params,
4598 .policy = nl80211_policy,
4599 /* can be retrieved by unprivileged users */
4600 },
4601 {
4602 .cmd = NL80211_CMD_SET_MESH_PARAMS,
4603 .doit = nl80211_set_mesh_params,
4604 .policy = nl80211_policy,
9aed3cc1
JM
4605 .flags = GENL_ADMIN_PERM,
4606 },
2a519311
JB
4607 {
4608 .cmd = NL80211_CMD_TRIGGER_SCAN,
4609 .doit = nl80211_trigger_scan,
4610 .policy = nl80211_policy,
4611 .flags = GENL_ADMIN_PERM,
4612 },
4613 {
4614 .cmd = NL80211_CMD_GET_SCAN,
4615 .policy = nl80211_policy,
4616 .dumpit = nl80211_dump_scan,
4617 },
636a5d36
JM
4618 {
4619 .cmd = NL80211_CMD_AUTHENTICATE,
4620 .doit = nl80211_authenticate,
4621 .policy = nl80211_policy,
4622 .flags = GENL_ADMIN_PERM,
4623 },
4624 {
4625 .cmd = NL80211_CMD_ASSOCIATE,
4626 .doit = nl80211_associate,
4627 .policy = nl80211_policy,
4628 .flags = GENL_ADMIN_PERM,
4629 },
4630 {
4631 .cmd = NL80211_CMD_DEAUTHENTICATE,
4632 .doit = nl80211_deauthenticate,
4633 .policy = nl80211_policy,
4634 .flags = GENL_ADMIN_PERM,
4635 },
4636 {
4637 .cmd = NL80211_CMD_DISASSOCIATE,
4638 .doit = nl80211_disassociate,
4639 .policy = nl80211_policy,
4640 .flags = GENL_ADMIN_PERM,
4641 },
04a773ad
JB
4642 {
4643 .cmd = NL80211_CMD_JOIN_IBSS,
4644 .doit = nl80211_join_ibss,
4645 .policy = nl80211_policy,
4646 .flags = GENL_ADMIN_PERM,
4647 },
4648 {
4649 .cmd = NL80211_CMD_LEAVE_IBSS,
4650 .doit = nl80211_leave_ibss,
4651 .policy = nl80211_policy,
4652 .flags = GENL_ADMIN_PERM,
4653 },
aff89a9b
JB
4654#ifdef CONFIG_NL80211_TESTMODE
4655 {
4656 .cmd = NL80211_CMD_TESTMODE,
4657 .doit = nl80211_testmode_do,
4658 .policy = nl80211_policy,
4659 .flags = GENL_ADMIN_PERM,
4660 },
4661#endif
b23aa676
SO
4662 {
4663 .cmd = NL80211_CMD_CONNECT,
4664 .doit = nl80211_connect,
4665 .policy = nl80211_policy,
4666 .flags = GENL_ADMIN_PERM,
4667 },
4668 {
4669 .cmd = NL80211_CMD_DISCONNECT,
4670 .doit = nl80211_disconnect,
4671 .policy = nl80211_policy,
4672 .flags = GENL_ADMIN_PERM,
4673 },
463d0183
JB
4674 {
4675 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
4676 .doit = nl80211_wiphy_netns,
4677 .policy = nl80211_policy,
4678 .flags = GENL_ADMIN_PERM,
4679 },
61fa713c
HS
4680 {
4681 .cmd = NL80211_CMD_GET_SURVEY,
4682 .policy = nl80211_policy,
4683 .dumpit = nl80211_dump_survey,
4684 },
67fbb16b
SO
4685 {
4686 .cmd = NL80211_CMD_SET_PMKSA,
4687 .doit = nl80211_setdel_pmksa,
4688 .policy = nl80211_policy,
4689 .flags = GENL_ADMIN_PERM,
4690 },
4691 {
4692 .cmd = NL80211_CMD_DEL_PMKSA,
4693 .doit = nl80211_setdel_pmksa,
4694 .policy = nl80211_policy,
4695 .flags = GENL_ADMIN_PERM,
4696 },
4697 {
4698 .cmd = NL80211_CMD_FLUSH_PMKSA,
4699 .doit = nl80211_flush_pmksa,
4700 .policy = nl80211_policy,
4701 .flags = GENL_ADMIN_PERM,
4702 },
9588bbd5
JM
4703 {
4704 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
4705 .doit = nl80211_remain_on_channel,
4706 .policy = nl80211_policy,
4707 .flags = GENL_ADMIN_PERM,
4708 },
4709 {
4710 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
4711 .doit = nl80211_cancel_remain_on_channel,
4712 .policy = nl80211_policy,
4713 .flags = GENL_ADMIN_PERM,
4714 },
55682965 4715};
9588bbd5 4716
6039f6d2
JM
4717static struct genl_multicast_group nl80211_mlme_mcgrp = {
4718 .name = "mlme",
4719};
55682965
JB
4720
4721/* multicast groups */
4722static struct genl_multicast_group nl80211_config_mcgrp = {
4723 .name = "config",
4724};
2a519311
JB
4725static struct genl_multicast_group nl80211_scan_mcgrp = {
4726 .name = "scan",
4727};
73d54c9e
LR
4728static struct genl_multicast_group nl80211_regulatory_mcgrp = {
4729 .name = "regulatory",
4730};
55682965
JB
4731
4732/* notification functions */
4733
4734void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
4735{
4736 struct sk_buff *msg;
4737
fd2120ca 4738 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
4739 if (!msg)
4740 return;
4741
4742 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
4743 nlmsg_free(msg);
4744 return;
4745 }
4746
463d0183
JB
4747 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4748 nl80211_config_mcgrp.id, GFP_KERNEL);
55682965
JB
4749}
4750
362a415d
JB
4751static int nl80211_add_scan_req(struct sk_buff *msg,
4752 struct cfg80211_registered_device *rdev)
4753{
4754 struct cfg80211_scan_request *req = rdev->scan_req;
4755 struct nlattr *nest;
4756 int i;
4757
667503dd
JB
4758 ASSERT_RDEV_LOCK(rdev);
4759
362a415d
JB
4760 if (WARN_ON(!req))
4761 return 0;
4762
4763 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
4764 if (!nest)
4765 goto nla_put_failure;
4766 for (i = 0; i < req->n_ssids; i++)
4767 NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid);
4768 nla_nest_end(msg, nest);
4769
4770 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
4771 if (!nest)
4772 goto nla_put_failure;
4773 for (i = 0; i < req->n_channels; i++)
4774 NLA_PUT_U32(msg, i, req->channels[i]->center_freq);
4775 nla_nest_end(msg, nest);
4776
4777 if (req->ie)
4778 NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);
4779
4780 return 0;
4781 nla_put_failure:
4782 return -ENOBUFS;
4783}
4784
a538e2d5
JB
4785static int nl80211_send_scan_msg(struct sk_buff *msg,
4786 struct cfg80211_registered_device *rdev,
4787 struct net_device *netdev,
4788 u32 pid, u32 seq, int flags,
4789 u32 cmd)
2a519311
JB
4790{
4791 void *hdr;
4792
4793 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
4794 if (!hdr)
4795 return -1;
4796
b5850a7a 4797 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
2a519311
JB
4798 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
4799
362a415d
JB
4800 /* ignore errors and send incomplete event anyway */
4801 nl80211_add_scan_req(msg, rdev);
2a519311
JB
4802
4803 return genlmsg_end(msg, hdr);
4804
4805 nla_put_failure:
4806 genlmsg_cancel(msg, hdr);
4807 return -EMSGSIZE;
4808}
4809
a538e2d5
JB
4810void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
4811 struct net_device *netdev)
4812{
4813 struct sk_buff *msg;
4814
4815 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
4816 if (!msg)
4817 return;
4818
4819 if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
4820 NL80211_CMD_TRIGGER_SCAN) < 0) {
4821 nlmsg_free(msg);
4822 return;
4823 }
4824
463d0183
JB
4825 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4826 nl80211_scan_mcgrp.id, GFP_KERNEL);
a538e2d5
JB
4827}
4828
2a519311
JB
4829void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
4830 struct net_device *netdev)
4831{
4832 struct sk_buff *msg;
4833
fd2120ca 4834 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311
JB
4835 if (!msg)
4836 return;
4837
a538e2d5
JB
4838 if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
4839 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311
JB
4840 nlmsg_free(msg);
4841 return;
4842 }
4843
463d0183
JB
4844 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4845 nl80211_scan_mcgrp.id, GFP_KERNEL);
2a519311
JB
4846}
4847
4848void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
4849 struct net_device *netdev)
4850{
4851 struct sk_buff *msg;
4852
fd2120ca 4853 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311
JB
4854 if (!msg)
4855 return;
4856
a538e2d5
JB
4857 if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
4858 NL80211_CMD_SCAN_ABORTED) < 0) {
2a519311
JB
4859 nlmsg_free(msg);
4860 return;
4861 }
4862
463d0183
JB
4863 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4864 nl80211_scan_mcgrp.id, GFP_KERNEL);
2a519311
JB
4865}
4866
73d54c9e
LR
4867/*
4868 * This can happen on global regulatory changes or device specific settings
4869 * based on custom world regulatory domains.
4870 */
4871void nl80211_send_reg_change_event(struct regulatory_request *request)
4872{
4873 struct sk_buff *msg;
4874 void *hdr;
4875
fd2120ca 4876 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
73d54c9e
LR
4877 if (!msg)
4878 return;
4879
4880 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
4881 if (!hdr) {
4882 nlmsg_free(msg);
4883 return;
4884 }
4885
4886 /* Userspace can always count this one always being set */
4887 NLA_PUT_U8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator);
4888
4889 if (request->alpha2[0] == '0' && request->alpha2[1] == '0')
4890 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
4891 NL80211_REGDOM_TYPE_WORLD);
4892 else if (request->alpha2[0] == '9' && request->alpha2[1] == '9')
4893 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
4894 NL80211_REGDOM_TYPE_CUSTOM_WORLD);
4895 else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
4896 request->intersect)
4897 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
4898 NL80211_REGDOM_TYPE_INTERSECTION);
4899 else {
4900 NLA_PUT_U8(msg, NL80211_ATTR_REG_TYPE,
4901 NL80211_REGDOM_TYPE_COUNTRY);
4902 NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, request->alpha2);
4903 }
4904
4905 if (wiphy_idx_valid(request->wiphy_idx))
4906 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx);
4907
4908 if (genlmsg_end(msg, hdr) < 0) {
4909 nlmsg_free(msg);
4910 return;
4911 }
4912
bc43b28c 4913 rcu_read_lock();
463d0183 4914 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
bc43b28c
JB
4915 GFP_ATOMIC);
4916 rcu_read_unlock();
73d54c9e
LR
4917
4918 return;
4919
4920nla_put_failure:
4921 genlmsg_cancel(msg, hdr);
4922 nlmsg_free(msg);
4923}
4924
6039f6d2
JM
4925static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
4926 struct net_device *netdev,
4927 const u8 *buf, size_t len,
e6d6e342 4928 enum nl80211_commands cmd, gfp_t gfp)
6039f6d2
JM
4929{
4930 struct sk_buff *msg;
4931 void *hdr;
4932
e6d6e342 4933 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
6039f6d2
JM
4934 if (!msg)
4935 return;
4936
4937 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
4938 if (!hdr) {
4939 nlmsg_free(msg);
4940 return;
4941 }
4942
4943 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
4944 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
4945 NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
4946
4947 if (genlmsg_end(msg, hdr) < 0) {
4948 nlmsg_free(msg);
4949 return;
4950 }
4951
463d0183
JB
4952 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4953 nl80211_mlme_mcgrp.id, gfp);
6039f6d2
JM
4954 return;
4955
4956 nla_put_failure:
4957 genlmsg_cancel(msg, hdr);
4958 nlmsg_free(msg);
4959}
4960
4961void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
4962 struct net_device *netdev, const u8 *buf,
4963 size_t len, gfp_t gfp)
6039f6d2
JM
4964{
4965 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 4966 NL80211_CMD_AUTHENTICATE, gfp);
6039f6d2
JM
4967}
4968
4969void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
4970 struct net_device *netdev, const u8 *buf,
e6d6e342 4971 size_t len, gfp_t gfp)
6039f6d2 4972{
e6d6e342
JB
4973 nl80211_send_mlme_event(rdev, netdev, buf, len,
4974 NL80211_CMD_ASSOCIATE, gfp);
6039f6d2
JM
4975}
4976
53b46b84 4977void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
4978 struct net_device *netdev, const u8 *buf,
4979 size_t len, gfp_t gfp)
6039f6d2
JM
4980{
4981 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 4982 NL80211_CMD_DEAUTHENTICATE, gfp);
6039f6d2
JM
4983}
4984
53b46b84
JM
4985void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
4986 struct net_device *netdev, const u8 *buf,
e6d6e342 4987 size_t len, gfp_t gfp)
6039f6d2
JM
4988{
4989 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 4990 NL80211_CMD_DISASSOCIATE, gfp);
6039f6d2
JM
4991}
4992
1b06bb40
LR
4993static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
4994 struct net_device *netdev, int cmd,
e6d6e342 4995 const u8 *addr, gfp_t gfp)
1965c853
JM
4996{
4997 struct sk_buff *msg;
4998 void *hdr;
4999
e6d6e342 5000 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
5001 if (!msg)
5002 return;
5003
5004 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
5005 if (!hdr) {
5006 nlmsg_free(msg);
5007 return;
5008 }
5009
5010 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5011 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5012 NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
5013 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
5014
5015 if (genlmsg_end(msg, hdr) < 0) {
5016 nlmsg_free(msg);
5017 return;
5018 }
5019
463d0183
JB
5020 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5021 nl80211_mlme_mcgrp.id, gfp);
1965c853
JM
5022 return;
5023
5024 nla_put_failure:
5025 genlmsg_cancel(msg, hdr);
5026 nlmsg_free(msg);
5027}
5028
5029void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
5030 struct net_device *netdev, const u8 *addr,
5031 gfp_t gfp)
1965c853
JM
5032{
5033 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 5034 addr, gfp);
1965c853
JM
5035}
5036
5037void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
5038 struct net_device *netdev, const u8 *addr,
5039 gfp_t gfp)
1965c853 5040{
e6d6e342
JB
5041 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
5042 addr, gfp);
1965c853
JM
5043}
5044
b23aa676
SO
5045void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5046 struct net_device *netdev, const u8 *bssid,
5047 const u8 *req_ie, size_t req_ie_len,
5048 const u8 *resp_ie, size_t resp_ie_len,
5049 u16 status, gfp_t gfp)
5050{
5051 struct sk_buff *msg;
5052 void *hdr;
5053
5054 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
5055 if (!msg)
5056 return;
5057
5058 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
5059 if (!hdr) {
5060 nlmsg_free(msg);
5061 return;
5062 }
5063
5064 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5065 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5066 if (bssid)
5067 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
5068 NLA_PUT_U16(msg, NL80211_ATTR_STATUS_CODE, status);
5069 if (req_ie)
5070 NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie);
5071 if (resp_ie)
5072 NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
5073
5074 if (genlmsg_end(msg, hdr) < 0) {
5075 nlmsg_free(msg);
5076 return;
5077 }
5078
463d0183
JB
5079 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5080 nl80211_mlme_mcgrp.id, gfp);
b23aa676
SO
5081 return;
5082
5083 nla_put_failure:
5084 genlmsg_cancel(msg, hdr);
5085 nlmsg_free(msg);
5086
5087}
5088
5089void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
5090 struct net_device *netdev, const u8 *bssid,
5091 const u8 *req_ie, size_t req_ie_len,
5092 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
5093{
5094 struct sk_buff *msg;
5095 void *hdr;
5096
5097 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
5098 if (!msg)
5099 return;
5100
5101 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
5102 if (!hdr) {
5103 nlmsg_free(msg);
5104 return;
5105 }
5106
5107 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5108 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5109 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
5110 if (req_ie)
5111 NLA_PUT(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie);
5112 if (resp_ie)
5113 NLA_PUT(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie);
5114
5115 if (genlmsg_end(msg, hdr) < 0) {
5116 nlmsg_free(msg);
5117 return;
5118 }
5119
463d0183
JB
5120 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5121 nl80211_mlme_mcgrp.id, gfp);
b23aa676
SO
5122 return;
5123
5124 nla_put_failure:
5125 genlmsg_cancel(msg, hdr);
5126 nlmsg_free(msg);
5127
5128}
5129
5130void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
5131 struct net_device *netdev, u16 reason,
667503dd 5132 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
5133{
5134 struct sk_buff *msg;
5135 void *hdr;
5136
667503dd 5137 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
b23aa676
SO
5138 if (!msg)
5139 return;
5140
5141 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
5142 if (!hdr) {
5143 nlmsg_free(msg);
5144 return;
5145 }
5146
5147 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5148 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5149 if (from_ap && reason)
5150 NLA_PUT_U16(msg, NL80211_ATTR_REASON_CODE, reason);
5151 if (from_ap)
5152 NLA_PUT_FLAG(msg, NL80211_ATTR_DISCONNECTED_BY_AP);
5153 if (ie)
5154 NLA_PUT(msg, NL80211_ATTR_IE, ie_len, ie);
5155
5156 if (genlmsg_end(msg, hdr) < 0) {
5157 nlmsg_free(msg);
5158 return;
5159 }
5160
463d0183
JB
5161 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5162 nl80211_mlme_mcgrp.id, GFP_KERNEL);
b23aa676
SO
5163 return;
5164
5165 nla_put_failure:
5166 genlmsg_cancel(msg, hdr);
5167 nlmsg_free(msg);
5168
5169}
5170
04a773ad
JB
5171void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
5172 struct net_device *netdev, const u8 *bssid,
5173 gfp_t gfp)
5174{
5175 struct sk_buff *msg;
5176 void *hdr;
5177
fd2120ca 5178 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
5179 if (!msg)
5180 return;
5181
5182 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
5183 if (!hdr) {
5184 nlmsg_free(msg);
5185 return;
5186 }
5187
5188 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5189 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5190 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
5191
5192 if (genlmsg_end(msg, hdr) < 0) {
5193 nlmsg_free(msg);
5194 return;
5195 }
5196
463d0183
JB
5197 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5198 nl80211_mlme_mcgrp.id, gfp);
04a773ad
JB
5199 return;
5200
5201 nla_put_failure:
5202 genlmsg_cancel(msg, hdr);
5203 nlmsg_free(msg);
5204}
5205
a3b8b056
JM
5206void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
5207 struct net_device *netdev, const u8 *addr,
5208 enum nl80211_key_type key_type, int key_id,
e6d6e342 5209 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
5210{
5211 struct sk_buff *msg;
5212 void *hdr;
5213
e6d6e342 5214 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
5215 if (!msg)
5216 return;
5217
5218 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
5219 if (!hdr) {
5220 nlmsg_free(msg);
5221 return;
5222 }
5223
5224 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5225 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5226 if (addr)
5227 NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
5228 NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
5229 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
5230 if (tsc)
5231 NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
5232
5233 if (genlmsg_end(msg, hdr) < 0) {
5234 nlmsg_free(msg);
5235 return;
5236 }
5237
463d0183
JB
5238 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5239 nl80211_mlme_mcgrp.id, gfp);
a3b8b056
JM
5240 return;
5241
5242 nla_put_failure:
5243 genlmsg_cancel(msg, hdr);
5244 nlmsg_free(msg);
5245}
5246
6bad8766
LR
5247void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
5248 struct ieee80211_channel *channel_before,
5249 struct ieee80211_channel *channel_after)
5250{
5251 struct sk_buff *msg;
5252 void *hdr;
5253 struct nlattr *nl_freq;
5254
fd2120ca 5255 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
5256 if (!msg)
5257 return;
5258
5259 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
5260 if (!hdr) {
5261 nlmsg_free(msg);
5262 return;
5263 }
5264
5265 /*
5266 * Since we are applying the beacon hint to a wiphy we know its
5267 * wiphy_idx is valid
5268 */
5269 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
5270
5271 /* Before */
5272 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
5273 if (!nl_freq)
5274 goto nla_put_failure;
5275 if (nl80211_msg_put_channel(msg, channel_before))
5276 goto nla_put_failure;
5277 nla_nest_end(msg, nl_freq);
5278
5279 /* After */
5280 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
5281 if (!nl_freq)
5282 goto nla_put_failure;
5283 if (nl80211_msg_put_channel(msg, channel_after))
5284 goto nla_put_failure;
5285 nla_nest_end(msg, nl_freq);
5286
5287 if (genlmsg_end(msg, hdr) < 0) {
5288 nlmsg_free(msg);
5289 return;
5290 }
5291
463d0183
JB
5292 rcu_read_lock();
5293 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
5294 GFP_ATOMIC);
5295 rcu_read_unlock();
6bad8766
LR
5296
5297 return;
5298
5299nla_put_failure:
5300 genlmsg_cancel(msg, hdr);
5301 nlmsg_free(msg);
5302}
5303
9588bbd5
JM
5304static void nl80211_send_remain_on_chan_event(
5305 int cmd, struct cfg80211_registered_device *rdev,
5306 struct net_device *netdev, u64 cookie,
5307 struct ieee80211_channel *chan,
5308 enum nl80211_channel_type channel_type,
5309 unsigned int duration, gfp_t gfp)
5310{
5311 struct sk_buff *msg;
5312 void *hdr;
5313
5314 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5315 if (!msg)
5316 return;
5317
5318 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
5319 if (!hdr) {
5320 nlmsg_free(msg);
5321 return;
5322 }
5323
5324 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
5325 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
5326 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq);
5327 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type);
5328 NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
5329
5330 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL)
5331 NLA_PUT_U32(msg, NL80211_ATTR_DURATION, duration);
5332
5333 if (genlmsg_end(msg, hdr) < 0) {
5334 nlmsg_free(msg);
5335 return;
5336 }
5337
5338 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5339 nl80211_mlme_mcgrp.id, gfp);
5340 return;
5341
5342 nla_put_failure:
5343 genlmsg_cancel(msg, hdr);
5344 nlmsg_free(msg);
5345}
5346
5347void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
5348 struct net_device *netdev, u64 cookie,
5349 struct ieee80211_channel *chan,
5350 enum nl80211_channel_type channel_type,
5351 unsigned int duration, gfp_t gfp)
5352{
5353 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
5354 rdev, netdev, cookie, chan,
5355 channel_type, duration, gfp);
5356}
5357
5358void nl80211_send_remain_on_channel_cancel(
5359 struct cfg80211_registered_device *rdev, struct net_device *netdev,
5360 u64 cookie, struct ieee80211_channel *chan,
5361 enum nl80211_channel_type channel_type, gfp_t gfp)
5362{
5363 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
5364 rdev, netdev, cookie, chan,
5365 channel_type, 0, gfp);
5366}
5367
98b62183
JB
5368void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
5369 struct net_device *dev, const u8 *mac_addr,
5370 struct station_info *sinfo, gfp_t gfp)
5371{
5372 struct sk_buff *msg;
5373
5374 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
5375 if (!msg)
5376 return;
5377
5378 if (nl80211_send_station(msg, 0, 0, 0, dev, mac_addr, sinfo) < 0) {
5379 nlmsg_free(msg);
5380 return;
5381 }
5382
5383 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
5384 nl80211_mlme_mcgrp.id, gfp);
5385}
5386
55682965
JB
5387/* initialisation/exit functions */
5388
5389int nl80211_init(void)
5390{
0d63cbb5 5391 int err;
55682965 5392
0d63cbb5
MM
5393 err = genl_register_family_with_ops(&nl80211_fam,
5394 nl80211_ops, ARRAY_SIZE(nl80211_ops));
55682965
JB
5395 if (err)
5396 return err;
5397
55682965
JB
5398 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
5399 if (err)
5400 goto err_out;
5401
2a519311
JB
5402 err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp);
5403 if (err)
5404 goto err_out;
5405
73d54c9e
LR
5406 err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
5407 if (err)
5408 goto err_out;
5409
6039f6d2
JM
5410 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
5411 if (err)
5412 goto err_out;
5413
aff89a9b
JB
5414#ifdef CONFIG_NL80211_TESTMODE
5415 err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp);
5416 if (err)
5417 goto err_out;
5418#endif
5419
55682965
JB
5420 return 0;
5421 err_out:
5422 genl_unregister_family(&nl80211_fam);
5423 return err;
5424}
5425
5426void nl80211_exit(void)
5427{
5428 genl_unregister_family(&nl80211_fam);
5429}