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