]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - net/wireless/nl80211.c
cfg80211: make some functions static
[mirror_ubuntu-hirsute-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
5fb628e9
JM
26static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type);
27static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
28 struct genl_info *info,
29 struct cfg80211_crypto_settings *settings,
30 int cipher_limit);
31
4c476991
JB
32static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
33 struct genl_info *info);
34static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
35 struct genl_info *info);
36
55682965
JB
37/* the netlink family */
38static struct genl_family nl80211_fam = {
39 .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */
40 .name = "nl80211", /* have users key off the name instead */
41 .hdrsize = 0, /* no private header */
42 .version = 1, /* no particular meaning now */
43 .maxattr = NL80211_ATTR_MAX,
463d0183 44 .netnsok = true,
4c476991
JB
45 .pre_doit = nl80211_pre_doit,
46 .post_doit = nl80211_post_doit,
55682965
JB
47};
48
79c97e97 49/* internal helper: get rdev and dev */
00918d33
JB
50static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs,
51 struct cfg80211_registered_device **rdev,
52 struct net_device **dev)
55682965
JB
53{
54 int ifindex;
55
bba95fef 56 if (!attrs[NL80211_ATTR_IFINDEX])
55682965
JB
57 return -EINVAL;
58
bba95fef 59 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
00918d33 60 *dev = dev_get_by_index(netns, ifindex);
55682965
JB
61 if (!*dev)
62 return -ENODEV;
63
00918d33 64 *rdev = cfg80211_get_dev_from_ifindex(netns, ifindex);
79c97e97 65 if (IS_ERR(*rdev)) {
55682965 66 dev_put(*dev);
79c97e97 67 return PTR_ERR(*rdev);
55682965
JB
68 }
69
70 return 0;
71}
72
a9455408
JB
73static struct cfg80211_registered_device *
74__cfg80211_rdev_from_info(struct genl_info *info)
75{
76 int ifindex;
77 struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL;
78 struct net_device *dev;
79 int err = -EINVAL;
80
81 assert_cfg80211_lock();
82
83 if (info->attrs[NL80211_ATTR_WIPHY]) {
84 bywiphyidx = cfg80211_rdev_by_wiphy_idx(
85 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY]));
86 err = -ENODEV;
87 }
88
89 if (info->attrs[NL80211_ATTR_IFINDEX]) {
90 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
91 dev = dev_get_by_index(genl_info_net(info), ifindex);
92 if (dev) {
93 if (dev->ieee80211_ptr)
94 byifidx =
95 wiphy_to_dev(dev->ieee80211_ptr->wiphy);
96 dev_put(dev);
97 }
98 err = -ENODEV;
99 }
100
101 if (bywiphyidx && byifidx) {
102 if (bywiphyidx != byifidx)
103 return ERR_PTR(-EINVAL);
104 else
105 return bywiphyidx; /* == byifidx */
106 }
107 if (bywiphyidx)
108 return bywiphyidx;
109
110 if (byifidx)
111 return byifidx;
112
113 return ERR_PTR(err);
114}
115
116/*
117 * This function returns a pointer to the driver
118 * that the genl_info item that is passed refers to.
119 * If successful, it returns non-NULL and also locks
120 * the driver's mutex!
121 *
122 * This means that you need to call cfg80211_unlock_rdev()
123 * before being allowed to acquire &cfg80211_mutex!
124 *
125 * This is necessary because we need to lock the global
126 * mutex to get an item off the list safely, and then
127 * we lock the rdev mutex so it doesn't go away under us.
128 *
129 * We don't want to keep cfg80211_mutex locked
130 * for all the time in order to allow requests on
131 * other interfaces to go through at the same time.
132 *
133 * The result of this can be a PTR_ERR and hence must
134 * be checked with IS_ERR() for errors.
135 */
136static struct cfg80211_registered_device *
137cfg80211_get_dev_from_info(struct genl_info *info)
138{
139 struct cfg80211_registered_device *rdev;
140
141 mutex_lock(&cfg80211_mutex);
142 rdev = __cfg80211_rdev_from_info(info);
143
144 /* if it is not an error we grab the lock on
145 * it to assure it won't be going away while
146 * we operate on it */
147 if (!IS_ERR(rdev))
148 mutex_lock(&rdev->mtx);
149
150 mutex_unlock(&cfg80211_mutex);
151
152 return rdev;
153}
154
55682965 155/* policy for the attributes */
b54452b0 156static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
55682965
JB
157 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
158 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 159 .len = 20-1 },
31888487 160 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
72bdcf34 161 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 162 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
b9a5f8ca
JM
163 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
164 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
165 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
166 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 167 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
55682965
JB
168
169 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
170 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
171 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 172
e007b857
EP
173 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
174 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
41ade00f 175
b9454e83 176 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
177 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
178 .len = WLAN_MAX_KEY_LEN },
179 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
180 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
181 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 182 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
e31b8213 183 [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 },
ed1b6cc7
JB
184
185 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
186 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
187 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
188 .len = IEEE80211_MAX_DATA_LEN },
189 [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY,
190 .len = IEEE80211_MAX_DATA_LEN },
5727ef1b
JB
191 [NL80211_ATTR_STA_AID] = { .type = NLA_U16 },
192 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
193 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
194 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
195 .len = NL80211_MAX_SUPP_RATES },
2ec600d6 196 [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 },
5727ef1b 197 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 198 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 199 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 200 .len = IEEE80211_MAX_MESH_ID_LEN },
2ec600d6 201 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 202
b2e1b302
LR
203 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
204 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
205
9f1ba906
JM
206 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
207 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
208 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
209 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
210 .len = NL80211_MAX_SUPP_RATES },
50b12f59 211 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 212
24bdd9f4 213 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 214 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 215
6c739419 216 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
217
218 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
219 [NL80211_ATTR_IE] = { .type = NLA_BINARY,
220 .len = IEEE80211_MAX_DATA_LEN },
2a519311
JB
221 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
222 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
223
224 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
225 .len = IEEE80211_MAX_SSID_LEN },
226 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
227 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 228 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 229 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
dc6382ce 230 [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
eccb8e8f
JB
231 [NL80211_ATTR_STA_FLAGS2] = {
232 .len = sizeof(struct nl80211_sta_flag_update),
233 },
3f77316c 234 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
235 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
236 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
b23aa676
SO
237 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
238 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
239 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 240 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 241 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
67fbb16b
SO
242 [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
243 .len = WLAN_PMKID_LEN },
9588bbd5
JM
244 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
245 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 246 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
247 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
248 .len = IEEE80211_MAX_DATA_LEN },
249 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ffb9eb3d 250 [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 },
d6dc1a38 251 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 252 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 253 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
254 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
255 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 256 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
257 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
258 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 259 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 260 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 261 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 262 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
9c3990aa 263 [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 },
bbe6ad6d 264 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 265 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 266 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
32e9de84 267 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
9946ecfb
JM
268 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
269 .len = IEEE80211_MAX_DATA_LEN },
270 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
271 .len = IEEE80211_MAX_DATA_LEN },
f4b34b55 272 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 273 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 274 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
275 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
276 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
277 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
278 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
279 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
e247bd90 280 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
281 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
282 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 283 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
284 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
285 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
286 .len = NL80211_HT_CAPABILITY_LEN
287 },
1d9d9213 288 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 289 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 290 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
55682965
JB
291};
292
e31b8213 293/* policy for the key attributes */
b54452b0 294static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 295 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
296 [NL80211_KEY_IDX] = { .type = NLA_U8 },
297 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 298 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
299 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
300 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
e31b8213 301 [NL80211_KEY_TYPE] = { .type = NLA_U32 },
dbd2fd65
JB
302 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
303};
304
305/* policy for the key default flags */
306static const struct nla_policy
307nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
308 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
309 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
310};
311
ff1b6e69
JB
312/* policy for WoWLAN attributes */
313static const struct nla_policy
314nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
315 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
316 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
317 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
318 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
319 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
320 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
321 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
322 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
ff1b6e69
JB
323};
324
e5497d76
JB
325/* policy for GTK rekey offload attributes */
326static const struct nla_policy
327nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
328 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
329 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
330 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
331};
332
a1f1c21c
LC
333static const struct nla_policy
334nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 335 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c
LC
336 .len = IEEE80211_MAX_SSID_LEN },
337};
338
a043897a
HS
339/* ifidx get helper */
340static int nl80211_get_ifidx(struct netlink_callback *cb)
341{
342 int res;
343
344 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
345 nl80211_fam.attrbuf, nl80211_fam.maxattr,
346 nl80211_policy);
347 if (res)
348 return res;
349
350 if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])
351 return -EINVAL;
352
353 res = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);
354 if (!res)
355 return -EINVAL;
356 return res;
357}
358
67748893
JB
359static int nl80211_prepare_netdev_dump(struct sk_buff *skb,
360 struct netlink_callback *cb,
361 struct cfg80211_registered_device **rdev,
362 struct net_device **dev)
363{
364 int ifidx = cb->args[0];
365 int err;
366
367 if (!ifidx)
368 ifidx = nl80211_get_ifidx(cb);
369 if (ifidx < 0)
370 return ifidx;
371
372 cb->args[0] = ifidx;
373
374 rtnl_lock();
375
376 *dev = __dev_get_by_index(sock_net(skb->sk), ifidx);
377 if (!*dev) {
378 err = -ENODEV;
379 goto out_rtnl;
380 }
381
382 *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3cc25e51
FF
383 if (IS_ERR(*rdev)) {
384 err = PTR_ERR(*rdev);
67748893
JB
385 goto out_rtnl;
386 }
387
388 return 0;
389 out_rtnl:
390 rtnl_unlock();
391 return err;
392}
393
394static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev)
395{
396 cfg80211_unlock_rdev(rdev);
397 rtnl_unlock();
398}
399
f4a11bb0
JB
400/* IE validation */
401static bool is_valid_ie_attr(const struct nlattr *attr)
402{
403 const u8 *pos;
404 int len;
405
406 if (!attr)
407 return true;
408
409 pos = nla_data(attr);
410 len = nla_len(attr);
411
412 while (len) {
413 u8 elemlen;
414
415 if (len < 2)
416 return false;
417 len -= 2;
418
419 elemlen = pos[1];
420 if (elemlen > len)
421 return false;
422
423 len -= elemlen;
424 pos += 2 + elemlen;
425 }
426
427 return true;
428}
429
55682965
JB
430/* message building helper */
431static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
432 int flags, u8 cmd)
433{
434 /* since there is no private header just add the generic one */
435 return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
436}
437
5dab3b8a
LR
438static int nl80211_msg_put_channel(struct sk_buff *msg,
439 struct ieee80211_channel *chan)
440{
9360ffd1
DM
441 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
442 chan->center_freq))
443 goto nla_put_failure;
5dab3b8a 444
9360ffd1
DM
445 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
446 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
447 goto nla_put_failure;
448 if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
449 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN))
450 goto nla_put_failure;
451 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
452 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
453 goto nla_put_failure;
454 if ((chan->flags & IEEE80211_CHAN_RADAR) &&
455 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
456 goto nla_put_failure;
5dab3b8a 457
9360ffd1
DM
458 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
459 DBM_TO_MBM(chan->max_power)))
460 goto nla_put_failure;
5dab3b8a
LR
461
462 return 0;
463
464 nla_put_failure:
465 return -ENOBUFS;
466}
467
55682965
JB
468/* netlink command implementations */
469
b9454e83
JB
470struct key_parse {
471 struct key_params p;
472 int idx;
e31b8213 473 int type;
b9454e83 474 bool def, defmgmt;
dbd2fd65 475 bool def_uni, def_multi;
b9454e83
JB
476};
477
478static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
479{
480 struct nlattr *tb[NL80211_KEY_MAX + 1];
481 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
482 nl80211_key_policy);
483 if (err)
484 return err;
485
486 k->def = !!tb[NL80211_KEY_DEFAULT];
487 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
488
dbd2fd65
JB
489 if (k->def) {
490 k->def_uni = true;
491 k->def_multi = true;
492 }
493 if (k->defmgmt)
494 k->def_multi = true;
495
b9454e83
JB
496 if (tb[NL80211_KEY_IDX])
497 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
498
499 if (tb[NL80211_KEY_DATA]) {
500 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
501 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
502 }
503
504 if (tb[NL80211_KEY_SEQ]) {
505 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
506 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
507 }
508
509 if (tb[NL80211_KEY_CIPHER])
510 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
511
e31b8213
JB
512 if (tb[NL80211_KEY_TYPE]) {
513 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
514 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
515 return -EINVAL;
516 }
517
dbd2fd65
JB
518 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
519 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
2da8f419
JB
520 err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
521 tb[NL80211_KEY_DEFAULT_TYPES],
522 nl80211_key_default_policy);
dbd2fd65
JB
523 if (err)
524 return err;
525
526 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
527 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
528 }
529
b9454e83
JB
530 return 0;
531}
532
533static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
534{
535 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
536 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
537 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
538 }
539
540 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
541 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
542 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
543 }
544
545 if (info->attrs[NL80211_ATTR_KEY_IDX])
546 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
547
548 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
549 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
550
551 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
552 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
553
dbd2fd65
JB
554 if (k->def) {
555 k->def_uni = true;
556 k->def_multi = true;
557 }
558 if (k->defmgmt)
559 k->def_multi = true;
560
e31b8213
JB
561 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
562 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
563 if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES)
564 return -EINVAL;
565 }
566
dbd2fd65
JB
567 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
568 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
569 int err = nla_parse_nested(
570 kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1,
571 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
572 nl80211_key_default_policy);
573 if (err)
574 return err;
575
576 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
577 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
578 }
579
b9454e83
JB
580 return 0;
581}
582
583static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
584{
585 int err;
586
587 memset(k, 0, sizeof(*k));
588 k->idx = -1;
e31b8213 589 k->type = -1;
b9454e83
JB
590
591 if (info->attrs[NL80211_ATTR_KEY])
592 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
593 else
594 err = nl80211_parse_key_old(info, k);
595
596 if (err)
597 return err;
598
599 if (k->def && k->defmgmt)
600 return -EINVAL;
601
dbd2fd65
JB
602 if (k->defmgmt) {
603 if (k->def_uni || !k->def_multi)
604 return -EINVAL;
605 }
606
b9454e83
JB
607 if (k->idx != -1) {
608 if (k->defmgmt) {
609 if (k->idx < 4 || k->idx > 5)
610 return -EINVAL;
611 } else if (k->def) {
612 if (k->idx < 0 || k->idx > 3)
613 return -EINVAL;
614 } else {
615 if (k->idx < 0 || k->idx > 5)
616 return -EINVAL;
617 }
618 }
619
620 return 0;
621}
622
fffd0934
JB
623static struct cfg80211_cached_keys *
624nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
625 struct nlattr *keys)
626{
627 struct key_parse parse;
628 struct nlattr *key;
629 struct cfg80211_cached_keys *result;
630 int rem, err, def = 0;
631
632 result = kzalloc(sizeof(*result), GFP_KERNEL);
633 if (!result)
634 return ERR_PTR(-ENOMEM);
635
636 result->def = -1;
637 result->defmgmt = -1;
638
639 nla_for_each_nested(key, keys, rem) {
640 memset(&parse, 0, sizeof(parse));
641 parse.idx = -1;
642
643 err = nl80211_parse_key_new(key, &parse);
644 if (err)
645 goto error;
646 err = -EINVAL;
647 if (!parse.p.key)
648 goto error;
649 if (parse.idx < 0 || parse.idx > 4)
650 goto error;
651 if (parse.def) {
652 if (def)
653 goto error;
654 def = 1;
655 result->def = parse.idx;
dbd2fd65
JB
656 if (!parse.def_uni || !parse.def_multi)
657 goto error;
fffd0934
JB
658 } else if (parse.defmgmt)
659 goto error;
660 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 661 parse.idx, false, NULL);
fffd0934
JB
662 if (err)
663 goto error;
664 result->params[parse.idx].cipher = parse.p.cipher;
665 result->params[parse.idx].key_len = parse.p.key_len;
666 result->params[parse.idx].key = result->data[parse.idx];
667 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
668 }
669
670 return result;
671 error:
672 kfree(result);
673 return ERR_PTR(err);
674}
675
676static int nl80211_key_allowed(struct wireless_dev *wdev)
677{
678 ASSERT_WDEV_LOCK(wdev);
679
fffd0934
JB
680 switch (wdev->iftype) {
681 case NL80211_IFTYPE_AP:
682 case NL80211_IFTYPE_AP_VLAN:
074ac8df 683 case NL80211_IFTYPE_P2P_GO:
ff973af7 684 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
685 break;
686 case NL80211_IFTYPE_ADHOC:
687 if (!wdev->current_bss)
688 return -ENOLINK;
689 break;
690 case NL80211_IFTYPE_STATION:
074ac8df 691 case NL80211_IFTYPE_P2P_CLIENT:
fffd0934
JB
692 if (wdev->sme_state != CFG80211_SME_CONNECTED)
693 return -ENOLINK;
694 break;
695 default:
696 return -EINVAL;
697 }
698
699 return 0;
700}
701
7527a782
JB
702static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
703{
704 struct nlattr *nl_modes = nla_nest_start(msg, attr);
705 int i;
706
707 if (!nl_modes)
708 goto nla_put_failure;
709
710 i = 0;
711 while (ifmodes) {
9360ffd1
DM
712 if ((ifmodes & 1) && nla_put_flag(msg, i))
713 goto nla_put_failure;
7527a782
JB
714 ifmodes >>= 1;
715 i++;
716 }
717
718 nla_nest_end(msg, nl_modes);
719 return 0;
720
721nla_put_failure:
722 return -ENOBUFS;
723}
724
725static int nl80211_put_iface_combinations(struct wiphy *wiphy,
726 struct sk_buff *msg)
727{
728 struct nlattr *nl_combis;
729 int i, j;
730
731 nl_combis = nla_nest_start(msg,
732 NL80211_ATTR_INTERFACE_COMBINATIONS);
733 if (!nl_combis)
734 goto nla_put_failure;
735
736 for (i = 0; i < wiphy->n_iface_combinations; i++) {
737 const struct ieee80211_iface_combination *c;
738 struct nlattr *nl_combi, *nl_limits;
739
740 c = &wiphy->iface_combinations[i];
741
742 nl_combi = nla_nest_start(msg, i + 1);
743 if (!nl_combi)
744 goto nla_put_failure;
745
746 nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS);
747 if (!nl_limits)
748 goto nla_put_failure;
749
750 for (j = 0; j < c->n_limits; j++) {
751 struct nlattr *nl_limit;
752
753 nl_limit = nla_nest_start(msg, j + 1);
754 if (!nl_limit)
755 goto nla_put_failure;
9360ffd1
DM
756 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
757 c->limits[j].max))
758 goto nla_put_failure;
7527a782
JB
759 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
760 c->limits[j].types))
761 goto nla_put_failure;
762 nla_nest_end(msg, nl_limit);
763 }
764
765 nla_nest_end(msg, nl_limits);
766
9360ffd1
DM
767 if (c->beacon_int_infra_match &&
768 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
769 goto nla_put_failure;
770 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
771 c->num_different_channels) ||
772 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
773 c->max_interfaces))
774 goto nla_put_failure;
7527a782
JB
775
776 nla_nest_end(msg, nl_combi);
777 }
778
779 nla_nest_end(msg, nl_combis);
780
781 return 0;
782nla_put_failure:
783 return -ENOBUFS;
784}
785
55682965
JB
786static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
787 struct cfg80211_registered_device *dev)
788{
789 void *hdr;
ee688b00
JB
790 struct nlattr *nl_bands, *nl_band;
791 struct nlattr *nl_freqs, *nl_freq;
792 struct nlattr *nl_rates, *nl_rate;
8fdc621d 793 struct nlattr *nl_cmds;
ee688b00
JB
794 enum ieee80211_band band;
795 struct ieee80211_channel *chan;
796 struct ieee80211_rate *rate;
797 int i;
2e161f78
JB
798 const struct ieee80211_txrx_stypes *mgmt_stypes =
799 dev->wiphy.mgmt_stypes;
55682965
JB
800
801 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
802 if (!hdr)
803 return -1;
804
9360ffd1
DM
805 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) ||
806 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)) ||
807 nla_put_u32(msg, NL80211_ATTR_GENERATION,
808 cfg80211_rdev_list_generation) ||
809 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
810 dev->wiphy.retry_short) ||
811 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
812 dev->wiphy.retry_long) ||
813 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
814 dev->wiphy.frag_threshold) ||
815 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
816 dev->wiphy.rts_threshold) ||
817 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
818 dev->wiphy.coverage_class) ||
819 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
820 dev->wiphy.max_scan_ssids) ||
821 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
822 dev->wiphy.max_sched_scan_ssids) ||
823 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
824 dev->wiphy.max_scan_ie_len) ||
825 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
826 dev->wiphy.max_sched_scan_ie_len) ||
827 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
828 dev->wiphy.max_match_sets))
829 goto nla_put_failure;
830
831 if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
832 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
833 goto nla_put_failure;
834 if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
835 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
836 goto nla_put_failure;
837 if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
838 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
839 goto nla_put_failure;
840 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
841 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
842 goto nla_put_failure;
843 if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
844 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
845 goto nla_put_failure;
846 if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
847 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
848 goto nla_put_failure;
849
850 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
851 sizeof(u32) * dev->wiphy.n_cipher_suites,
852 dev->wiphy.cipher_suites))
853 goto nla_put_failure;
854
855 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
856 dev->wiphy.max_num_pmkids))
857 goto nla_put_failure;
858
859 if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
860 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
861 goto nla_put_failure;
862
863 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
864 dev->wiphy.available_antennas_tx) ||
865 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
866 dev->wiphy.available_antennas_rx))
867 goto nla_put_failure;
868
869 if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
870 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
871 dev->wiphy.probe_resp_offload))
872 goto nla_put_failure;
87bbbe22 873
7f531e03
BR
874 if ((dev->wiphy.available_antennas_tx ||
875 dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) {
afe0cbf8
BR
876 u32 tx_ant = 0, rx_ant = 0;
877 int res;
878 res = dev->ops->get_antenna(&dev->wiphy, &tx_ant, &rx_ant);
879 if (!res) {
9360ffd1
DM
880 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX,
881 tx_ant) ||
882 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX,
883 rx_ant))
884 goto nla_put_failure;
afe0cbf8
BR
885 }
886 }
887
7527a782
JB
888 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
889 dev->wiphy.interface_modes))
f59ac048
LR
890 goto nla_put_failure;
891
ee688b00
JB
892 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
893 if (!nl_bands)
894 goto nla_put_failure;
895
896 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
897 if (!dev->wiphy.bands[band])
898 continue;
899
900 nl_band = nla_nest_start(msg, band);
901 if (!nl_band)
902 goto nla_put_failure;
903
d51626df 904 /* add HT info */
9360ffd1
DM
905 if (dev->wiphy.bands[band]->ht_cap.ht_supported &&
906 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
907 sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
908 &dev->wiphy.bands[band]->ht_cap.mcs) ||
909 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
910 dev->wiphy.bands[band]->ht_cap.cap) ||
911 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
912 dev->wiphy.bands[band]->ht_cap.ampdu_factor) ||
913 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
914 dev->wiphy.bands[band]->ht_cap.ampdu_density)))
915 goto nla_put_failure;
d51626df 916
ee688b00
JB
917 /* add frequencies */
918 nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
919 if (!nl_freqs)
920 goto nla_put_failure;
921
922 for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) {
923 nl_freq = nla_nest_start(msg, i);
924 if (!nl_freq)
925 goto nla_put_failure;
926
927 chan = &dev->wiphy.bands[band]->channels[i];
5dab3b8a
LR
928
929 if (nl80211_msg_put_channel(msg, chan))
930 goto nla_put_failure;
e2f367f2 931
ee688b00
JB
932 nla_nest_end(msg, nl_freq);
933 }
934
935 nla_nest_end(msg, nl_freqs);
936
937 /* add bitrates */
938 nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES);
939 if (!nl_rates)
940 goto nla_put_failure;
941
942 for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) {
943 nl_rate = nla_nest_start(msg, i);
944 if (!nl_rate)
945 goto nla_put_failure;
946
947 rate = &dev->wiphy.bands[band]->bitrates[i];
9360ffd1
DM
948 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
949 rate->bitrate))
950 goto nla_put_failure;
951 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
952 nla_put_flag(msg,
953 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
954 goto nla_put_failure;
ee688b00
JB
955
956 nla_nest_end(msg, nl_rate);
957 }
958
959 nla_nest_end(msg, nl_rates);
960
961 nla_nest_end(msg, nl_band);
962 }
963 nla_nest_end(msg, nl_bands);
964
8fdc621d
JB
965 nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS);
966 if (!nl_cmds)
967 goto nla_put_failure;
968
969 i = 0;
970#define CMD(op, n) \
971 do { \
972 if (dev->ops->op) { \
973 i++; \
9360ffd1
DM
974 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
975 goto nla_put_failure; \
8fdc621d
JB
976 } \
977 } while (0)
978
979 CMD(add_virtual_intf, NEW_INTERFACE);
980 CMD(change_virtual_intf, SET_INTERFACE);
981 CMD(add_key, NEW_KEY);
8860020e 982 CMD(start_ap, START_AP);
8fdc621d
JB
983 CMD(add_station, NEW_STATION);
984 CMD(add_mpath, NEW_MPATH);
24bdd9f4 985 CMD(update_mesh_config, SET_MESH_CONFIG);
8fdc621d 986 CMD(change_bss, SET_BSS);
636a5d36
JM
987 CMD(auth, AUTHENTICATE);
988 CMD(assoc, ASSOCIATE);
989 CMD(deauth, DEAUTHENTICATE);
990 CMD(disassoc, DISASSOCIATE);
04a773ad 991 CMD(join_ibss, JOIN_IBSS);
29cbe68c 992 CMD(join_mesh, JOIN_MESH);
67fbb16b
SO
993 CMD(set_pmksa, SET_PMKSA);
994 CMD(del_pmksa, DEL_PMKSA);
995 CMD(flush_pmksa, FLUSH_PMKSA);
7c4ef712
JB
996 if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
997 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
13ae75b1 998 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
2e161f78 999 CMD(mgmt_tx, FRAME);
f7ca38df 1000 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
5be83de5 1001 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
463d0183 1002 i++;
9360ffd1
DM
1003 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1004 goto nla_put_failure;
463d0183 1005 }
e8c9bd5b 1006 if (dev->ops->set_monitor_channel || dev->ops->start_ap ||
cc1d2806 1007 dev->ops->join_mesh) {
aa430da4
JB
1008 i++;
1009 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1010 goto nla_put_failure;
1011 }
e8347eba 1012 CMD(set_wds_peer, SET_WDS_PEER);
109086ce
AN
1013 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1014 CMD(tdls_mgmt, TDLS_MGMT);
1015 CMD(tdls_oper, TDLS_OPER);
1016 }
807f8a8c
LC
1017 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
1018 CMD(sched_scan_start, START_SCHED_SCAN);
7f6cf311 1019 CMD(probe_client, PROBE_CLIENT);
1d9d9213 1020 CMD(set_noack_map, SET_NOACK_MAP);
5e760230
JB
1021 if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1022 i++;
9360ffd1
DM
1023 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1024 goto nla_put_failure;
5e760230 1025 }
8fdc621d 1026
4745fc09
KV
1027#ifdef CONFIG_NL80211_TESTMODE
1028 CMD(testmode_cmd, TESTMODE);
1029#endif
1030
8fdc621d 1031#undef CMD
b23aa676 1032
6829c878 1033 if (dev->ops->connect || dev->ops->auth) {
b23aa676 1034 i++;
9360ffd1
DM
1035 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1036 goto nla_put_failure;
b23aa676
SO
1037 }
1038
6829c878 1039 if (dev->ops->disconnect || dev->ops->deauth) {
b23aa676 1040 i++;
9360ffd1
DM
1041 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1042 goto nla_put_failure;
b23aa676
SO
1043 }
1044
8fdc621d
JB
1045 nla_nest_end(msg, nl_cmds);
1046
7c4ef712 1047 if (dev->ops->remain_on_channel &&
9360ffd1
DM
1048 (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
1049 nla_put_u32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1050 dev->wiphy.max_remain_on_channel_duration))
1051 goto nla_put_failure;
a293911d 1052
9360ffd1
DM
1053 if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
1054 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
1055 goto nla_put_failure;
f7ca38df 1056
2e161f78
JB
1057 if (mgmt_stypes) {
1058 u16 stypes;
1059 struct nlattr *nl_ftypes, *nl_ifs;
1060 enum nl80211_iftype ift;
1061
1062 nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES);
1063 if (!nl_ifs)
1064 goto nla_put_failure;
1065
1066 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1067 nl_ftypes = nla_nest_start(msg, ift);
1068 if (!nl_ftypes)
1069 goto nla_put_failure;
1070 i = 0;
1071 stypes = mgmt_stypes[ift].tx;
1072 while (stypes) {
9360ffd1
DM
1073 if ((stypes & 1) &&
1074 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1075 (i << 4) | IEEE80211_FTYPE_MGMT))
1076 goto nla_put_failure;
2e161f78
JB
1077 stypes >>= 1;
1078 i++;
1079 }
1080 nla_nest_end(msg, nl_ftypes);
1081 }
1082
74b70a4e
JB
1083 nla_nest_end(msg, nl_ifs);
1084
2e161f78
JB
1085 nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES);
1086 if (!nl_ifs)
1087 goto nla_put_failure;
1088
1089 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
1090 nl_ftypes = nla_nest_start(msg, ift);
1091 if (!nl_ftypes)
1092 goto nla_put_failure;
1093 i = 0;
1094 stypes = mgmt_stypes[ift].rx;
1095 while (stypes) {
9360ffd1
DM
1096 if ((stypes & 1) &&
1097 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1098 (i << 4) | IEEE80211_FTYPE_MGMT))
1099 goto nla_put_failure;
2e161f78
JB
1100 stypes >>= 1;
1101 i++;
1102 }
1103 nla_nest_end(msg, nl_ftypes);
1104 }
1105 nla_nest_end(msg, nl_ifs);
1106 }
1107
ff1b6e69
JB
1108 if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) {
1109 struct nlattr *nl_wowlan;
1110
1111 nl_wowlan = nla_nest_start(msg,
1112 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1113 if (!nl_wowlan)
1114 goto nla_put_failure;
1115
9360ffd1
DM
1116 if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) &&
1117 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1118 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) &&
1119 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1120 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) &&
1121 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1122 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
1123 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1124 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
1125 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1126 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
1127 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1128 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
1129 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1130 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
1131 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1132 goto nla_put_failure;
ff1b6e69
JB
1133 if (dev->wiphy.wowlan.n_patterns) {
1134 struct nl80211_wowlan_pattern_support pat = {
1135 .max_patterns = dev->wiphy.wowlan.n_patterns,
1136 .min_pattern_len =
1137 dev->wiphy.wowlan.pattern_min_len,
1138 .max_pattern_len =
1139 dev->wiphy.wowlan.pattern_max_len,
1140 };
9360ffd1
DM
1141 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1142 sizeof(pat), &pat))
1143 goto nla_put_failure;
ff1b6e69
JB
1144 }
1145
1146 nla_nest_end(msg, nl_wowlan);
1147 }
1148
7527a782
JB
1149 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1150 dev->wiphy.software_iftypes))
1151 goto nla_put_failure;
1152
1153 if (nl80211_put_iface_combinations(&dev->wiphy, msg))
1154 goto nla_put_failure;
1155
9360ffd1
DM
1156 if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
1157 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1158 dev->wiphy.ap_sme_capa))
1159 goto nla_put_failure;
562a7480 1160
9360ffd1
DM
1161 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS,
1162 dev->wiphy.features))
1163 goto nla_put_failure;
1f074bd8 1164
9360ffd1
DM
1165 if (dev->wiphy.ht_capa_mod_mask &&
1166 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1167 sizeof(*dev->wiphy.ht_capa_mod_mask),
1168 dev->wiphy.ht_capa_mod_mask))
1169 goto nla_put_failure;
7e7c8926 1170
55682965
JB
1171 return genlmsg_end(msg, hdr);
1172
1173 nla_put_failure:
bc3ed28c
TG
1174 genlmsg_cancel(msg, hdr);
1175 return -EMSGSIZE;
55682965
JB
1176}
1177
1178static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1179{
1180 int idx = 0;
1181 int start = cb->args[0];
1182 struct cfg80211_registered_device *dev;
1183
a1794390 1184 mutex_lock(&cfg80211_mutex);
79c97e97 1185 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
463d0183
JB
1186 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
1187 continue;
b4637271 1188 if (++idx <= start)
55682965
JB
1189 continue;
1190 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
1191 cb->nlh->nlmsg_seq, NLM_F_MULTI,
b4637271
JV
1192 dev) < 0) {
1193 idx--;
55682965 1194 break;
b4637271 1195 }
55682965 1196 }
a1794390 1197 mutex_unlock(&cfg80211_mutex);
55682965
JB
1198
1199 cb->args[0] = idx;
1200
1201 return skb->len;
1202}
1203
1204static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
1205{
1206 struct sk_buff *msg;
4c476991 1207 struct cfg80211_registered_device *dev = info->user_ptr[0];
55682965 1208
fd2120ca 1209 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 1210 if (!msg)
4c476991 1211 return -ENOMEM;
55682965 1212
4c476991
JB
1213 if (nl80211_send_wiphy(msg, info->snd_pid, info->snd_seq, 0, dev) < 0) {
1214 nlmsg_free(msg);
1215 return -ENOBUFS;
1216 }
55682965 1217
134e6375 1218 return genlmsg_reply(msg, info);
55682965
JB
1219}
1220
31888487
JM
1221static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
1222 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
1223 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
1224 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
1225 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
1226 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
1227};
1228
1229static int parse_txq_params(struct nlattr *tb[],
1230 struct ieee80211_txq_params *txq_params)
1231{
a3304b0a 1232 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
1233 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
1234 !tb[NL80211_TXQ_ATTR_AIFS])
1235 return -EINVAL;
1236
a3304b0a 1237 txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
1238 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
1239 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
1240 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
1241 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
1242
a3304b0a
JB
1243 if (txq_params->ac >= NL80211_NUM_ACS)
1244 return -EINVAL;
1245
31888487
JM
1246 return 0;
1247}
1248
f444de05
JB
1249static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
1250{
1251 /*
cc1d2806
JB
1252 * You can only set the channel explicitly for WDS interfaces,
1253 * all others have their channel managed via their respective
1254 * "establish a connection" command (connect, join, ...)
1255 *
1256 * For AP/GO and mesh mode, the channel can be set with the
1257 * channel userspace API, but is only stored and passed to the
1258 * low-level driver when the AP starts or the mesh is joined.
1259 * This is for backward compatibility, userspace can also give
1260 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
1261 *
1262 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
1263 * whatever else is going on, so they have their own special
1264 * operation to set the monitor channel if possible.
f444de05
JB
1265 */
1266 return !wdev ||
1267 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 1268 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
1269 wdev->iftype == NL80211_IFTYPE_MONITOR ||
1270 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
1271}
1272
cd6c6598
JB
1273static bool nl80211_valid_channel_type(struct genl_info *info,
1274 enum nl80211_channel_type *channel_type)
1275{
1276 enum nl80211_channel_type tmp;
1277
1278 if (!info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE])
1279 return false;
1280
1281 tmp = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
1282 if (tmp != NL80211_CHAN_NO_HT &&
1283 tmp != NL80211_CHAN_HT20 &&
1284 tmp != NL80211_CHAN_HT40PLUS &&
1285 tmp != NL80211_CHAN_HT40MINUS)
1286 return false;
1287
1288 if (channel_type)
1289 *channel_type = tmp;
1290
1291 return true;
1292}
1293
f444de05
JB
1294static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1295 struct wireless_dev *wdev,
1296 struct genl_info *info)
1297{
aa430da4 1298 struct ieee80211_channel *channel;
f444de05
JB
1299 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
1300 u32 freq;
1301 int result;
e8c9bd5b
JB
1302 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1303
1304 if (wdev)
1305 iftype = wdev->iftype;
f444de05
JB
1306
1307 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1308 return -EINVAL;
1309
1310 if (!nl80211_can_set_dev_channel(wdev))
1311 return -EOPNOTSUPP;
1312
cd6c6598
JB
1313 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
1314 !nl80211_valid_channel_type(info, &channel_type))
1315 return -EINVAL;
f444de05
JB
1316
1317 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1318
1319 mutex_lock(&rdev->devlist_mtx);
e8c9bd5b 1320 switch (iftype) {
aa430da4
JB
1321 case NL80211_IFTYPE_AP:
1322 case NL80211_IFTYPE_P2P_GO:
1323 if (wdev->beacon_interval) {
1324 result = -EBUSY;
1325 break;
1326 }
1327 channel = rdev_freq_to_chan(rdev, freq, channel_type);
1328 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
1329 channel,
1330 channel_type)) {
1331 result = -EINVAL;
1332 break;
1333 }
1334 wdev->preset_chan = channel;
1335 wdev->preset_chantype = channel_type;
1336 result = 0;
1337 break;
cc1d2806
JB
1338 case NL80211_IFTYPE_MESH_POINT:
1339 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type);
1340 break;
e8c9bd5b
JB
1341 case NL80211_IFTYPE_MONITOR:
1342 result = cfg80211_set_monitor_channel(rdev, freq, channel_type);
1343 break;
aa430da4 1344 default:
e8c9bd5b 1345 result = -EINVAL;
f444de05
JB
1346 }
1347 mutex_unlock(&rdev->devlist_mtx);
1348
1349 return result;
1350}
1351
1352static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
1353{
4c476991
JB
1354 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1355 struct net_device *netdev = info->user_ptr[1];
f444de05 1356
4c476991 1357 return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info);
f444de05
JB
1358}
1359
e8347eba
BJ
1360static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
1361{
43b19952
JB
1362 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1363 struct net_device *dev = info->user_ptr[1];
1364 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 1365 const u8 *bssid;
e8347eba
BJ
1366
1367 if (!info->attrs[NL80211_ATTR_MAC])
1368 return -EINVAL;
1369
43b19952
JB
1370 if (netif_running(dev))
1371 return -EBUSY;
e8347eba 1372
43b19952
JB
1373 if (!rdev->ops->set_wds_peer)
1374 return -EOPNOTSUPP;
e8347eba 1375
43b19952
JB
1376 if (wdev->iftype != NL80211_IFTYPE_WDS)
1377 return -EOPNOTSUPP;
e8347eba
BJ
1378
1379 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
43b19952 1380 return rdev->ops->set_wds_peer(wdev->wiphy, dev, bssid);
e8347eba
BJ
1381}
1382
1383
55682965
JB
1384static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1385{
1386 struct cfg80211_registered_device *rdev;
f444de05
JB
1387 struct net_device *netdev = NULL;
1388 struct wireless_dev *wdev;
a1e567c8 1389 int result = 0, rem_txq_params = 0;
31888487 1390 struct nlattr *nl_txq_params;
b9a5f8ca
JM
1391 u32 changed;
1392 u8 retry_short = 0, retry_long = 0;
1393 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 1394 u8 coverage_class = 0;
55682965 1395
f444de05
JB
1396 /*
1397 * Try to find the wiphy and netdev. Normally this
1398 * function shouldn't need the netdev, but this is
1399 * done for backward compatibility -- previously
1400 * setting the channel was done per wiphy, but now
1401 * it is per netdev. Previous userland like hostapd
1402 * also passed a netdev to set_wiphy, so that it is
1403 * possible to let that go to the right netdev!
1404 */
4bbf4d56
JB
1405 mutex_lock(&cfg80211_mutex);
1406
f444de05
JB
1407 if (info->attrs[NL80211_ATTR_IFINDEX]) {
1408 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
1409
1410 netdev = dev_get_by_index(genl_info_net(info), ifindex);
1411 if (netdev && netdev->ieee80211_ptr) {
1412 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy);
1413 mutex_lock(&rdev->mtx);
1414 } else
1415 netdev = NULL;
4bbf4d56
JB
1416 }
1417
f444de05
JB
1418 if (!netdev) {
1419 rdev = __cfg80211_rdev_from_info(info);
1420 if (IS_ERR(rdev)) {
1421 mutex_unlock(&cfg80211_mutex);
4c476991 1422 return PTR_ERR(rdev);
f444de05
JB
1423 }
1424 wdev = NULL;
1425 netdev = NULL;
1426 result = 0;
1427
1428 mutex_lock(&rdev->mtx);
cc1d2806 1429 } else if (nl80211_can_set_dev_channel(netdev->ieee80211_ptr))
f444de05
JB
1430 wdev = netdev->ieee80211_ptr;
1431 else
1432 wdev = NULL;
1433
1434 /*
1435 * end workaround code, by now the rdev is available
1436 * and locked, and wdev may or may not be NULL.
1437 */
4bbf4d56
JB
1438
1439 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
1440 result = cfg80211_dev_rename(
1441 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56
JB
1442
1443 mutex_unlock(&cfg80211_mutex);
1444
1445 if (result)
1446 goto bad_res;
31888487
JM
1447
1448 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
1449 struct ieee80211_txq_params txq_params;
1450 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
1451
1452 if (!rdev->ops->set_txq_params) {
1453 result = -EOPNOTSUPP;
1454 goto bad_res;
1455 }
1456
f70f01c2
EP
1457 if (!netdev) {
1458 result = -EINVAL;
1459 goto bad_res;
1460 }
1461
133a3ff2
JB
1462 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
1463 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
1464 result = -EINVAL;
1465 goto bad_res;
1466 }
1467
2b5f8b0b
JB
1468 if (!netif_running(netdev)) {
1469 result = -ENETDOWN;
1470 goto bad_res;
1471 }
1472
31888487
JM
1473 nla_for_each_nested(nl_txq_params,
1474 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
1475 rem_txq_params) {
1476 nla_parse(tb, NL80211_TXQ_ATTR_MAX,
1477 nla_data(nl_txq_params),
1478 nla_len(nl_txq_params),
1479 txq_params_policy);
1480 result = parse_txq_params(tb, &txq_params);
1481 if (result)
1482 goto bad_res;
1483
1484 result = rdev->ops->set_txq_params(&rdev->wiphy,
f70f01c2 1485 netdev,
31888487
JM
1486 &txq_params);
1487 if (result)
1488 goto bad_res;
1489 }
1490 }
55682965 1491
72bdcf34 1492 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
f444de05 1493 result = __nl80211_set_channel(rdev, wdev, info);
72bdcf34
JM
1494 if (result)
1495 goto bad_res;
1496 }
1497
98d2ff8b
JO
1498 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
1499 enum nl80211_tx_power_setting type;
1500 int idx, mbm = 0;
1501
1502 if (!rdev->ops->set_tx_power) {
60ea385f 1503 result = -EOPNOTSUPP;
98d2ff8b
JO
1504 goto bad_res;
1505 }
1506
1507 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
1508 type = nla_get_u32(info->attrs[idx]);
1509
1510 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
1511 (type != NL80211_TX_POWER_AUTOMATIC)) {
1512 result = -EINVAL;
1513 goto bad_res;
1514 }
1515
1516 if (type != NL80211_TX_POWER_AUTOMATIC) {
1517 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
1518 mbm = nla_get_u32(info->attrs[idx]);
1519 }
1520
1521 result = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm);
1522 if (result)
1523 goto bad_res;
1524 }
1525
afe0cbf8
BR
1526 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
1527 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
1528 u32 tx_ant, rx_ant;
7f531e03
BR
1529 if ((!rdev->wiphy.available_antennas_tx &&
1530 !rdev->wiphy.available_antennas_rx) ||
1531 !rdev->ops->set_antenna) {
afe0cbf8
BR
1532 result = -EOPNOTSUPP;
1533 goto bad_res;
1534 }
1535
1536 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
1537 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
1538
a7ffac95 1539 /* reject antenna configurations which don't match the
7f531e03
BR
1540 * available antenna masks, except for the "all" mask */
1541 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
1542 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
a7ffac95
BR
1543 result = -EINVAL;
1544 goto bad_res;
1545 }
1546
7f531e03
BR
1547 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
1548 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 1549
afe0cbf8
BR
1550 result = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
1551 if (result)
1552 goto bad_res;
1553 }
1554
b9a5f8ca
JM
1555 changed = 0;
1556
1557 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
1558 retry_short = nla_get_u8(
1559 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
1560 if (retry_short == 0) {
1561 result = -EINVAL;
1562 goto bad_res;
1563 }
1564 changed |= WIPHY_PARAM_RETRY_SHORT;
1565 }
1566
1567 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
1568 retry_long = nla_get_u8(
1569 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
1570 if (retry_long == 0) {
1571 result = -EINVAL;
1572 goto bad_res;
1573 }
1574 changed |= WIPHY_PARAM_RETRY_LONG;
1575 }
1576
1577 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
1578 frag_threshold = nla_get_u32(
1579 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
1580 if (frag_threshold < 256) {
1581 result = -EINVAL;
1582 goto bad_res;
1583 }
1584 if (frag_threshold != (u32) -1) {
1585 /*
1586 * Fragments (apart from the last one) are required to
1587 * have even length. Make the fragmentation code
1588 * simpler by stripping LSB should someone try to use
1589 * odd threshold value.
1590 */
1591 frag_threshold &= ~0x1;
1592 }
1593 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
1594 }
1595
1596 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
1597 rts_threshold = nla_get_u32(
1598 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
1599 changed |= WIPHY_PARAM_RTS_THRESHOLD;
1600 }
1601
81077e82
LT
1602 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
1603 coverage_class = nla_get_u8(
1604 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
1605 changed |= WIPHY_PARAM_COVERAGE_CLASS;
1606 }
1607
b9a5f8ca
JM
1608 if (changed) {
1609 u8 old_retry_short, old_retry_long;
1610 u32 old_frag_threshold, old_rts_threshold;
81077e82 1611 u8 old_coverage_class;
b9a5f8ca
JM
1612
1613 if (!rdev->ops->set_wiphy_params) {
1614 result = -EOPNOTSUPP;
1615 goto bad_res;
1616 }
1617
1618 old_retry_short = rdev->wiphy.retry_short;
1619 old_retry_long = rdev->wiphy.retry_long;
1620 old_frag_threshold = rdev->wiphy.frag_threshold;
1621 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 1622 old_coverage_class = rdev->wiphy.coverage_class;
b9a5f8ca
JM
1623
1624 if (changed & WIPHY_PARAM_RETRY_SHORT)
1625 rdev->wiphy.retry_short = retry_short;
1626 if (changed & WIPHY_PARAM_RETRY_LONG)
1627 rdev->wiphy.retry_long = retry_long;
1628 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
1629 rdev->wiphy.frag_threshold = frag_threshold;
1630 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
1631 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
1632 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
1633 rdev->wiphy.coverage_class = coverage_class;
b9a5f8ca
JM
1634
1635 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
1636 if (result) {
1637 rdev->wiphy.retry_short = old_retry_short;
1638 rdev->wiphy.retry_long = old_retry_long;
1639 rdev->wiphy.frag_threshold = old_frag_threshold;
1640 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 1641 rdev->wiphy.coverage_class = old_coverage_class;
b9a5f8ca
JM
1642 }
1643 }
72bdcf34 1644
306d6112 1645 bad_res:
4bbf4d56 1646 mutex_unlock(&rdev->mtx);
f444de05
JB
1647 if (netdev)
1648 dev_put(netdev);
55682965
JB
1649 return result;
1650}
1651
1652
1653static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
d726405a 1654 struct cfg80211_registered_device *rdev,
55682965
JB
1655 struct net_device *dev)
1656{
1657 void *hdr;
1658
1659 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE);
1660 if (!hdr)
1661 return -1;
1662
9360ffd1
DM
1663 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
1664 nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
1665 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) ||
1666 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
1667 dev->ieee80211_ptr->iftype) ||
1668 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1669 rdev->devlist_generation ^
1670 (cfg80211_rdev_list_generation << 2)))
1671 goto nla_put_failure;
f5ea9120 1672
d91df0e3
PF
1673 if (rdev->ops->get_channel) {
1674 struct ieee80211_channel *chan;
1675 enum nl80211_channel_type channel_type;
1676
1677 chan = rdev->ops->get_channel(&rdev->wiphy, &channel_type);
59ef43e6
JL
1678 if (chan &&
1679 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
1680 chan->center_freq) ||
1681 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
1682 channel_type)))
1683 goto nla_put_failure;
d91df0e3
PF
1684 }
1685
55682965
JB
1686 return genlmsg_end(msg, hdr);
1687
1688 nla_put_failure:
bc3ed28c
TG
1689 genlmsg_cancel(msg, hdr);
1690 return -EMSGSIZE;
55682965
JB
1691}
1692
1693static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
1694{
1695 int wp_idx = 0;
1696 int if_idx = 0;
1697 int wp_start = cb->args[0];
1698 int if_start = cb->args[1];
f5ea9120 1699 struct cfg80211_registered_device *rdev;
55682965
JB
1700 struct wireless_dev *wdev;
1701
a1794390 1702 mutex_lock(&cfg80211_mutex);
f5ea9120
JB
1703 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
1704 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 1705 continue;
bba95fef
JB
1706 if (wp_idx < wp_start) {
1707 wp_idx++;
55682965 1708 continue;
bba95fef 1709 }
55682965
JB
1710 if_idx = 0;
1711
f5ea9120
JB
1712 mutex_lock(&rdev->devlist_mtx);
1713 list_for_each_entry(wdev, &rdev->netdev_list, list) {
bba95fef
JB
1714 if (if_idx < if_start) {
1715 if_idx++;
55682965 1716 continue;
bba95fef 1717 }
55682965
JB
1718 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
1719 cb->nlh->nlmsg_seq, NLM_F_MULTI,
f5ea9120
JB
1720 rdev, wdev->netdev) < 0) {
1721 mutex_unlock(&rdev->devlist_mtx);
bba95fef
JB
1722 goto out;
1723 }
1724 if_idx++;
55682965 1725 }
f5ea9120 1726 mutex_unlock(&rdev->devlist_mtx);
bba95fef
JB
1727
1728 wp_idx++;
55682965 1729 }
bba95fef 1730 out:
a1794390 1731 mutex_unlock(&cfg80211_mutex);
55682965
JB
1732
1733 cb->args[0] = wp_idx;
1734 cb->args[1] = if_idx;
1735
1736 return skb->len;
1737}
1738
1739static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
1740{
1741 struct sk_buff *msg;
4c476991
JB
1742 struct cfg80211_registered_device *dev = info->user_ptr[0];
1743 struct net_device *netdev = info->user_ptr[1];
55682965 1744
fd2120ca 1745 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 1746 if (!msg)
4c476991 1747 return -ENOMEM;
55682965 1748
d726405a 1749 if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
4c476991
JB
1750 dev, netdev) < 0) {
1751 nlmsg_free(msg);
1752 return -ENOBUFS;
1753 }
55682965 1754
134e6375 1755 return genlmsg_reply(msg, info);
55682965
JB
1756}
1757
66f7ac50
MW
1758static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
1759 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
1760 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
1761 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
1762 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
1763 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
1764};
1765
1766static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
1767{
1768 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
1769 int flag;
1770
1771 *mntrflags = 0;
1772
1773 if (!nla)
1774 return -EINVAL;
1775
1776 if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX,
1777 nla, mntr_flags_policy))
1778 return -EINVAL;
1779
1780 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
1781 if (flags[flag])
1782 *mntrflags |= (1<<flag);
1783
1784 return 0;
1785}
1786
9bc383de 1787static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
1788 struct net_device *netdev, u8 use_4addr,
1789 enum nl80211_iftype iftype)
9bc383de 1790{
ad4bb6f8 1791 if (!use_4addr) {
f350a0a8 1792 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 1793 return -EBUSY;
9bc383de 1794 return 0;
ad4bb6f8 1795 }
9bc383de
JB
1796
1797 switch (iftype) {
1798 case NL80211_IFTYPE_AP_VLAN:
1799 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
1800 return 0;
1801 break;
1802 case NL80211_IFTYPE_STATION:
1803 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
1804 return 0;
1805 break;
1806 default:
1807 break;
1808 }
1809
1810 return -EOPNOTSUPP;
1811}
1812
55682965
JB
1813static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
1814{
4c476991 1815 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 1816 struct vif_params params;
e36d56b6 1817 int err;
04a773ad 1818 enum nl80211_iftype otype, ntype;
4c476991 1819 struct net_device *dev = info->user_ptr[1];
92ffe055 1820 u32 _flags, *flags = NULL;
ac7f9cfa 1821 bool change = false;
55682965 1822
2ec600d6
LCC
1823 memset(&params, 0, sizeof(params));
1824
04a773ad 1825 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 1826
723b038d 1827 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 1828 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 1829 if (otype != ntype)
ac7f9cfa 1830 change = true;
4c476991
JB
1831 if (ntype > NL80211_IFTYPE_MAX)
1832 return -EINVAL;
723b038d
JB
1833 }
1834
92ffe055 1835 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
1836 struct wireless_dev *wdev = dev->ieee80211_ptr;
1837
4c476991
JB
1838 if (ntype != NL80211_IFTYPE_MESH_POINT)
1839 return -EINVAL;
29cbe68c
JB
1840 if (netif_running(dev))
1841 return -EBUSY;
1842
1843 wdev_lock(wdev);
1844 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
1845 IEEE80211_MAX_MESH_ID_LEN);
1846 wdev->mesh_id_up_len =
1847 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
1848 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
1849 wdev->mesh_id_up_len);
1850 wdev_unlock(wdev);
2ec600d6
LCC
1851 }
1852
8b787643
FF
1853 if (info->attrs[NL80211_ATTR_4ADDR]) {
1854 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
1855 change = true;
ad4bb6f8 1856 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 1857 if (err)
4c476991 1858 return err;
8b787643
FF
1859 } else {
1860 params.use_4addr = -1;
1861 }
1862
92ffe055 1863 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
4c476991
JB
1864 if (ntype != NL80211_IFTYPE_MONITOR)
1865 return -EINVAL;
92ffe055
JB
1866 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
1867 &_flags);
ac7f9cfa 1868 if (err)
4c476991 1869 return err;
ac7f9cfa
JB
1870
1871 flags = &_flags;
1872 change = true;
92ffe055 1873 }
3b85875a 1874
ac7f9cfa 1875 if (change)
3d54d255 1876 err = cfg80211_change_iface(rdev, dev, ntype, flags, &params);
ac7f9cfa
JB
1877 else
1878 err = 0;
60719ffd 1879
9bc383de
JB
1880 if (!err && params.use_4addr != -1)
1881 dev->ieee80211_ptr->use_4addr = params.use_4addr;
1882
55682965
JB
1883 return err;
1884}
1885
1886static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1887{
4c476991 1888 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 1889 struct vif_params params;
f9e10ce4 1890 struct net_device *dev;
55682965
JB
1891 int err;
1892 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
66f7ac50 1893 u32 flags;
55682965 1894
2ec600d6
LCC
1895 memset(&params, 0, sizeof(params));
1896
55682965
JB
1897 if (!info->attrs[NL80211_ATTR_IFNAME])
1898 return -EINVAL;
1899
1900 if (info->attrs[NL80211_ATTR_IFTYPE]) {
1901 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
1902 if (type > NL80211_IFTYPE_MAX)
1903 return -EINVAL;
1904 }
1905
79c97e97 1906 if (!rdev->ops->add_virtual_intf ||
4c476991
JB
1907 !(rdev->wiphy.interface_modes & (1 << type)))
1908 return -EOPNOTSUPP;
55682965 1909
9bc383de 1910 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 1911 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 1912 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 1913 if (err)
4c476991 1914 return err;
9bc383de 1915 }
8b787643 1916
66f7ac50
MW
1917 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
1918 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
1919 &flags);
f9e10ce4 1920 dev = rdev->ops->add_virtual_intf(&rdev->wiphy,
66f7ac50 1921 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
2ec600d6 1922 type, err ? NULL : &flags, &params);
f9e10ce4
JB
1923 if (IS_ERR(dev))
1924 return PTR_ERR(dev);
2ec600d6 1925
29cbe68c
JB
1926 if (type == NL80211_IFTYPE_MESH_POINT &&
1927 info->attrs[NL80211_ATTR_MESH_ID]) {
1928 struct wireless_dev *wdev = dev->ieee80211_ptr;
1929
1930 wdev_lock(wdev);
1931 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
1932 IEEE80211_MAX_MESH_ID_LEN);
1933 wdev->mesh_id_up_len =
1934 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
1935 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
1936 wdev->mesh_id_up_len);
1937 wdev_unlock(wdev);
1938 }
1939
f9e10ce4 1940 return 0;
55682965
JB
1941}
1942
1943static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
1944{
4c476991
JB
1945 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1946 struct net_device *dev = info->user_ptr[1];
55682965 1947
4c476991
JB
1948 if (!rdev->ops->del_virtual_intf)
1949 return -EOPNOTSUPP;
55682965 1950
4c476991 1951 return rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
55682965
JB
1952}
1953
1d9d9213
SW
1954static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
1955{
1956 struct cfg80211_registered_device *rdev = info->user_ptr[0];
1957 struct net_device *dev = info->user_ptr[1];
1958 u16 noack_map;
1959
1960 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
1961 return -EINVAL;
1962
1963 if (!rdev->ops->set_noack_map)
1964 return -EOPNOTSUPP;
1965
1966 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
1967
1968 return rdev->ops->set_noack_map(&rdev->wiphy, dev, noack_map);
1969}
1970
41ade00f
JB
1971struct get_key_cookie {
1972 struct sk_buff *msg;
1973 int error;
b9454e83 1974 int idx;
41ade00f
JB
1975};
1976
1977static void get_key_callback(void *c, struct key_params *params)
1978{
b9454e83 1979 struct nlattr *key;
41ade00f
JB
1980 struct get_key_cookie *cookie = c;
1981
9360ffd1
DM
1982 if ((params->key &&
1983 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
1984 params->key_len, params->key)) ||
1985 (params->seq &&
1986 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
1987 params->seq_len, params->seq)) ||
1988 (params->cipher &&
1989 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
1990 params->cipher)))
1991 goto nla_put_failure;
41ade00f 1992
b9454e83
JB
1993 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
1994 if (!key)
1995 goto nla_put_failure;
1996
9360ffd1
DM
1997 if ((params->key &&
1998 nla_put(cookie->msg, NL80211_KEY_DATA,
1999 params->key_len, params->key)) ||
2000 (params->seq &&
2001 nla_put(cookie->msg, NL80211_KEY_SEQ,
2002 params->seq_len, params->seq)) ||
2003 (params->cipher &&
2004 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
2005 params->cipher)))
2006 goto nla_put_failure;
b9454e83 2007
9360ffd1
DM
2008 if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx))
2009 goto nla_put_failure;
b9454e83
JB
2010
2011 nla_nest_end(cookie->msg, key);
2012
41ade00f
JB
2013 return;
2014 nla_put_failure:
2015 cookie->error = 1;
2016}
2017
2018static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
2019{
4c476991 2020 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 2021 int err;
4c476991 2022 struct net_device *dev = info->user_ptr[1];
41ade00f 2023 u8 key_idx = 0;
e31b8213
JB
2024 const u8 *mac_addr = NULL;
2025 bool pairwise;
41ade00f
JB
2026 struct get_key_cookie cookie = {
2027 .error = 0,
2028 };
2029 void *hdr;
2030 struct sk_buff *msg;
2031
2032 if (info->attrs[NL80211_ATTR_KEY_IDX])
2033 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
2034
3cfcf6ac 2035 if (key_idx > 5)
41ade00f
JB
2036 return -EINVAL;
2037
2038 if (info->attrs[NL80211_ATTR_MAC])
2039 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2040
e31b8213
JB
2041 pairwise = !!mac_addr;
2042 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
2043 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
2044 if (kt >= NUM_NL80211_KEYTYPES)
2045 return -EINVAL;
2046 if (kt != NL80211_KEYTYPE_GROUP &&
2047 kt != NL80211_KEYTYPE_PAIRWISE)
2048 return -EINVAL;
2049 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
2050 }
2051
4c476991
JB
2052 if (!rdev->ops->get_key)
2053 return -EOPNOTSUPP;
41ade00f 2054
fd2120ca 2055 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
2056 if (!msg)
2057 return -ENOMEM;
41ade00f
JB
2058
2059 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
2060 NL80211_CMD_NEW_KEY);
4c476991
JB
2061 if (IS_ERR(hdr))
2062 return PTR_ERR(hdr);
41ade00f
JB
2063
2064 cookie.msg = msg;
b9454e83 2065 cookie.idx = key_idx;
41ade00f 2066
9360ffd1
DM
2067 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
2068 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
2069 goto nla_put_failure;
2070 if (mac_addr &&
2071 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
2072 goto nla_put_failure;
41ade00f 2073
e31b8213
JB
2074 if (pairwise && mac_addr &&
2075 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
2076 return -ENOENT;
2077
2078 err = rdev->ops->get_key(&rdev->wiphy, dev, key_idx, pairwise,
2079 mac_addr, &cookie, get_key_callback);
41ade00f
JB
2080
2081 if (err)
6c95e2a2 2082 goto free_msg;
41ade00f
JB
2083
2084 if (cookie.error)
2085 goto nla_put_failure;
2086
2087 genlmsg_end(msg, hdr);
4c476991 2088 return genlmsg_reply(msg, info);
41ade00f
JB
2089
2090 nla_put_failure:
2091 err = -ENOBUFS;
6c95e2a2 2092 free_msg:
41ade00f 2093 nlmsg_free(msg);
41ade00f
JB
2094 return err;
2095}
2096
2097static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
2098{
4c476991 2099 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 2100 struct key_parse key;
41ade00f 2101 int err;
4c476991 2102 struct net_device *dev = info->user_ptr[1];
41ade00f 2103
b9454e83
JB
2104 err = nl80211_parse_key(info, &key);
2105 if (err)
2106 return err;
41ade00f 2107
b9454e83 2108 if (key.idx < 0)
41ade00f
JB
2109 return -EINVAL;
2110
b9454e83
JB
2111 /* only support setting default key */
2112 if (!key.def && !key.defmgmt)
41ade00f
JB
2113 return -EINVAL;
2114
dbd2fd65 2115 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 2116
dbd2fd65
JB
2117 if (key.def) {
2118 if (!rdev->ops->set_default_key) {
2119 err = -EOPNOTSUPP;
2120 goto out;
2121 }
41ade00f 2122
dbd2fd65
JB
2123 err = nl80211_key_allowed(dev->ieee80211_ptr);
2124 if (err)
2125 goto out;
2126
dbd2fd65
JB
2127 err = rdev->ops->set_default_key(&rdev->wiphy, dev, key.idx,
2128 key.def_uni, key.def_multi);
2129
2130 if (err)
2131 goto out;
fffd0934 2132
3d23e349 2133#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
2134 dev->ieee80211_ptr->wext.default_key = key.idx;
2135#endif
2136 } else {
2137 if (key.def_uni || !key.def_multi) {
2138 err = -EINVAL;
2139 goto out;
2140 }
2141
2142 if (!rdev->ops->set_default_mgmt_key) {
2143 err = -EOPNOTSUPP;
2144 goto out;
2145 }
2146
2147 err = nl80211_key_allowed(dev->ieee80211_ptr);
2148 if (err)
2149 goto out;
2150
2151 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
2152 dev, key.idx);
2153 if (err)
2154 goto out;
2155
2156#ifdef CONFIG_CFG80211_WEXT
2157 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 2158#endif
dbd2fd65
JB
2159 }
2160
2161 out:
fffd0934 2162 wdev_unlock(dev->ieee80211_ptr);
41ade00f 2163
41ade00f
JB
2164 return err;
2165}
2166
2167static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
2168{
4c476991 2169 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 2170 int err;
4c476991 2171 struct net_device *dev = info->user_ptr[1];
b9454e83 2172 struct key_parse key;
e31b8213 2173 const u8 *mac_addr = NULL;
41ade00f 2174
b9454e83
JB
2175 err = nl80211_parse_key(info, &key);
2176 if (err)
2177 return err;
41ade00f 2178
b9454e83 2179 if (!key.p.key)
41ade00f
JB
2180 return -EINVAL;
2181
41ade00f
JB
2182 if (info->attrs[NL80211_ATTR_MAC])
2183 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2184
e31b8213
JB
2185 if (key.type == -1) {
2186 if (mac_addr)
2187 key.type = NL80211_KEYTYPE_PAIRWISE;
2188 else
2189 key.type = NL80211_KEYTYPE_GROUP;
2190 }
2191
2192 /* for now */
2193 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
2194 key.type != NL80211_KEYTYPE_GROUP)
2195 return -EINVAL;
2196
4c476991
JB
2197 if (!rdev->ops->add_key)
2198 return -EOPNOTSUPP;
25e47c18 2199
e31b8213
JB
2200 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
2201 key.type == NL80211_KEYTYPE_PAIRWISE,
2202 mac_addr))
4c476991 2203 return -EINVAL;
41ade00f 2204
fffd0934
JB
2205 wdev_lock(dev->ieee80211_ptr);
2206 err = nl80211_key_allowed(dev->ieee80211_ptr);
2207 if (!err)
2208 err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx,
e31b8213 2209 key.type == NL80211_KEYTYPE_PAIRWISE,
fffd0934
JB
2210 mac_addr, &key.p);
2211 wdev_unlock(dev->ieee80211_ptr);
41ade00f 2212
41ade00f
JB
2213 return err;
2214}
2215
2216static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
2217{
4c476991 2218 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 2219 int err;
4c476991 2220 struct net_device *dev = info->user_ptr[1];
41ade00f 2221 u8 *mac_addr = NULL;
b9454e83 2222 struct key_parse key;
41ade00f 2223
b9454e83
JB
2224 err = nl80211_parse_key(info, &key);
2225 if (err)
2226 return err;
41ade00f
JB
2227
2228 if (info->attrs[NL80211_ATTR_MAC])
2229 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2230
e31b8213
JB
2231 if (key.type == -1) {
2232 if (mac_addr)
2233 key.type = NL80211_KEYTYPE_PAIRWISE;
2234 else
2235 key.type = NL80211_KEYTYPE_GROUP;
2236 }
2237
2238 /* for now */
2239 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
2240 key.type != NL80211_KEYTYPE_GROUP)
2241 return -EINVAL;
2242
4c476991
JB
2243 if (!rdev->ops->del_key)
2244 return -EOPNOTSUPP;
41ade00f 2245
fffd0934
JB
2246 wdev_lock(dev->ieee80211_ptr);
2247 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213
JB
2248
2249 if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr &&
2250 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
2251 err = -ENOENT;
2252
fffd0934 2253 if (!err)
e31b8213
JB
2254 err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx,
2255 key.type == NL80211_KEYTYPE_PAIRWISE,
2256 mac_addr);
41ade00f 2257
3d23e349 2258#ifdef CONFIG_CFG80211_WEXT
08645126 2259 if (!err) {
b9454e83 2260 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 2261 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 2262 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
2263 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
2264 }
2265#endif
fffd0934 2266 wdev_unlock(dev->ieee80211_ptr);
08645126 2267
41ade00f
JB
2268 return err;
2269}
2270
8860020e
JB
2271static int nl80211_parse_beacon(struct genl_info *info,
2272 struct cfg80211_beacon_data *bcn)
ed1b6cc7 2273{
8860020e 2274 bool haveinfo = false;
ed1b6cc7 2275
9946ecfb
JM
2276 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
2277 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
2278 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
2279 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
f4a11bb0
JB
2280 return -EINVAL;
2281
8860020e 2282 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 2283
ed1b6cc7 2284 if (info->attrs[NL80211_ATTR_BEACON_HEAD]) {
8860020e
JB
2285 bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]);
2286 bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]);
2287 if (!bcn->head_len)
2288 return -EINVAL;
2289 haveinfo = true;
ed1b6cc7
JB
2290 }
2291
2292 if (info->attrs[NL80211_ATTR_BEACON_TAIL]) {
8860020e
JB
2293 bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]);
2294 bcn->tail_len =
ed1b6cc7 2295 nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 2296 haveinfo = true;
ed1b6cc7
JB
2297 }
2298
4c476991
JB
2299 if (!haveinfo)
2300 return -EINVAL;
3b85875a 2301
9946ecfb 2302 if (info->attrs[NL80211_ATTR_IE]) {
8860020e
JB
2303 bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2304 bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9946ecfb
JM
2305 }
2306
2307 if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 2308 bcn->proberesp_ies =
9946ecfb 2309 nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 2310 bcn->proberesp_ies_len =
9946ecfb
JM
2311 nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
2312 }
2313
2314 if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 2315 bcn->assocresp_ies =
9946ecfb 2316 nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 2317 bcn->assocresp_ies_len =
9946ecfb
JM
2318 nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2319 }
2320
00f740e1 2321 if (info->attrs[NL80211_ATTR_PROBE_RESP]) {
8860020e 2322 bcn->probe_resp =
00f740e1 2323 nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]);
8860020e 2324 bcn->probe_resp_len =
00f740e1
AN
2325 nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]);
2326 }
2327
8860020e
JB
2328 return 0;
2329}
2330
2331static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2332{
2333 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2334 struct net_device *dev = info->user_ptr[1];
2335 struct wireless_dev *wdev = dev->ieee80211_ptr;
2336 struct cfg80211_ap_settings params;
2337 int err;
2338
2339 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2340 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2341 return -EOPNOTSUPP;
2342
2343 if (!rdev->ops->start_ap)
2344 return -EOPNOTSUPP;
2345
2346 if (wdev->beacon_interval)
2347 return -EALREADY;
2348
2349 memset(&params, 0, sizeof(params));
2350
2351 /* these are required for START_AP */
2352 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
2353 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
2354 !info->attrs[NL80211_ATTR_BEACON_HEAD])
2355 return -EINVAL;
2356
2357 err = nl80211_parse_beacon(info, &params.beacon);
2358 if (err)
2359 return err;
2360
2361 params.beacon_interval =
2362 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
2363 params.dtim_period =
2364 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
2365
2366 err = cfg80211_validate_beacon_int(rdev, params.beacon_interval);
2367 if (err)
2368 return err;
2369
2370 /*
2371 * In theory, some of these attributes should be required here
2372 * but since they were not used when the command was originally
2373 * added, keep them optional for old user space programs to let
2374 * them continue to work with drivers that do not need the
2375 * additional information -- drivers must check!
2376 */
2377 if (info->attrs[NL80211_ATTR_SSID]) {
2378 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2379 params.ssid_len =
2380 nla_len(info->attrs[NL80211_ATTR_SSID]);
2381 if (params.ssid_len == 0 ||
2382 params.ssid_len > IEEE80211_MAX_SSID_LEN)
2383 return -EINVAL;
2384 }
2385
2386 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
2387 params.hidden_ssid = nla_get_u32(
2388 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
2389 if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE &&
2390 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN &&
2391 params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS)
2392 return -EINVAL;
2393 }
2394
2395 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
2396
2397 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
2398 params.auth_type = nla_get_u32(
2399 info->attrs[NL80211_ATTR_AUTH_TYPE]);
2400 if (!nl80211_valid_auth_type(params.auth_type))
2401 return -EINVAL;
2402 } else
2403 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
2404
2405 err = nl80211_crypto_settings(rdev, info, &params.crypto,
2406 NL80211_MAX_NR_CIPHER_SUITES);
2407 if (err)
2408 return err;
2409
1b658f11
VT
2410 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
2411 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
2412 return -EOPNOTSUPP;
2413 params.inactivity_timeout = nla_get_u16(
2414 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
2415 }
2416
aa430da4
JB
2417 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2418 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
2419
2420 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
2421 !nl80211_valid_channel_type(info, &channel_type))
2422 return -EINVAL;
2423
2424 params.channel = rdev_freq_to_chan(rdev,
2425 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
2426 channel_type);
2427 if (!params.channel)
2428 return -EINVAL;
2429 params.channel_type = channel_type;
2430 } else if (wdev->preset_chan) {
2431 params.channel = wdev->preset_chan;
2432 params.channel_type = wdev->preset_chantype;
2433 } else
2434 return -EINVAL;
2435
2436 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel,
2437 params.channel_type))
2438 return -EINVAL;
2439
8860020e
JB
2440 err = rdev->ops->start_ap(&rdev->wiphy, dev, &params);
2441 if (!err)
2442 wdev->beacon_interval = params.beacon_interval;
56d1893d 2443 return err;
ed1b6cc7
JB
2444}
2445
8860020e
JB
2446static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
2447{
2448 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2449 struct net_device *dev = info->user_ptr[1];
2450 struct wireless_dev *wdev = dev->ieee80211_ptr;
2451 struct cfg80211_beacon_data params;
2452 int err;
2453
2454 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
2455 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2456 return -EOPNOTSUPP;
2457
2458 if (!rdev->ops->change_beacon)
2459 return -EOPNOTSUPP;
2460
2461 if (!wdev->beacon_interval)
2462 return -EINVAL;
2463
2464 err = nl80211_parse_beacon(info, &params);
2465 if (err)
2466 return err;
2467
2468 return rdev->ops->change_beacon(&rdev->wiphy, dev, &params);
2469}
2470
2471static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 2472{
4c476991
JB
2473 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2474 struct net_device *dev = info->user_ptr[1];
56d1893d
JB
2475 struct wireless_dev *wdev = dev->ieee80211_ptr;
2476 int err;
ed1b6cc7 2477
8860020e 2478 if (!rdev->ops->stop_ap)
4c476991 2479 return -EOPNOTSUPP;
ed1b6cc7 2480
074ac8df 2481 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
2482 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2483 return -EOPNOTSUPP;
3b85875a 2484
8860020e
JB
2485 if (!wdev->beacon_interval)
2486 return -ENOENT;
2487
2488 err = rdev->ops->stop_ap(&rdev->wiphy, dev);
56d1893d
JB
2489 if (!err)
2490 wdev->beacon_interval = 0;
2491 return err;
ed1b6cc7
JB
2492}
2493
5727ef1b
JB
2494static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
2495 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
2496 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
2497 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 2498 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 2499 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 2500 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
2501};
2502
eccb8e8f 2503static int parse_station_flags(struct genl_info *info,
bdd3ae3d 2504 enum nl80211_iftype iftype,
eccb8e8f 2505 struct station_parameters *params)
5727ef1b
JB
2506{
2507 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 2508 struct nlattr *nla;
5727ef1b
JB
2509 int flag;
2510
eccb8e8f
JB
2511 /*
2512 * Try parsing the new attribute first so userspace
2513 * can specify both for older kernels.
2514 */
2515 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
2516 if (nla) {
2517 struct nl80211_sta_flag_update *sta_flags;
2518
2519 sta_flags = nla_data(nla);
2520 params->sta_flags_mask = sta_flags->mask;
2521 params->sta_flags_set = sta_flags->set;
2522 if ((params->sta_flags_mask |
2523 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
2524 return -EINVAL;
2525 return 0;
2526 }
2527
2528 /* if present, parse the old attribute */
5727ef1b 2529
eccb8e8f 2530 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
2531 if (!nla)
2532 return 0;
2533
2534 if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX,
2535 nla, sta_flags_policy))
2536 return -EINVAL;
2537
bdd3ae3d
JB
2538 /*
2539 * Only allow certain flags for interface types so that
2540 * other attributes are silently ignored. Remember that
2541 * this is backward compatibility code with old userspace
2542 * and shouldn't be hit in other cases anyway.
2543 */
2544 switch (iftype) {
2545 case NL80211_IFTYPE_AP:
2546 case NL80211_IFTYPE_AP_VLAN:
2547 case NL80211_IFTYPE_P2P_GO:
2548 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
2549 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
2550 BIT(NL80211_STA_FLAG_WME) |
2551 BIT(NL80211_STA_FLAG_MFP);
2552 break;
2553 case NL80211_IFTYPE_P2P_CLIENT:
2554 case NL80211_IFTYPE_STATION:
2555 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
2556 BIT(NL80211_STA_FLAG_TDLS_PEER);
2557 break;
2558 case NL80211_IFTYPE_MESH_POINT:
2559 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2560 BIT(NL80211_STA_FLAG_MFP) |
2561 BIT(NL80211_STA_FLAG_AUTHORIZED);
2562 default:
2563 return -EINVAL;
2564 }
5727ef1b 2565
3383b5a6
JB
2566 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
2567 if (flags[flag]) {
eccb8e8f 2568 params->sta_flags_set |= (1<<flag);
5727ef1b 2569
3383b5a6
JB
2570 /* no longer support new API additions in old API */
2571 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
2572 return -EINVAL;
2573 }
2574 }
2575
5727ef1b
JB
2576 return 0;
2577}
2578
c8dcfd8a
FF
2579static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info,
2580 int attr)
2581{
2582 struct nlattr *rate;
2583 u16 bitrate;
2584
2585 rate = nla_nest_start(msg, attr);
2586 if (!rate)
2587 goto nla_put_failure;
2588
2589 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
2590 bitrate = cfg80211_calculate_bitrate(info);
9360ffd1
DM
2591 if ((bitrate > 0 &&
2592 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate)) ||
2593 ((info->flags & RATE_INFO_FLAGS_MCS) &&
2594 nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) ||
2595 ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) &&
2596 nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) ||
2597 ((info->flags & RATE_INFO_FLAGS_SHORT_GI) &&
2598 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)))
2599 goto nla_put_failure;
c8dcfd8a
FF
2600
2601 nla_nest_end(msg, rate);
2602 return true;
2603
2604nla_put_failure:
2605 return false;
2606}
2607
fd5b74dc 2608static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
66266b3a
JL
2609 int flags,
2610 struct cfg80211_registered_device *rdev,
2611 struct net_device *dev,
98b62183 2612 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
2613{
2614 void *hdr;
f4263c98 2615 struct nlattr *sinfoattr, *bss_param;
fd5b74dc
JB
2616
2617 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
2618 if (!hdr)
2619 return -1;
2620
9360ffd1
DM
2621 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
2622 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
2623 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
2624 goto nla_put_failure;
f5ea9120 2625
2ec600d6
LCC
2626 sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO);
2627 if (!sinfoattr)
fd5b74dc 2628 goto nla_put_failure;
9360ffd1
DM
2629 if ((sinfo->filled & STATION_INFO_CONNECTED_TIME) &&
2630 nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME,
2631 sinfo->connected_time))
2632 goto nla_put_failure;
2633 if ((sinfo->filled & STATION_INFO_INACTIVE_TIME) &&
2634 nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME,
2635 sinfo->inactive_time))
2636 goto nla_put_failure;
2637 if ((sinfo->filled & STATION_INFO_RX_BYTES) &&
2638 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
2639 sinfo->rx_bytes))
2640 goto nla_put_failure;
2641 if ((sinfo->filled & STATION_INFO_TX_BYTES) &&
2642 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
2643 sinfo->tx_bytes))
2644 goto nla_put_failure;
2645 if ((sinfo->filled & STATION_INFO_LLID) &&
2646 nla_put_u16(msg, NL80211_STA_INFO_LLID, sinfo->llid))
2647 goto nla_put_failure;
2648 if ((sinfo->filled & STATION_INFO_PLID) &&
2649 nla_put_u16(msg, NL80211_STA_INFO_PLID, sinfo->plid))
2650 goto nla_put_failure;
2651 if ((sinfo->filled & STATION_INFO_PLINK_STATE) &&
2652 nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE,
2653 sinfo->plink_state))
2654 goto nla_put_failure;
66266b3a
JL
2655 switch (rdev->wiphy.signal_type) {
2656 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
2657 if ((sinfo->filled & STATION_INFO_SIGNAL) &&
2658 nla_put_u8(msg, NL80211_STA_INFO_SIGNAL,
2659 sinfo->signal))
2660 goto nla_put_failure;
2661 if ((sinfo->filled & STATION_INFO_SIGNAL_AVG) &&
2662 nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG,
2663 sinfo->signal_avg))
2664 goto nla_put_failure;
66266b3a
JL
2665 break;
2666 default:
2667 break;
2668 }
420e7fab 2669 if (sinfo->filled & STATION_INFO_TX_BITRATE) {
c8dcfd8a
FF
2670 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
2671 NL80211_STA_INFO_TX_BITRATE))
2672 goto nla_put_failure;
2673 }
2674 if (sinfo->filled & STATION_INFO_RX_BITRATE) {
2675 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
2676 NL80211_STA_INFO_RX_BITRATE))
420e7fab 2677 goto nla_put_failure;
420e7fab 2678 }
9360ffd1
DM
2679 if ((sinfo->filled & STATION_INFO_RX_PACKETS) &&
2680 nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS,
2681 sinfo->rx_packets))
2682 goto nla_put_failure;
2683 if ((sinfo->filled & STATION_INFO_TX_PACKETS) &&
2684 nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS,
2685 sinfo->tx_packets))
2686 goto nla_put_failure;
2687 if ((sinfo->filled & STATION_INFO_TX_RETRIES) &&
2688 nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES,
2689 sinfo->tx_retries))
2690 goto nla_put_failure;
2691 if ((sinfo->filled & STATION_INFO_TX_FAILED) &&
2692 nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED,
2693 sinfo->tx_failed))
2694 goto nla_put_failure;
2695 if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) &&
2696 nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS,
2697 sinfo->beacon_loss_count))
2698 goto nla_put_failure;
f4263c98
PS
2699 if (sinfo->filled & STATION_INFO_BSS_PARAM) {
2700 bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM);
2701 if (!bss_param)
2702 goto nla_put_failure;
2703
9360ffd1
DM
2704 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
2705 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
2706 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
2707 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
2708 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
2709 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
2710 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
2711 sinfo->bss_param.dtim_period) ||
2712 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
2713 sinfo->bss_param.beacon_interval))
2714 goto nla_put_failure;
f4263c98
PS
2715
2716 nla_nest_end(msg, bss_param);
2717 }
9360ffd1
DM
2718 if ((sinfo->filled & STATION_INFO_STA_FLAGS) &&
2719 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
2720 sizeof(struct nl80211_sta_flag_update),
2721 &sinfo->sta_flags))
2722 goto nla_put_failure;
7eab0f64
JL
2723 if ((sinfo->filled & STATION_INFO_T_OFFSET) &&
2724 nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET,
2725 sinfo->t_offset))
2726 goto nla_put_failure;
2ec600d6 2727 nla_nest_end(msg, sinfoattr);
fd5b74dc 2728
9360ffd1
DM
2729 if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) &&
2730 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
2731 sinfo->assoc_req_ies))
2732 goto nla_put_failure;
50d3dfb7 2733
fd5b74dc
JB
2734 return genlmsg_end(msg, hdr);
2735
2736 nla_put_failure:
bc3ed28c
TG
2737 genlmsg_cancel(msg, hdr);
2738 return -EMSGSIZE;
fd5b74dc
JB
2739}
2740
2ec600d6 2741static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 2742 struct netlink_callback *cb)
2ec600d6 2743{
2ec600d6
LCC
2744 struct station_info sinfo;
2745 struct cfg80211_registered_device *dev;
bba95fef 2746 struct net_device *netdev;
2ec600d6 2747 u8 mac_addr[ETH_ALEN];
bba95fef 2748 int sta_idx = cb->args[1];
2ec600d6 2749 int err;
2ec600d6 2750
67748893
JB
2751 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
2752 if (err)
2753 return err;
bba95fef
JB
2754
2755 if (!dev->ops->dump_station) {
eec60b03 2756 err = -EOPNOTSUPP;
bba95fef
JB
2757 goto out_err;
2758 }
2759
bba95fef 2760 while (1) {
f612cedf 2761 memset(&sinfo, 0, sizeof(sinfo));
bba95fef
JB
2762 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
2763 mac_addr, &sinfo);
2764 if (err == -ENOENT)
2765 break;
2766 if (err)
3b85875a 2767 goto out_err;
bba95fef
JB
2768
2769 if (nl80211_send_station(skb,
2770 NETLINK_CB(cb->skb).pid,
2771 cb->nlh->nlmsg_seq, NLM_F_MULTI,
66266b3a 2772 dev, netdev, mac_addr,
bba95fef
JB
2773 &sinfo) < 0)
2774 goto out;
2775
2776 sta_idx++;
2777 }
2778
2779
2780 out:
2781 cb->args[1] = sta_idx;
2782 err = skb->len;
bba95fef 2783 out_err:
67748893 2784 nl80211_finish_netdev_dump(dev);
bba95fef
JB
2785
2786 return err;
2ec600d6 2787}
fd5b74dc 2788
5727ef1b
JB
2789static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
2790{
4c476991
JB
2791 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2792 struct net_device *dev = info->user_ptr[1];
2ec600d6 2793 struct station_info sinfo;
fd5b74dc
JB
2794 struct sk_buff *msg;
2795 u8 *mac_addr = NULL;
4c476991 2796 int err;
fd5b74dc 2797
2ec600d6 2798 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc
JB
2799
2800 if (!info->attrs[NL80211_ATTR_MAC])
2801 return -EINVAL;
2802
2803 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2804
4c476991
JB
2805 if (!rdev->ops->get_station)
2806 return -EOPNOTSUPP;
3b85875a 2807
4c476991 2808 err = rdev->ops->get_station(&rdev->wiphy, dev, mac_addr, &sinfo);
fd5b74dc 2809 if (err)
4c476991 2810 return err;
2ec600d6 2811
fd2120ca 2812 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
fd5b74dc 2813 if (!msg)
4c476991 2814 return -ENOMEM;
fd5b74dc
JB
2815
2816 if (nl80211_send_station(msg, info->snd_pid, info->snd_seq, 0,
66266b3a 2817 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991
JB
2818 nlmsg_free(msg);
2819 return -ENOBUFS;
2820 }
3b85875a 2821
4c476991 2822 return genlmsg_reply(msg, info);
5727ef1b
JB
2823}
2824
2825/*
c258d2de 2826 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 2827 */
80b99899
JB
2828static struct net_device *get_vlan(struct genl_info *info,
2829 struct cfg80211_registered_device *rdev)
5727ef1b 2830{
463d0183 2831 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
2832 struct net_device *v;
2833 int ret;
2834
2835 if (!vlanattr)
2836 return NULL;
2837
2838 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
2839 if (!v)
2840 return ERR_PTR(-ENODEV);
2841
2842 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
2843 ret = -EINVAL;
2844 goto error;
5727ef1b 2845 }
80b99899
JB
2846
2847 if (!netif_running(v)) {
2848 ret = -ENETDOWN;
2849 goto error;
2850 }
2851
2852 return v;
2853 error:
2854 dev_put(v);
2855 return ERR_PTR(ret);
5727ef1b
JB
2856}
2857
2858static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
2859{
4c476991 2860 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 2861 int err;
4c476991 2862 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
2863 struct station_parameters params;
2864 u8 *mac_addr = NULL;
2865
2866 memset(&params, 0, sizeof(params));
2867
2868 params.listen_interval = -1;
57cf8043 2869 params.plink_state = -1;
5727ef1b
JB
2870
2871 if (info->attrs[NL80211_ATTR_STA_AID])
2872 return -EINVAL;
2873
2874 if (!info->attrs[NL80211_ATTR_MAC])
2875 return -EINVAL;
2876
2877 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
2878
2879 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
2880 params.supported_rates =
2881 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
2882 params.supported_rates_len =
2883 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
2884 }
2885
2886 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
2887 params.listen_interval =
2888 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
2889
36aedc90
JM
2890 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
2891 params.ht_capa =
2892 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
2893
bdd90d5e
JB
2894 if (!rdev->ops->change_station)
2895 return -EOPNOTSUPP;
2896
bdd3ae3d 2897 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
2898 return -EINVAL;
2899
2ec600d6
LCC
2900 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2901 params.plink_action =
2902 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2903
9c3990aa
JC
2904 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE])
2905 params.plink_state =
2906 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
2907
a97f4424
JB
2908 switch (dev->ieee80211_ptr->iftype) {
2909 case NL80211_IFTYPE_AP:
2910 case NL80211_IFTYPE_AP_VLAN:
074ac8df 2911 case NL80211_IFTYPE_P2P_GO:
a97f4424
JB
2912 /* disallow mesh-specific things */
2913 if (params.plink_action)
bdd90d5e
JB
2914 return -EINVAL;
2915
2916 /* TDLS can't be set, ... */
2917 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
2918 return -EINVAL;
2919 /*
2920 * ... but don't bother the driver with it. This works around
2921 * a hostapd/wpa_supplicant issue -- it always includes the
2922 * TLDS_PEER flag in the mask even for AP mode.
2923 */
2924 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2925
2926 /* accept only the listed bits */
2927 if (params.sta_flags_mask &
2928 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
2929 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
2930 BIT(NL80211_STA_FLAG_WME) |
2931 BIT(NL80211_STA_FLAG_MFP)))
2932 return -EINVAL;
2933
2934 /* must be last in here for error handling */
2935 params.vlan = get_vlan(info, rdev);
2936 if (IS_ERR(params.vlan))
2937 return PTR_ERR(params.vlan);
a97f4424 2938 break;
074ac8df 2939 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 2940 case NL80211_IFTYPE_STATION:
bdd90d5e
JB
2941 /*
2942 * Don't allow userspace to change the TDLS_PEER flag,
2943 * but silently ignore attempts to change it since we
2944 * don't have state here to verify that it doesn't try
2945 * to change the flag.
2946 */
2947 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
267335d6
AQ
2948 /* fall through */
2949 case NL80211_IFTYPE_ADHOC:
2950 /* disallow things sta doesn't support */
2951 if (params.plink_action)
2952 return -EINVAL;
2953 if (params.ht_capa)
2954 return -EINVAL;
2955 if (params.listen_interval >= 0)
2956 return -EINVAL;
bdd90d5e
JB
2957 /* reject any changes other than AUTHORIZED */
2958 if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
2959 return -EINVAL;
a97f4424
JB
2960 break;
2961 case NL80211_IFTYPE_MESH_POINT:
2962 /* disallow things mesh doesn't support */
2963 if (params.vlan)
bdd90d5e 2964 return -EINVAL;
a97f4424 2965 if (params.ht_capa)
bdd90d5e 2966 return -EINVAL;
a97f4424 2967 if (params.listen_interval >= 0)
bdd90d5e
JB
2968 return -EINVAL;
2969 /*
2970 * No special handling for TDLS here -- the userspace
2971 * mesh code doesn't have this bug.
2972 */
b39c48fa
JC
2973 if (params.sta_flags_mask &
2974 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
8429828e 2975 BIT(NL80211_STA_FLAG_MFP) |
b39c48fa 2976 BIT(NL80211_STA_FLAG_AUTHORIZED)))
bdd90d5e 2977 return -EINVAL;
a97f4424
JB
2978 break;
2979 default:
bdd90d5e 2980 return -EOPNOTSUPP;
034d655e
JB
2981 }
2982
bdd90d5e 2983 /* be aware of params.vlan when changing code here */
5727ef1b 2984
79c97e97 2985 err = rdev->ops->change_station(&rdev->wiphy, dev, mac_addr, &params);
5727ef1b 2986
5727ef1b
JB
2987 if (params.vlan)
2988 dev_put(params.vlan);
3b85875a 2989
5727ef1b
JB
2990 return err;
2991}
2992
c75786c9
EP
2993static struct nla_policy
2994nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = {
2995 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
2996 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
2997};
2998
5727ef1b
JB
2999static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3000{
4c476991 3001 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 3002 int err;
4c476991 3003 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
3004 struct station_parameters params;
3005 u8 *mac_addr = NULL;
3006
3007 memset(&params, 0, sizeof(params));
3008
3009 if (!info->attrs[NL80211_ATTR_MAC])
3010 return -EINVAL;
3011
5727ef1b
JB
3012 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
3013 return -EINVAL;
3014
3015 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
3016 return -EINVAL;
3017
0e956c13
TLSC
3018 if (!info->attrs[NL80211_ATTR_STA_AID])
3019 return -EINVAL;
3020
5727ef1b
JB
3021 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3022 params.supported_rates =
3023 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
3024 params.supported_rates_len =
3025 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
3026 params.listen_interval =
3027 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 3028
0e956c13
TLSC
3029 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
3030 if (!params.aid || params.aid > IEEE80211_MAX_AID)
3031 return -EINVAL;
51b50fbe 3032
36aedc90
JM
3033 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
3034 params.ht_capa =
3035 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 3036
96b78dff
JC
3037 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
3038 params.plink_action =
3039 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
3040
bdd90d5e
JB
3041 if (!rdev->ops->add_station)
3042 return -EOPNOTSUPP;
3043
bdd3ae3d 3044 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
3045 return -EINVAL;
3046
bdd90d5e
JB
3047 switch (dev->ieee80211_ptr->iftype) {
3048 case NL80211_IFTYPE_AP:
3049 case NL80211_IFTYPE_AP_VLAN:
3050 case NL80211_IFTYPE_P2P_GO:
3051 /* parse WME attributes if sta is WME capable */
3052 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3053 (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) &&
3054 info->attrs[NL80211_ATTR_STA_WME]) {
3055 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
3056 struct nlattr *nla;
3057
3058 nla = info->attrs[NL80211_ATTR_STA_WME];
3059 err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla,
3060 nl80211_sta_wme_policy);
3061 if (err)
3062 return err;
3063
3064 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
3065 params.uapsd_queues =
3066 nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]);
3067 if (params.uapsd_queues &
3068 ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
3069 return -EINVAL;
c75786c9 3070
bdd90d5e
JB
3071 if (tb[NL80211_STA_WME_MAX_SP])
3072 params.max_sp =
3073 nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
c75786c9 3074
bdd90d5e
JB
3075 if (params.max_sp &
3076 ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
3077 return -EINVAL;
4319e193 3078
bdd90d5e
JB
3079 params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
3080 }
3081 /* TDLS peers cannot be added */
3082 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
4319e193 3083 return -EINVAL;
bdd90d5e
JB
3084 /* but don't bother the driver with it */
3085 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 3086
bdd90d5e
JB
3087 /* must be last in here for error handling */
3088 params.vlan = get_vlan(info, rdev);
3089 if (IS_ERR(params.vlan))
3090 return PTR_ERR(params.vlan);
3091 break;
3092 case NL80211_IFTYPE_MESH_POINT:
3093 /* TDLS peers cannot be added */
3094 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
3095 return -EINVAL;
3096 break;
3097 case NL80211_IFTYPE_STATION:
3098 /* Only TDLS peers can be added */
3099 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
3100 return -EINVAL;
3101 /* Can only add if TDLS ... */
3102 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
3103 return -EOPNOTSUPP;
3104 /* ... with external setup is supported */
3105 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
3106 return -EOPNOTSUPP;
3107 break;
3108 default:
3109 return -EOPNOTSUPP;
c75786c9
EP
3110 }
3111
bdd90d5e 3112 /* be aware of params.vlan when changing code here */
5727ef1b 3113
79c97e97 3114 err = rdev->ops->add_station(&rdev->wiphy, dev, mac_addr, &params);
5727ef1b 3115
5727ef1b
JB
3116 if (params.vlan)
3117 dev_put(params.vlan);
5727ef1b
JB
3118 return err;
3119}
3120
3121static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
3122{
4c476991
JB
3123 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3124 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
3125 u8 *mac_addr = NULL;
3126
3127 if (info->attrs[NL80211_ATTR_MAC])
3128 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3129
e80cf853 3130 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 3131 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 3132 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
3133 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3134 return -EINVAL;
5727ef1b 3135
4c476991
JB
3136 if (!rdev->ops->del_station)
3137 return -EOPNOTSUPP;
3b85875a 3138
4c476991 3139 return rdev->ops->del_station(&rdev->wiphy, dev, mac_addr);
5727ef1b
JB
3140}
3141
2ec600d6
LCC
3142static int nl80211_send_mpath(struct sk_buff *msg, u32 pid, u32 seq,
3143 int flags, struct net_device *dev,
3144 u8 *dst, u8 *next_hop,
3145 struct mpath_info *pinfo)
3146{
3147 void *hdr;
3148 struct nlattr *pinfoattr;
3149
3150 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_STATION);
3151 if (!hdr)
3152 return -1;
3153
9360ffd1
DM
3154 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3155 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
3156 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
3157 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
3158 goto nla_put_failure;
f5ea9120 3159
2ec600d6
LCC
3160 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO);
3161 if (!pinfoattr)
3162 goto nla_put_failure;
9360ffd1
DM
3163 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
3164 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
3165 pinfo->frame_qlen))
3166 goto nla_put_failure;
3167 if (((pinfo->filled & MPATH_INFO_SN) &&
3168 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
3169 ((pinfo->filled & MPATH_INFO_METRIC) &&
3170 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
3171 pinfo->metric)) ||
3172 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
3173 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
3174 pinfo->exptime)) ||
3175 ((pinfo->filled & MPATH_INFO_FLAGS) &&
3176 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
3177 pinfo->flags)) ||
3178 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
3179 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
3180 pinfo->discovery_timeout)) ||
3181 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
3182 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
3183 pinfo->discovery_retries)))
3184 goto nla_put_failure;
2ec600d6
LCC
3185
3186 nla_nest_end(msg, pinfoattr);
3187
3188 return genlmsg_end(msg, hdr);
3189
3190 nla_put_failure:
bc3ed28c
TG
3191 genlmsg_cancel(msg, hdr);
3192 return -EMSGSIZE;
2ec600d6
LCC
3193}
3194
3195static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 3196 struct netlink_callback *cb)
2ec600d6 3197{
2ec600d6
LCC
3198 struct mpath_info pinfo;
3199 struct cfg80211_registered_device *dev;
bba95fef 3200 struct net_device *netdev;
2ec600d6
LCC
3201 u8 dst[ETH_ALEN];
3202 u8 next_hop[ETH_ALEN];
bba95fef 3203 int path_idx = cb->args[1];
2ec600d6 3204 int err;
2ec600d6 3205
67748893
JB
3206 err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
3207 if (err)
3208 return err;
bba95fef
JB
3209
3210 if (!dev->ops->dump_mpath) {
eec60b03 3211 err = -EOPNOTSUPP;
bba95fef
JB
3212 goto out_err;
3213 }
3214
eec60b03
JM
3215 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) {
3216 err = -EOPNOTSUPP;
0448b5fc 3217 goto out_err;
eec60b03
JM
3218 }
3219
bba95fef
JB
3220 while (1) {
3221 err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,
3222 dst, next_hop, &pinfo);
3223 if (err == -ENOENT)
2ec600d6 3224 break;
bba95fef 3225 if (err)
3b85875a 3226 goto out_err;
2ec600d6 3227
bba95fef
JB
3228 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,
3229 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3230 netdev, dst, next_hop,
3231 &pinfo) < 0)
3232 goto out;
2ec600d6 3233
bba95fef 3234 path_idx++;
2ec600d6 3235 }
2ec600d6 3236
2ec600d6 3237
bba95fef
JB
3238 out:
3239 cb->args[1] = path_idx;
3240 err = skb->len;
bba95fef 3241 out_err:
67748893 3242 nl80211_finish_netdev_dump(dev);
bba95fef 3243 return err;
2ec600d6
LCC
3244}
3245
3246static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
3247{
4c476991 3248 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3249 int err;
4c476991 3250 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
3251 struct mpath_info pinfo;
3252 struct sk_buff *msg;
3253 u8 *dst = NULL;
3254 u8 next_hop[ETH_ALEN];
3255
3256 memset(&pinfo, 0, sizeof(pinfo));
3257
3258 if (!info->attrs[NL80211_ATTR_MAC])
3259 return -EINVAL;
3260
3261 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
3262
4c476991
JB
3263 if (!rdev->ops->get_mpath)
3264 return -EOPNOTSUPP;
2ec600d6 3265
4c476991
JB
3266 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
3267 return -EOPNOTSUPP;
eec60b03 3268
79c97e97 3269 err = rdev->ops->get_mpath(&rdev->wiphy, dev, dst, next_hop, &pinfo);
2ec600d6 3270 if (err)
4c476991 3271 return err;
2ec600d6 3272
fd2120ca 3273 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 3274 if (!msg)
4c476991 3275 return -ENOMEM;
2ec600d6
LCC
3276
3277 if (nl80211_send_mpath(msg, info->snd_pid, info->snd_seq, 0,
4c476991
JB
3278 dev, dst, next_hop, &pinfo) < 0) {
3279 nlmsg_free(msg);
3280 return -ENOBUFS;
3281 }
3b85875a 3282
4c476991 3283 return genlmsg_reply(msg, info);
2ec600d6
LCC
3284}
3285
3286static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
3287{
4c476991
JB
3288 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3289 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
3290 u8 *dst = NULL;
3291 u8 *next_hop = NULL;
3292
3293 if (!info->attrs[NL80211_ATTR_MAC])
3294 return -EINVAL;
3295
3296 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
3297 return -EINVAL;
3298
3299 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
3300 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
3301
4c476991
JB
3302 if (!rdev->ops->change_mpath)
3303 return -EOPNOTSUPP;
35a8efe1 3304
4c476991
JB
3305 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
3306 return -EOPNOTSUPP;
2ec600d6 3307
4c476991 3308 return rdev->ops->change_mpath(&rdev->wiphy, dev, dst, next_hop);
2ec600d6 3309}
4c476991 3310
2ec600d6
LCC
3311static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
3312{
4c476991
JB
3313 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3314 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
3315 u8 *dst = NULL;
3316 u8 *next_hop = NULL;
3317
3318 if (!info->attrs[NL80211_ATTR_MAC])
3319 return -EINVAL;
3320
3321 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
3322 return -EINVAL;
3323
3324 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
3325 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
3326
4c476991
JB
3327 if (!rdev->ops->add_mpath)
3328 return -EOPNOTSUPP;
35a8efe1 3329
4c476991
JB
3330 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
3331 return -EOPNOTSUPP;
2ec600d6 3332
4c476991 3333 return rdev->ops->add_mpath(&rdev->wiphy, dev, dst, next_hop);
2ec600d6
LCC
3334}
3335
3336static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
3337{
4c476991
JB
3338 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3339 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
3340 u8 *dst = NULL;
3341
3342 if (info->attrs[NL80211_ATTR_MAC])
3343 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
3344
4c476991
JB
3345 if (!rdev->ops->del_mpath)
3346 return -EOPNOTSUPP;
3b85875a 3347
4c476991 3348 return rdev->ops->del_mpath(&rdev->wiphy, dev, dst);
2ec600d6
LCC
3349}
3350
9f1ba906
JM
3351static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
3352{
4c476991
JB
3353 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3354 struct net_device *dev = info->user_ptr[1];
9f1ba906
JM
3355 struct bss_parameters params;
3356
3357 memset(&params, 0, sizeof(params));
3358 /* default to not changing parameters */
3359 params.use_cts_prot = -1;
3360 params.use_short_preamble = -1;
3361 params.use_short_slot_time = -1;
fd8aaaf3 3362 params.ap_isolate = -1;
50b12f59 3363 params.ht_opmode = -1;
9f1ba906
JM
3364
3365 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
3366 params.use_cts_prot =
3367 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
3368 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
3369 params.use_short_preamble =
3370 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
3371 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
3372 params.use_short_slot_time =
3373 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
3374 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
3375 params.basic_rates =
3376 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
3377 params.basic_rates_len =
3378 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
3379 }
fd8aaaf3
FF
3380 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
3381 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
3382 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
3383 params.ht_opmode =
3384 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 3385
4c476991
JB
3386 if (!rdev->ops->change_bss)
3387 return -EOPNOTSUPP;
9f1ba906 3388
074ac8df 3389 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
3390 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3391 return -EOPNOTSUPP;
3b85875a 3392
4c476991 3393 return rdev->ops->change_bss(&rdev->wiphy, dev, &params);
9f1ba906
JM
3394}
3395
b54452b0 3396static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
b2e1b302
LR
3397 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
3398 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
3399 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
3400 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
3401 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
3402 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
3403};
3404
3405static int parse_reg_rule(struct nlattr *tb[],
3406 struct ieee80211_reg_rule *reg_rule)
3407{
3408 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
3409 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
3410
3411 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
3412 return -EINVAL;
3413 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
3414 return -EINVAL;
3415 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
3416 return -EINVAL;
3417 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
3418 return -EINVAL;
3419 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
3420 return -EINVAL;
3421
3422 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
3423
3424 freq_range->start_freq_khz =
3425 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
3426 freq_range->end_freq_khz =
3427 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
3428 freq_range->max_bandwidth_khz =
3429 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
3430
3431 power_rule->max_eirp =
3432 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
3433
3434 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
3435 power_rule->max_antenna_gain =
3436 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
3437
3438 return 0;
3439}
3440
3441static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
3442{
3443 int r;
3444 char *data = NULL;
3445
80778f18
LR
3446 /*
3447 * You should only get this when cfg80211 hasn't yet initialized
3448 * completely when built-in to the kernel right between the time
3449 * window between nl80211_init() and regulatory_init(), if that is
3450 * even possible.
3451 */
3452 mutex_lock(&cfg80211_mutex);
3453 if (unlikely(!cfg80211_regdomain)) {
fe33eb39
LR
3454 mutex_unlock(&cfg80211_mutex);
3455 return -EINPROGRESS;
80778f18 3456 }
fe33eb39 3457 mutex_unlock(&cfg80211_mutex);
80778f18 3458
fe33eb39
LR
3459 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
3460 return -EINVAL;
b2e1b302
LR
3461
3462 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
3463
fe33eb39
LR
3464 r = regulatory_hint_user(data);
3465
b2e1b302
LR
3466 return r;
3467}
3468
24bdd9f4 3469static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 3470 struct genl_info *info)
93da9cc1 3471{
4c476991 3472 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 3473 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
3474 struct wireless_dev *wdev = dev->ieee80211_ptr;
3475 struct mesh_config cur_params;
3476 int err = 0;
93da9cc1 3477 void *hdr;
3478 struct nlattr *pinfoattr;
3479 struct sk_buff *msg;
3480
29cbe68c
JB
3481 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
3482 return -EOPNOTSUPP;
3483
24bdd9f4 3484 if (!rdev->ops->get_mesh_config)
4c476991 3485 return -EOPNOTSUPP;
f3f92586 3486
29cbe68c
JB
3487 wdev_lock(wdev);
3488 /* If not connected, get default parameters */
3489 if (!wdev->mesh_id_len)
3490 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
3491 else
24bdd9f4 3492 err = rdev->ops->get_mesh_config(&rdev->wiphy, dev,
29cbe68c
JB
3493 &cur_params);
3494 wdev_unlock(wdev);
3495
93da9cc1 3496 if (err)
4c476991 3497 return err;
93da9cc1 3498
3499 /* Draw up a netlink message to send back */
fd2120ca 3500 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3501 if (!msg)
3502 return -ENOMEM;
93da9cc1 3503 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
24bdd9f4 3504 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 3505 if (!hdr)
efe1cf0c 3506 goto out;
24bdd9f4 3507 pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 3508 if (!pinfoattr)
3509 goto nla_put_failure;
9360ffd1
DM
3510 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3511 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
3512 cur_params.dot11MeshRetryTimeout) ||
3513 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
3514 cur_params.dot11MeshConfirmTimeout) ||
3515 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
3516 cur_params.dot11MeshHoldingTimeout) ||
3517 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
3518 cur_params.dot11MeshMaxPeerLinks) ||
3519 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
3520 cur_params.dot11MeshMaxRetries) ||
3521 nla_put_u8(msg, NL80211_MESHCONF_TTL,
3522 cur_params.dot11MeshTTL) ||
3523 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
3524 cur_params.element_ttl) ||
3525 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
3526 cur_params.auto_open_plinks) ||
7eab0f64
JL
3527 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3528 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
3529 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3530 cur_params.dot11MeshHWMPmaxPREQretries) ||
3531 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
3532 cur_params.path_refresh_time) ||
3533 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
3534 cur_params.min_discovery_timeout) ||
3535 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
3536 cur_params.dot11MeshHWMPactivePathTimeout) ||
3537 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
3538 cur_params.dot11MeshHWMPpreqMinInterval) ||
3539 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
3540 cur_params.dot11MeshHWMPperrMinInterval) ||
3541 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
3542 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
3543 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
3544 cur_params.dot11MeshHWMPRootMode) ||
3545 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3546 cur_params.dot11MeshHWMPRannInterval) ||
3547 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3548 cur_params.dot11MeshGateAnnouncementProtocol) ||
3549 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
3550 cur_params.dot11MeshForwarding) ||
3551 nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
3552 cur_params.rssi_threshold) ||
3553 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
3554 cur_params.ht_opmode) ||
3555 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
3556 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
3557 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
3558 cur_params.dot11MeshHWMProotInterval) ||
3559 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3560 cur_params.dot11MeshHWMPconfirmationInterval))
9360ffd1 3561 goto nla_put_failure;
93da9cc1 3562 nla_nest_end(msg, pinfoattr);
3563 genlmsg_end(msg, hdr);
4c476991 3564 return genlmsg_reply(msg, info);
93da9cc1 3565
3b85875a 3566 nla_put_failure:
93da9cc1 3567 genlmsg_cancel(msg, hdr);
efe1cf0c 3568 out:
d080e275 3569 nlmsg_free(msg);
4c476991 3570 return -ENOBUFS;
93da9cc1 3571}
3572
b54452b0 3573static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
93da9cc1 3574 [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 },
3575 [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 },
3576 [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 },
3577 [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 },
3578 [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 },
3579 [NL80211_MESHCONF_TTL] = { .type = NLA_U8 },
45904f21 3580 [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 },
93da9cc1 3581 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 },
d299a1f2 3582 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 },
93da9cc1 3583 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
3584 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
3585 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 },
3586 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
3587 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 },
dca7e943 3588 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 },
93da9cc1 3589 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 },
699403db 3590 [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 },
0507e159 3591 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 },
16dd7267 3592 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 },
94f90656 3593 [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 },
a4f606ea
CYY
3594 [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 },
3595 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6
CYY
3596 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
3597 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 },
728b19e5 3598 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
93da9cc1 3599};
3600
c80d545d
JC
3601static const struct nla_policy
3602 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 3603 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
3604 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
3605 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 3606 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
581a8b0f 3607 [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY,
a4f606ea 3608 .len = IEEE80211_MAX_DATA_LEN },
b130e5ce 3609 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
3610};
3611
24bdd9f4 3612static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
3613 struct mesh_config *cfg,
3614 u32 *mask_out)
93da9cc1 3615{
93da9cc1 3616 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 3617 u32 mask = 0;
93da9cc1 3618
bd90fdcc
JB
3619#define FILL_IN_MESH_PARAM_IF_SET(table, cfg, param, mask, attr_num, nla_fn) \
3620do {\
3621 if (table[attr_num]) {\
3622 cfg->param = nla_fn(table[attr_num]); \
3623 mask |= (1 << (attr_num - 1)); \
3624 } \
3625} while (0);\
3626
3627
24bdd9f4 3628 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 3629 return -EINVAL;
3630 if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX,
24bdd9f4 3631 info->attrs[NL80211_ATTR_MESH_CONFIG],
bd90fdcc 3632 nl80211_meshconf_params_policy))
93da9cc1 3633 return -EINVAL;
3634
93da9cc1 3635 /* This makes sure that there aren't more than 32 mesh config
3636 * parameters (otherwise our bitfield scheme would not work.) */
3637 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
3638
3639 /* Fill in the params struct */
93da9cc1 3640 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout,
a4f606ea
CYY
3641 mask, NL80211_MESHCONF_RETRY_TIMEOUT,
3642 nla_get_u16);
93da9cc1 3643 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout,
a4f606ea
CYY
3644 mask, NL80211_MESHCONF_CONFIRM_TIMEOUT,
3645 nla_get_u16);
93da9cc1 3646 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout,
a4f606ea
CYY
3647 mask, NL80211_MESHCONF_HOLDING_TIMEOUT,
3648 nla_get_u16);
93da9cc1 3649 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks,
a4f606ea
CYY
3650 mask, NL80211_MESHCONF_MAX_PEER_LINKS,
3651 nla_get_u16);
93da9cc1 3652 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries,
a4f606ea
CYY
3653 mask, NL80211_MESHCONF_MAX_RETRIES,
3654 nla_get_u8);
93da9cc1 3655 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL,
a4f606ea 3656 mask, NL80211_MESHCONF_TTL, nla_get_u8);
45904f21 3657 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl,
a4f606ea
CYY
3658 mask, NL80211_MESHCONF_ELEMENT_TTL,
3659 nla_get_u8);
93da9cc1 3660 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks,
a4f606ea
CYY
3661 mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
3662 nla_get_u8);
3663 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask,
3664 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
3665 nla_get_u32);
93da9cc1 3666 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries,
a4f606ea
CYY
3667 mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
3668 nla_get_u8);
93da9cc1 3669 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time,
a4f606ea
CYY
3670 mask, NL80211_MESHCONF_PATH_REFRESH_TIME,
3671 nla_get_u32);
93da9cc1 3672 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout,
a4f606ea
CYY
3673 mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
3674 nla_get_u16);
3675 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask,
3676 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
3677 nla_get_u32);
93da9cc1 3678 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval,
a4f606ea
CYY
3679 mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
3680 nla_get_u16);
dca7e943 3681 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval,
a4f606ea
CYY
3682 mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
3683 nla_get_u16);
0507e159 3684 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
a4f606ea
CYY
3685 dot11MeshHWMPnetDiameterTraversalTime, mask,
3686 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
3687 nla_get_u16);
3688 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
3689 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
3690 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
3691 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
3692 nla_get_u16);
16dd7267 3693 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
a4f606ea
CYY
3694 dot11MeshGateAnnouncementProtocol, mask,
3695 NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
3696 nla_get_u8);
94f90656 3697 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding,
a4f606ea
CYY
3698 mask, NL80211_MESHCONF_FORWARDING,
3699 nla_get_u8);
55335137 3700 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold,
a4f606ea
CYY
3701 mask, NL80211_MESHCONF_RSSI_THRESHOLD,
3702 nla_get_u32);
70c33eaa 3703 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode,
a4f606ea 3704 mask, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
3705 nla_get_u16);
3706 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout,
3707 mask,
3708 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
3709 nla_get_u32);
3710 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval,
3711 mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
3712 nla_get_u16);
3713 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
3714 dot11MeshHWMPconfirmationInterval, mask,
3715 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
a4f606ea 3716 nla_get_u16);
bd90fdcc
JB
3717 if (mask_out)
3718 *mask_out = mask;
c80d545d 3719
bd90fdcc
JB
3720 return 0;
3721
3722#undef FILL_IN_MESH_PARAM_IF_SET
3723}
3724
c80d545d
JC
3725static int nl80211_parse_mesh_setup(struct genl_info *info,
3726 struct mesh_setup *setup)
3727{
3728 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
3729
3730 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
3731 return -EINVAL;
3732 if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX,
3733 info->attrs[NL80211_ATTR_MESH_SETUP],
3734 nl80211_mesh_setup_params_policy))
3735 return -EINVAL;
3736
d299a1f2
JC
3737 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
3738 setup->sync_method =
3739 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
3740 IEEE80211_SYNC_METHOD_VENDOR :
3741 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
3742
c80d545d
JC
3743 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
3744 setup->path_sel_proto =
3745 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
3746 IEEE80211_PATH_PROTOCOL_VENDOR :
3747 IEEE80211_PATH_PROTOCOL_HWMP;
3748
3749 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
3750 setup->path_metric =
3751 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
3752 IEEE80211_PATH_METRIC_VENDOR :
3753 IEEE80211_PATH_METRIC_AIRTIME;
3754
581a8b0f
JC
3755
3756 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 3757 struct nlattr *ieattr =
581a8b0f 3758 tb[NL80211_MESH_SETUP_IE];
c80d545d
JC
3759 if (!is_valid_ie_attr(ieattr))
3760 return -EINVAL;
581a8b0f
JC
3761 setup->ie = nla_data(ieattr);
3762 setup->ie_len = nla_len(ieattr);
c80d545d 3763 }
b130e5ce
JC
3764 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
3765 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
c80d545d
JC
3766
3767 return 0;
3768}
3769
24bdd9f4 3770static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 3771 struct genl_info *info)
bd90fdcc
JB
3772{
3773 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3774 struct net_device *dev = info->user_ptr[1];
29cbe68c 3775 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
3776 struct mesh_config cfg;
3777 u32 mask;
3778 int err;
3779
29cbe68c
JB
3780 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
3781 return -EOPNOTSUPP;
3782
24bdd9f4 3783 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
3784 return -EOPNOTSUPP;
3785
24bdd9f4 3786 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
3787 if (err)
3788 return err;
3789
29cbe68c
JB
3790 wdev_lock(wdev);
3791 if (!wdev->mesh_id_len)
3792 err = -ENOLINK;
3793
3794 if (!err)
24bdd9f4 3795 err = rdev->ops->update_mesh_config(&rdev->wiphy, dev,
29cbe68c
JB
3796 mask, &cfg);
3797
3798 wdev_unlock(wdev);
3799
3800 return err;
93da9cc1 3801}
3802
f130347c
LR
3803static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
3804{
3805 struct sk_buff *msg;
3806 void *hdr = NULL;
3807 struct nlattr *nl_reg_rules;
3808 unsigned int i;
3809 int err = -EINVAL;
3810
a1794390 3811 mutex_lock(&cfg80211_mutex);
f130347c
LR
3812
3813 if (!cfg80211_regdomain)
3814 goto out;
3815
fd2120ca 3816 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
f130347c
LR
3817 if (!msg) {
3818 err = -ENOBUFS;
3819 goto out;
3820 }
3821
3822 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
3823 NL80211_CMD_GET_REG);
3824 if (!hdr)
efe1cf0c 3825 goto put_failure;
f130347c 3826
9360ffd1
DM
3827 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
3828 cfg80211_regdomain->alpha2) ||
3829 (cfg80211_regdomain->dfs_region &&
3830 nla_put_u8(msg, NL80211_ATTR_DFS_REGION,
3831 cfg80211_regdomain->dfs_region)))
3832 goto nla_put_failure;
f130347c
LR
3833
3834 nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES);
3835 if (!nl_reg_rules)
3836 goto nla_put_failure;
3837
3838 for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) {
3839 struct nlattr *nl_reg_rule;
3840 const struct ieee80211_reg_rule *reg_rule;
3841 const struct ieee80211_freq_range *freq_range;
3842 const struct ieee80211_power_rule *power_rule;
3843
3844 reg_rule = &cfg80211_regdomain->reg_rules[i];
3845 freq_range = &reg_rule->freq_range;
3846 power_rule = &reg_rule->power_rule;
3847
3848 nl_reg_rule = nla_nest_start(msg, i);
3849 if (!nl_reg_rule)
3850 goto nla_put_failure;
3851
9360ffd1
DM
3852 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
3853 reg_rule->flags) ||
3854 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
3855 freq_range->start_freq_khz) ||
3856 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
3857 freq_range->end_freq_khz) ||
3858 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
3859 freq_range->max_bandwidth_khz) ||
3860 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
3861 power_rule->max_antenna_gain) ||
3862 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
3863 power_rule->max_eirp))
3864 goto nla_put_failure;
f130347c
LR
3865
3866 nla_nest_end(msg, nl_reg_rule);
3867 }
3868
3869 nla_nest_end(msg, nl_reg_rules);
3870
3871 genlmsg_end(msg, hdr);
134e6375 3872 err = genlmsg_reply(msg, info);
f130347c
LR
3873 goto out;
3874
3875nla_put_failure:
3876 genlmsg_cancel(msg, hdr);
efe1cf0c 3877put_failure:
d080e275 3878 nlmsg_free(msg);
f130347c
LR
3879 err = -EMSGSIZE;
3880out:
a1794390 3881 mutex_unlock(&cfg80211_mutex);
f130347c
LR
3882 return err;
3883}
3884
b2e1b302
LR
3885static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
3886{
3887 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
3888 struct nlattr *nl_reg_rule;
3889 char *alpha2 = NULL;
3890 int rem_reg_rules = 0, r = 0;
3891 u32 num_rules = 0, rule_idx = 0, size_of_regd;
8b60b078 3892 u8 dfs_region = 0;
b2e1b302
LR
3893 struct ieee80211_regdomain *rd = NULL;
3894
3895 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
3896 return -EINVAL;
3897
3898 if (!info->attrs[NL80211_ATTR_REG_RULES])
3899 return -EINVAL;
3900
3901 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
3902
8b60b078
LR
3903 if (info->attrs[NL80211_ATTR_DFS_REGION])
3904 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
3905
b2e1b302
LR
3906 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
3907 rem_reg_rules) {
3908 num_rules++;
3909 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 3910 return -EINVAL;
b2e1b302
LR
3911 }
3912
61405e97
LR
3913 mutex_lock(&cfg80211_mutex);
3914
d0e18f83
LR
3915 if (!reg_is_valid_request(alpha2)) {
3916 r = -EINVAL;
3917 goto bad_reg;
3918 }
b2e1b302
LR
3919
3920 size_of_regd = sizeof(struct ieee80211_regdomain) +
3921 (num_rules * sizeof(struct ieee80211_reg_rule));
3922
3923 rd = kzalloc(size_of_regd, GFP_KERNEL);
d0e18f83
LR
3924 if (!rd) {
3925 r = -ENOMEM;
3926 goto bad_reg;
3927 }
b2e1b302
LR
3928
3929 rd->n_reg_rules = num_rules;
3930 rd->alpha2[0] = alpha2[0];
3931 rd->alpha2[1] = alpha2[1];
3932
8b60b078
LR
3933 /*
3934 * Disable DFS master mode if the DFS region was
3935 * not supported or known on this kernel.
3936 */
3937 if (reg_supported_dfs_region(dfs_region))
3938 rd->dfs_region = dfs_region;
3939
b2e1b302
LR
3940 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
3941 rem_reg_rules) {
3942 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
3943 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
3944 reg_rule_policy);
3945 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
3946 if (r)
3947 goto bad_reg;
3948
3949 rule_idx++;
3950
d0e18f83
LR
3951 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
3952 r = -EINVAL;
b2e1b302 3953 goto bad_reg;
d0e18f83 3954 }
b2e1b302
LR
3955 }
3956
3957 BUG_ON(rule_idx != num_rules);
3958
b2e1b302 3959 r = set_regdom(rd);
61405e97 3960
a1794390 3961 mutex_unlock(&cfg80211_mutex);
d0e18f83 3962
b2e1b302
LR
3963 return r;
3964
d2372b31 3965 bad_reg:
61405e97 3966 mutex_unlock(&cfg80211_mutex);
b2e1b302 3967 kfree(rd);
d0e18f83 3968 return r;
b2e1b302
LR
3969}
3970
83f5e2cf
JB
3971static int validate_scan_freqs(struct nlattr *freqs)
3972{
3973 struct nlattr *attr1, *attr2;
3974 int n_channels = 0, tmp1, tmp2;
3975
3976 nla_for_each_nested(attr1, freqs, tmp1) {
3977 n_channels++;
3978 /*
3979 * Some hardware has a limited channel list for
3980 * scanning, and it is pretty much nonsensical
3981 * to scan for a channel twice, so disallow that
3982 * and don't require drivers to check that the
3983 * channel list they get isn't longer than what
3984 * they can scan, as long as they can scan all
3985 * the channels they registered at once.
3986 */
3987 nla_for_each_nested(attr2, freqs, tmp2)
3988 if (attr1 != attr2 &&
3989 nla_get_u32(attr1) == nla_get_u32(attr2))
3990 return 0;
3991 }
3992
3993 return n_channels;
3994}
3995
2a519311
JB
3996static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3997{
4c476991
JB
3998 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3999 struct net_device *dev = info->user_ptr[1];
2a519311 4000 struct cfg80211_scan_request *request;
2a519311
JB
4001 struct nlattr *attr;
4002 struct wiphy *wiphy;
83f5e2cf 4003 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 4004 size_t ie_len;
2a519311 4005
f4a11bb0
JB
4006 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4007 return -EINVAL;
4008
79c97e97 4009 wiphy = &rdev->wiphy;
2a519311 4010
4c476991
JB
4011 if (!rdev->ops->scan)
4012 return -EOPNOTSUPP;
2a519311 4013
4c476991
JB
4014 if (rdev->scan_req)
4015 return -EBUSY;
2a519311
JB
4016
4017 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
4018 n_channels = validate_scan_freqs(
4019 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
4c476991
JB
4020 if (!n_channels)
4021 return -EINVAL;
2a519311 4022 } else {
34850ab2 4023 enum ieee80211_band band;
83f5e2cf
JB
4024 n_channels = 0;
4025
2a519311
JB
4026 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
4027 if (wiphy->bands[band])
4028 n_channels += wiphy->bands[band]->n_channels;
4029 }
4030
4031 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
4032 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
4033 n_ssids++;
4034
4c476991
JB
4035 if (n_ssids > wiphy->max_scan_ssids)
4036 return -EINVAL;
2a519311 4037
70692ad2
JM
4038 if (info->attrs[NL80211_ATTR_IE])
4039 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
4040 else
4041 ie_len = 0;
4042
4c476991
JB
4043 if (ie_len > wiphy->max_scan_ie_len)
4044 return -EINVAL;
18a83659 4045
2a519311 4046 request = kzalloc(sizeof(*request)
a2cd43c5
LC
4047 + sizeof(*request->ssids) * n_ssids
4048 + sizeof(*request->channels) * n_channels
70692ad2 4049 + ie_len, GFP_KERNEL);
4c476991
JB
4050 if (!request)
4051 return -ENOMEM;
2a519311 4052
2a519311 4053 if (n_ssids)
5ba63533 4054 request->ssids = (void *)&request->channels[n_channels];
2a519311 4055 request->n_ssids = n_ssids;
70692ad2
JM
4056 if (ie_len) {
4057 if (request->ssids)
4058 request->ie = (void *)(request->ssids + n_ssids);
4059 else
4060 request->ie = (void *)(request->channels + n_channels);
4061 }
2a519311 4062
584991dc 4063 i = 0;
2a519311
JB
4064 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
4065 /* user specified, bail out if channel not found */
2a519311 4066 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
4067 struct ieee80211_channel *chan;
4068
4069 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
4070
4071 if (!chan) {
2a519311
JB
4072 err = -EINVAL;
4073 goto out_free;
4074 }
584991dc
JB
4075
4076 /* ignore disabled channels */
4077 if (chan->flags & IEEE80211_CHAN_DISABLED)
4078 continue;
4079
4080 request->channels[i] = chan;
2a519311
JB
4081 i++;
4082 }
4083 } else {
34850ab2
JB
4084 enum ieee80211_band band;
4085
2a519311 4086 /* all channels */
2a519311
JB
4087 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
4088 int j;
4089 if (!wiphy->bands[band])
4090 continue;
4091 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
4092 struct ieee80211_channel *chan;
4093
4094 chan = &wiphy->bands[band]->channels[j];
4095
4096 if (chan->flags & IEEE80211_CHAN_DISABLED)
4097 continue;
4098
4099 request->channels[i] = chan;
2a519311
JB
4100 i++;
4101 }
4102 }
4103 }
4104
584991dc
JB
4105 if (!i) {
4106 err = -EINVAL;
4107 goto out_free;
4108 }
4109
4110 request->n_channels = i;
4111
2a519311
JB
4112 i = 0;
4113 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
4114 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 4115 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
4116 err = -EINVAL;
4117 goto out_free;
4118 }
57a27e1d 4119 request->ssids[i].ssid_len = nla_len(attr);
2a519311 4120 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
4121 i++;
4122 }
4123 }
4124
70692ad2
JM
4125 if (info->attrs[NL80211_ATTR_IE]) {
4126 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
4127 memcpy((void *)request->ie,
4128 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
4129 request->ie_len);
4130 }
4131
34850ab2 4132 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
a401d2bb
JB
4133 if (wiphy->bands[i])
4134 request->rates[i] =
4135 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
4136
4137 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
4138 nla_for_each_nested(attr,
4139 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
4140 tmp) {
4141 enum ieee80211_band band = nla_type(attr);
4142
84404623 4143 if (band < 0 || band >= IEEE80211_NUM_BANDS) {
34850ab2
JB
4144 err = -EINVAL;
4145 goto out_free;
4146 }
4147 err = ieee80211_get_ratemask(wiphy->bands[band],
4148 nla_data(attr),
4149 nla_len(attr),
4150 &request->rates[band]);
4151 if (err)
4152 goto out_free;
4153 }
4154 }
4155
e9f935e3
RM
4156 request->no_cck =
4157 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
4158
463d0183 4159 request->dev = dev;
79c97e97 4160 request->wiphy = &rdev->wiphy;
2a519311 4161
79c97e97
JB
4162 rdev->scan_req = request;
4163 err = rdev->ops->scan(&rdev->wiphy, dev, request);
2a519311 4164
463d0183 4165 if (!err) {
79c97e97 4166 nl80211_send_scan_start(rdev, dev);
463d0183 4167 dev_hold(dev);
4c476991 4168 } else {
2a519311 4169 out_free:
79c97e97 4170 rdev->scan_req = NULL;
2a519311
JB
4171 kfree(request);
4172 }
3b85875a 4173
2a519311
JB
4174 return err;
4175}
4176
807f8a8c
LC
4177static int nl80211_start_sched_scan(struct sk_buff *skb,
4178 struct genl_info *info)
4179{
4180 struct cfg80211_sched_scan_request *request;
4181 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4182 struct net_device *dev = info->user_ptr[1];
807f8a8c
LC
4183 struct nlattr *attr;
4184 struct wiphy *wiphy;
a1f1c21c 4185 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i;
bbe6ad6d 4186 u32 interval;
807f8a8c
LC
4187 enum ieee80211_band band;
4188 size_t ie_len;
a1f1c21c 4189 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
807f8a8c
LC
4190
4191 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
4192 !rdev->ops->sched_scan_start)
4193 return -EOPNOTSUPP;
4194
4195 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4196 return -EINVAL;
4197
bbe6ad6d
LC
4198 if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
4199 return -EINVAL;
4200
4201 interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
4202 if (interval == 0)
4203 return -EINVAL;
4204
807f8a8c
LC
4205 wiphy = &rdev->wiphy;
4206
4207 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
4208 n_channels = validate_scan_freqs(
4209 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
4210 if (!n_channels)
4211 return -EINVAL;
4212 } else {
4213 n_channels = 0;
4214
4215 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
4216 if (wiphy->bands[band])
4217 n_channels += wiphy->bands[band]->n_channels;
4218 }
4219
4220 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
4221 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
4222 tmp)
4223 n_ssids++;
4224
93b6aa69 4225 if (n_ssids > wiphy->max_sched_scan_ssids)
807f8a8c
LC
4226 return -EINVAL;
4227
a1f1c21c
LC
4228 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH])
4229 nla_for_each_nested(attr,
4230 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
4231 tmp)
4232 n_match_sets++;
4233
4234 if (n_match_sets > wiphy->max_match_sets)
4235 return -EINVAL;
4236
807f8a8c
LC
4237 if (info->attrs[NL80211_ATTR_IE])
4238 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
4239 else
4240 ie_len = 0;
4241
5a865bad 4242 if (ie_len > wiphy->max_sched_scan_ie_len)
807f8a8c
LC
4243 return -EINVAL;
4244
c10841ca
LC
4245 mutex_lock(&rdev->sched_scan_mtx);
4246
4247 if (rdev->sched_scan_req) {
4248 err = -EINPROGRESS;
4249 goto out;
4250 }
4251
807f8a8c 4252 request = kzalloc(sizeof(*request)
a2cd43c5 4253 + sizeof(*request->ssids) * n_ssids
a1f1c21c 4254 + sizeof(*request->match_sets) * n_match_sets
a2cd43c5 4255 + sizeof(*request->channels) * n_channels
807f8a8c 4256 + ie_len, GFP_KERNEL);
c10841ca
LC
4257 if (!request) {
4258 err = -ENOMEM;
4259 goto out;
4260 }
807f8a8c
LC
4261
4262 if (n_ssids)
4263 request->ssids = (void *)&request->channels[n_channels];
4264 request->n_ssids = n_ssids;
4265 if (ie_len) {
4266 if (request->ssids)
4267 request->ie = (void *)(request->ssids + n_ssids);
4268 else
4269 request->ie = (void *)(request->channels + n_channels);
4270 }
4271
a1f1c21c
LC
4272 if (n_match_sets) {
4273 if (request->ie)
4274 request->match_sets = (void *)(request->ie + ie_len);
4275 else if (request->ssids)
4276 request->match_sets =
4277 (void *)(request->ssids + n_ssids);
4278 else
4279 request->match_sets =
4280 (void *)(request->channels + n_channels);
4281 }
4282 request->n_match_sets = n_match_sets;
4283
807f8a8c
LC
4284 i = 0;
4285 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
4286 /* user specified, bail out if channel not found */
4287 nla_for_each_nested(attr,
4288 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES],
4289 tmp) {
4290 struct ieee80211_channel *chan;
4291
4292 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
4293
4294 if (!chan) {
4295 err = -EINVAL;
4296 goto out_free;
4297 }
4298
4299 /* ignore disabled channels */
4300 if (chan->flags & IEEE80211_CHAN_DISABLED)
4301 continue;
4302
4303 request->channels[i] = chan;
4304 i++;
4305 }
4306 } else {
4307 /* all channels */
4308 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
4309 int j;
4310 if (!wiphy->bands[band])
4311 continue;
4312 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
4313 struct ieee80211_channel *chan;
4314
4315 chan = &wiphy->bands[band]->channels[j];
4316
4317 if (chan->flags & IEEE80211_CHAN_DISABLED)
4318 continue;
4319
4320 request->channels[i] = chan;
4321 i++;
4322 }
4323 }
4324 }
4325
4326 if (!i) {
4327 err = -EINVAL;
4328 goto out_free;
4329 }
4330
4331 request->n_channels = i;
4332
4333 i = 0;
4334 if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
4335 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
4336 tmp) {
57a27e1d 4337 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
4338 err = -EINVAL;
4339 goto out_free;
4340 }
57a27e1d 4341 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
4342 memcpy(request->ssids[i].ssid, nla_data(attr),
4343 nla_len(attr));
807f8a8c
LC
4344 i++;
4345 }
4346 }
4347
a1f1c21c
LC
4348 i = 0;
4349 if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
4350 nla_for_each_nested(attr,
4351 info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
4352 tmp) {
4353 struct nlattr *ssid;
4354
4355 nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
4356 nla_data(attr), nla_len(attr),
4357 nl80211_match_policy);
4a4ab0d7 4358 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
a1f1c21c
LC
4359 if (ssid) {
4360 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
4361 err = -EINVAL;
4362 goto out_free;
4363 }
4364 memcpy(request->match_sets[i].ssid.ssid,
4365 nla_data(ssid), nla_len(ssid));
4366 request->match_sets[i].ssid.ssid_len =
4367 nla_len(ssid);
4368 }
4369 i++;
4370 }
4371 }
4372
807f8a8c
LC
4373 if (info->attrs[NL80211_ATTR_IE]) {
4374 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
4375 memcpy((void *)request->ie,
4376 nla_data(info->attrs[NL80211_ATTR_IE]),
4377 request->ie_len);
4378 }
4379
4380 request->dev = dev;
4381 request->wiphy = &rdev->wiphy;
bbe6ad6d 4382 request->interval = interval;
807f8a8c
LC
4383
4384 err = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request);
4385 if (!err) {
4386 rdev->sched_scan_req = request;
4387 nl80211_send_sched_scan(rdev, dev,
4388 NL80211_CMD_START_SCHED_SCAN);
4389 goto out;
4390 }
4391
4392out_free:
4393 kfree(request);
4394out:
c10841ca 4395 mutex_unlock(&rdev->sched_scan_mtx);
807f8a8c
LC
4396 return err;
4397}
4398
4399static int nl80211_stop_sched_scan(struct sk_buff *skb,
4400 struct genl_info *info)
4401{
4402 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c10841ca 4403 int err;
807f8a8c
LC
4404
4405 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
4406 !rdev->ops->sched_scan_stop)
4407 return -EOPNOTSUPP;
4408
c10841ca
LC
4409 mutex_lock(&rdev->sched_scan_mtx);
4410 err = __cfg80211_stop_sched_scan(rdev, false);
4411 mutex_unlock(&rdev->sched_scan_mtx);
4412
4413 return err;
807f8a8c
LC
4414}
4415
9720bb3a
JB
4416static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
4417 u32 seq, int flags,
2a519311 4418 struct cfg80211_registered_device *rdev,
48ab905d
JB
4419 struct wireless_dev *wdev,
4420 struct cfg80211_internal_bss *intbss)
2a519311 4421{
48ab905d 4422 struct cfg80211_bss *res = &intbss->pub;
2a519311
JB
4423 void *hdr;
4424 struct nlattr *bss;
48ab905d
JB
4425
4426 ASSERT_WDEV_LOCK(wdev);
2a519311 4427
9720bb3a 4428 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).pid, seq, flags,
2a519311
JB
4429 NL80211_CMD_NEW_SCAN_RESULTS);
4430 if (!hdr)
4431 return -1;
4432
9720bb3a
JB
4433 genl_dump_check_consistent(cb, hdr, &nl80211_fam);
4434
9360ffd1
DM
4435 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation) ||
4436 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
4437 goto nla_put_failure;
2a519311
JB
4438
4439 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
4440 if (!bss)
4441 goto nla_put_failure;
9360ffd1
DM
4442 if ((!is_zero_ether_addr(res->bssid) &&
4443 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)) ||
4444 (res->information_elements && res->len_information_elements &&
4445 nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
4446 res->len_information_elements,
4447 res->information_elements)) ||
4448 (res->beacon_ies && res->len_beacon_ies &&
4449 res->beacon_ies != res->information_elements &&
4450 nla_put(msg, NL80211_BSS_BEACON_IES,
4451 res->len_beacon_ies, res->beacon_ies)))
4452 goto nla_put_failure;
4453 if (res->tsf &&
4454 nla_put_u64(msg, NL80211_BSS_TSF, res->tsf))
4455 goto nla_put_failure;
4456 if (res->beacon_interval &&
4457 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
4458 goto nla_put_failure;
4459 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
4460 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
4461 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
4462 jiffies_to_msecs(jiffies - intbss->ts)))
4463 goto nla_put_failure;
2a519311 4464
77965c97 4465 switch (rdev->wiphy.signal_type) {
2a519311 4466 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
4467 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
4468 goto nla_put_failure;
2a519311
JB
4469 break;
4470 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
4471 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
4472 goto nla_put_failure;
2a519311
JB
4473 break;
4474 default:
4475 break;
4476 }
4477
48ab905d 4478 switch (wdev->iftype) {
074ac8df 4479 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 4480 case NL80211_IFTYPE_STATION:
9360ffd1
DM
4481 if (intbss == wdev->current_bss &&
4482 nla_put_u32(msg, NL80211_BSS_STATUS,
4483 NL80211_BSS_STATUS_ASSOCIATED))
4484 goto nla_put_failure;
48ab905d
JB
4485 break;
4486 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
4487 if (intbss == wdev->current_bss &&
4488 nla_put_u32(msg, NL80211_BSS_STATUS,
4489 NL80211_BSS_STATUS_IBSS_JOINED))
4490 goto nla_put_failure;
48ab905d
JB
4491 break;
4492 default:
4493 break;
4494 }
4495
2a519311
JB
4496 nla_nest_end(msg, bss);
4497
4498 return genlmsg_end(msg, hdr);
4499
4500 nla_put_failure:
4501 genlmsg_cancel(msg, hdr);
4502 return -EMSGSIZE;
4503}
4504
4505static int nl80211_dump_scan(struct sk_buff *skb,
4506 struct netlink_callback *cb)
4507{
48ab905d
JB
4508 struct cfg80211_registered_device *rdev;
4509 struct net_device *dev;
2a519311 4510 struct cfg80211_internal_bss *scan;
48ab905d 4511 struct wireless_dev *wdev;
2a519311
JB
4512 int start = cb->args[1], idx = 0;
4513 int err;
4514
67748893
JB
4515 err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev);
4516 if (err)
4517 return err;
2a519311 4518
48ab905d 4519 wdev = dev->ieee80211_ptr;
2a519311 4520
48ab905d
JB
4521 wdev_lock(wdev);
4522 spin_lock_bh(&rdev->bss_lock);
4523 cfg80211_bss_expire(rdev);
4524
9720bb3a
JB
4525 cb->seq = rdev->bss_generation;
4526
48ab905d 4527 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
4528 if (++idx <= start)
4529 continue;
9720bb3a 4530 if (nl80211_send_bss(skb, cb,
2a519311 4531 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 4532 rdev, wdev, scan) < 0) {
2a519311 4533 idx--;
67748893 4534 break;
2a519311
JB
4535 }
4536 }
4537
48ab905d
JB
4538 spin_unlock_bh(&rdev->bss_lock);
4539 wdev_unlock(wdev);
2a519311
JB
4540
4541 cb->args[1] = idx;
67748893 4542 nl80211_finish_netdev_dump(rdev);
2a519311 4543
67748893 4544 return skb->len;
2a519311
JB
4545}
4546
61fa713c
HS
4547static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
4548 int flags, struct net_device *dev,
4549 struct survey_info *survey)
4550{
4551 void *hdr;
4552 struct nlattr *infoattr;
4553
61fa713c
HS
4554 hdr = nl80211hdr_put(msg, pid, seq, flags,
4555 NL80211_CMD_NEW_SURVEY_RESULTS);
4556 if (!hdr)
4557 return -ENOMEM;
4558
9360ffd1
DM
4559 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
4560 goto nla_put_failure;
61fa713c
HS
4561
4562 infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO);
4563 if (!infoattr)
4564 goto nla_put_failure;
4565
9360ffd1
DM
4566 if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
4567 survey->channel->center_freq))
4568 goto nla_put_failure;
4569
4570 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
4571 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
4572 goto nla_put_failure;
4573 if ((survey->filled & SURVEY_INFO_IN_USE) &&
4574 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
4575 goto nla_put_failure;
4576 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME) &&
4577 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
4578 survey->channel_time))
4579 goto nla_put_failure;
4580 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) &&
4581 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
4582 survey->channel_time_busy))
4583 goto nla_put_failure;
4584 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) &&
4585 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
4586 survey->channel_time_ext_busy))
4587 goto nla_put_failure;
4588 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) &&
4589 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
4590 survey->channel_time_rx))
4591 goto nla_put_failure;
4592 if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) &&
4593 nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
4594 survey->channel_time_tx))
4595 goto nla_put_failure;
61fa713c
HS
4596
4597 nla_nest_end(msg, infoattr);
4598
4599 return genlmsg_end(msg, hdr);
4600
4601 nla_put_failure:
4602 genlmsg_cancel(msg, hdr);
4603 return -EMSGSIZE;
4604}
4605
4606static int nl80211_dump_survey(struct sk_buff *skb,
4607 struct netlink_callback *cb)
4608{
4609 struct survey_info survey;
4610 struct cfg80211_registered_device *dev;
4611 struct net_device *netdev;
61fa713c
HS
4612 int survey_idx = cb->args[1];
4613 int res;
4614
67748893
JB
4615 res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev);
4616 if (res)
4617 return res;
61fa713c
HS
4618
4619 if (!dev->ops->dump_survey) {
4620 res = -EOPNOTSUPP;
4621 goto out_err;
4622 }
4623
4624 while (1) {
180cdc79
LR
4625 struct ieee80211_channel *chan;
4626
61fa713c
HS
4627 res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx,
4628 &survey);
4629 if (res == -ENOENT)
4630 break;
4631 if (res)
4632 goto out_err;
4633
180cdc79
LR
4634 /* Survey without a channel doesn't make sense */
4635 if (!survey.channel) {
4636 res = -EINVAL;
4637 goto out;
4638 }
4639
4640 chan = ieee80211_get_channel(&dev->wiphy,
4641 survey.channel->center_freq);
4642 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) {
4643 survey_idx++;
4644 continue;
4645 }
4646
61fa713c
HS
4647 if (nl80211_send_survey(skb,
4648 NETLINK_CB(cb->skb).pid,
4649 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4650 netdev,
4651 &survey) < 0)
4652 goto out;
4653 survey_idx++;
4654 }
4655
4656 out:
4657 cb->args[1] = survey_idx;
4658 res = skb->len;
4659 out_err:
67748893 4660 nl80211_finish_netdev_dump(dev);
61fa713c
HS
4661 return res;
4662}
4663
255e737e
JM
4664static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type)
4665{
b23aa676
SO
4666 return auth_type <= NL80211_AUTHTYPE_MAX;
4667}
4668
4669static bool nl80211_valid_wpa_versions(u32 wpa_versions)
4670{
4671 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
4672 NL80211_WPA_VERSION_2));
4673}
4674
636a5d36
JM
4675static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
4676{
4c476991
JB
4677 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4678 struct net_device *dev = info->user_ptr[1];
19957bb3
JB
4679 struct ieee80211_channel *chan;
4680 const u8 *bssid, *ssid, *ie = NULL;
4681 int err, ssid_len, ie_len = 0;
4682 enum nl80211_auth_type auth_type;
fffd0934 4683 struct key_parse key;
d5cdfacb 4684 bool local_state_change;
636a5d36 4685
f4a11bb0
JB
4686 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4687 return -EINVAL;
4688
4689 if (!info->attrs[NL80211_ATTR_MAC])
4690 return -EINVAL;
4691
1778092e
JM
4692 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
4693 return -EINVAL;
4694
19957bb3
JB
4695 if (!info->attrs[NL80211_ATTR_SSID])
4696 return -EINVAL;
4697
4698 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
4699 return -EINVAL;
4700
fffd0934
JB
4701 err = nl80211_parse_key(info, &key);
4702 if (err)
4703 return err;
4704
4705 if (key.idx >= 0) {
e31b8213
JB
4706 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
4707 return -EINVAL;
fffd0934
JB
4708 if (!key.p.key || !key.p.key_len)
4709 return -EINVAL;
4710 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
4711 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
4712 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
4713 key.p.key_len != WLAN_KEY_LEN_WEP104))
4714 return -EINVAL;
4715 if (key.idx > 4)
4716 return -EINVAL;
4717 } else {
4718 key.p.key_len = 0;
4719 key.p.key = NULL;
4720 }
4721
afea0b7a
JB
4722 if (key.idx >= 0) {
4723 int i;
4724 bool ok = false;
4725 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
4726 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
4727 ok = true;
4728 break;
4729 }
4730 }
4c476991
JB
4731 if (!ok)
4732 return -EINVAL;
afea0b7a
JB
4733 }
4734
4c476991
JB
4735 if (!rdev->ops->auth)
4736 return -EOPNOTSUPP;
636a5d36 4737
074ac8df 4738 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
4739 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4740 return -EOPNOTSUPP;
eec60b03 4741
19957bb3 4742 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
79c97e97 4743 chan = ieee80211_get_channel(&rdev->wiphy,
19957bb3 4744 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
4c476991
JB
4745 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
4746 return -EINVAL;
636a5d36 4747
19957bb3
JB
4748 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4749 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
4750
4751 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
4752 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
4753 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
4754 }
4755
19957bb3 4756 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
4c476991
JB
4757 if (!nl80211_valid_auth_type(auth_type))
4758 return -EINVAL;
636a5d36 4759
d5cdfacb
JM
4760 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
4761
95de817b
JB
4762 /*
4763 * Since we no longer track auth state, ignore
4764 * requests to only change local state.
4765 */
4766 if (local_state_change)
4767 return 0;
4768
4c476991
JB
4769 return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
4770 ssid, ssid_len, ie, ie_len,
95de817b 4771 key.p.key, key.p.key_len, key.idx);
636a5d36
JM
4772}
4773
c0692b8f
JB
4774static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
4775 struct genl_info *info,
3dc27d25
JB
4776 struct cfg80211_crypto_settings *settings,
4777 int cipher_limit)
b23aa676 4778{
c0b2bbd8
JB
4779 memset(settings, 0, sizeof(*settings));
4780
b23aa676
SO
4781 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
4782
c0692b8f
JB
4783 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
4784 u16 proto;
4785 proto = nla_get_u16(
4786 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
4787 settings->control_port_ethertype = cpu_to_be16(proto);
4788 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
4789 proto != ETH_P_PAE)
4790 return -EINVAL;
4791 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
4792 settings->control_port_no_encrypt = true;
4793 } else
4794 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
4795
b23aa676
SO
4796 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
4797 void *data;
4798 int len, i;
4799
4800 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
4801 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
4802 settings->n_ciphers_pairwise = len / sizeof(u32);
4803
4804 if (len % sizeof(u32))
4805 return -EINVAL;
4806
3dc27d25 4807 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
4808 return -EINVAL;
4809
4810 memcpy(settings->ciphers_pairwise, data, len);
4811
4812 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
4813 if (!cfg80211_supported_cipher_suite(
4814 &rdev->wiphy,
b23aa676
SO
4815 settings->ciphers_pairwise[i]))
4816 return -EINVAL;
4817 }
4818
4819 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
4820 settings->cipher_group =
4821 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
4822 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
4823 settings->cipher_group))
b23aa676
SO
4824 return -EINVAL;
4825 }
4826
4827 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
4828 settings->wpa_versions =
4829 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
4830 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
4831 return -EINVAL;
4832 }
4833
4834 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
4835 void *data;
6d30240e 4836 int len;
b23aa676
SO
4837
4838 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
4839 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
4840 settings->n_akm_suites = len / sizeof(u32);
4841
4842 if (len % sizeof(u32))
4843 return -EINVAL;
4844
1b9ca027
JM
4845 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
4846 return -EINVAL;
4847
b23aa676 4848 memcpy(settings->akm_suites, data, len);
b23aa676
SO
4849 }
4850
4851 return 0;
4852}
4853
636a5d36
JM
4854static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
4855{
4c476991
JB
4856 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4857 struct net_device *dev = info->user_ptr[1];
19957bb3 4858 struct cfg80211_crypto_settings crypto;
f444de05 4859 struct ieee80211_channel *chan;
3e5d7649 4860 const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL;
19957bb3
JB
4861 int err, ssid_len, ie_len = 0;
4862 bool use_mfp = false;
7e7c8926
BG
4863 u32 flags = 0;
4864 struct ieee80211_ht_cap *ht_capa = NULL;
4865 struct ieee80211_ht_cap *ht_capa_mask = NULL;
636a5d36 4866
f4a11bb0
JB
4867 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4868 return -EINVAL;
4869
4870 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
4871 !info->attrs[NL80211_ATTR_SSID] ||
4872 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
4873 return -EINVAL;
4874
4c476991
JB
4875 if (!rdev->ops->assoc)
4876 return -EOPNOTSUPP;
636a5d36 4877
074ac8df 4878 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
4879 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4880 return -EOPNOTSUPP;
eec60b03 4881
19957bb3 4882 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 4883
19957bb3
JB
4884 chan = ieee80211_get_channel(&rdev->wiphy,
4885 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
4c476991
JB
4886 if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED))
4887 return -EINVAL;
636a5d36 4888
19957bb3
JB
4889 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4890 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
4891
4892 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
4893 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
4894 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
4895 }
4896
dc6382ce 4897 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 4898 enum nl80211_mfp mfp =
dc6382ce 4899 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 4900 if (mfp == NL80211_MFP_REQUIRED)
19957bb3 4901 use_mfp = true;
4c476991
JB
4902 else if (mfp != NL80211_MFP_NO)
4903 return -EINVAL;
dc6382ce
JM
4904 }
4905
3e5d7649
JB
4906 if (info->attrs[NL80211_ATTR_PREV_BSSID])
4907 prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
4908
7e7c8926
BG
4909 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
4910 flags |= ASSOC_REQ_DISABLE_HT;
4911
4912 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
4913 ht_capa_mask =
4914 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]);
4915
4916 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
4917 if (!ht_capa_mask)
4918 return -EINVAL;
4919 ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
4920 }
4921
c0692b8f 4922 err = nl80211_crypto_settings(rdev, info, &crypto, 1);
b23aa676 4923 if (!err)
3e5d7649
JB
4924 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid,
4925 ssid, ssid_len, ie, ie_len, use_mfp,
7e7c8926
BG
4926 &crypto, flags, ht_capa,
4927 ht_capa_mask);
636a5d36 4928
636a5d36
JM
4929 return err;
4930}
4931
4932static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
4933{
4c476991
JB
4934 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4935 struct net_device *dev = info->user_ptr[1];
19957bb3 4936 const u8 *ie = NULL, *bssid;
4c476991 4937 int ie_len = 0;
19957bb3 4938 u16 reason_code;
d5cdfacb 4939 bool local_state_change;
636a5d36 4940
f4a11bb0
JB
4941 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4942 return -EINVAL;
4943
4944 if (!info->attrs[NL80211_ATTR_MAC])
4945 return -EINVAL;
4946
4947 if (!info->attrs[NL80211_ATTR_REASON_CODE])
4948 return -EINVAL;
4949
4c476991
JB
4950 if (!rdev->ops->deauth)
4951 return -EOPNOTSUPP;
636a5d36 4952
074ac8df 4953 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
4954 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4955 return -EOPNOTSUPP;
eec60b03 4956
19957bb3 4957 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 4958
19957bb3
JB
4959 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
4960 if (reason_code == 0) {
f4a11bb0 4961 /* Reason Code 0 is reserved */
4c476991 4962 return -EINVAL;
255e737e 4963 }
636a5d36
JM
4964
4965 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
4966 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
4967 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
4968 }
4969
d5cdfacb
JM
4970 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
4971
4c476991
JB
4972 return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
4973 local_state_change);
636a5d36
JM
4974}
4975
4976static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
4977{
4c476991
JB
4978 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4979 struct net_device *dev = info->user_ptr[1];
19957bb3 4980 const u8 *ie = NULL, *bssid;
4c476991 4981 int ie_len = 0;
19957bb3 4982 u16 reason_code;
d5cdfacb 4983 bool local_state_change;
636a5d36 4984
f4a11bb0
JB
4985 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
4986 return -EINVAL;
4987
4988 if (!info->attrs[NL80211_ATTR_MAC])
4989 return -EINVAL;
4990
4991 if (!info->attrs[NL80211_ATTR_REASON_CODE])
4992 return -EINVAL;
4993
4c476991
JB
4994 if (!rdev->ops->disassoc)
4995 return -EOPNOTSUPP;
636a5d36 4996
074ac8df 4997 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
4998 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
4999 return -EOPNOTSUPP;
eec60b03 5000
19957bb3 5001 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 5002
19957bb3
JB
5003 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5004 if (reason_code == 0) {
f4a11bb0 5005 /* Reason Code 0 is reserved */
4c476991 5006 return -EINVAL;
255e737e 5007 }
636a5d36
JM
5008
5009 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
5010 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
5011 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
5012 }
5013
d5cdfacb
JM
5014 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
5015
4c476991
JB
5016 return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
5017 local_state_change);
636a5d36
JM
5018}
5019
dd5b4cc7
FF
5020static bool
5021nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
5022 int mcast_rate[IEEE80211_NUM_BANDS],
5023 int rateval)
5024{
5025 struct wiphy *wiphy = &rdev->wiphy;
5026 bool found = false;
5027 int band, i;
5028
5029 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
5030 struct ieee80211_supported_band *sband;
5031
5032 sband = wiphy->bands[band];
5033 if (!sband)
5034 continue;
5035
5036 for (i = 0; i < sband->n_bitrates; i++) {
5037 if (sband->bitrates[i].bitrate == rateval) {
5038 mcast_rate[band] = i + 1;
5039 found = true;
5040 break;
5041 }
5042 }
5043 }
5044
5045 return found;
5046}
5047
04a773ad
JB
5048static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5049{
4c476991
JB
5050 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5051 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
5052 struct cfg80211_ibss_params ibss;
5053 struct wiphy *wiphy;
fffd0934 5054 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
5055 int err;
5056
8e30bc55
JB
5057 memset(&ibss, 0, sizeof(ibss));
5058
04a773ad
JB
5059 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5060 return -EINVAL;
5061
5062 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
5063 !info->attrs[NL80211_ATTR_SSID] ||
5064 !nla_len(info->attrs[NL80211_ATTR_SSID]))
5065 return -EINVAL;
5066
8e30bc55
JB
5067 ibss.beacon_interval = 100;
5068
5069 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
5070 ibss.beacon_interval =
5071 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
5072 if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
5073 return -EINVAL;
5074 }
5075
4c476991
JB
5076 if (!rdev->ops->join_ibss)
5077 return -EOPNOTSUPP;
04a773ad 5078
4c476991
JB
5079 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
5080 return -EOPNOTSUPP;
04a773ad 5081
79c97e97 5082 wiphy = &rdev->wiphy;
04a773ad 5083
39193498 5084 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 5085 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
5086
5087 if (!is_valid_ether_addr(ibss.bssid))
5088 return -EINVAL;
5089 }
04a773ad
JB
5090 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
5091 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
5092
5093 if (info->attrs[NL80211_ATTR_IE]) {
5094 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
5095 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5096 }
5097
54858ee5
AS
5098 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
5099 enum nl80211_channel_type channel_type;
5100
cd6c6598 5101 if (!nl80211_valid_channel_type(info, &channel_type))
54858ee5
AS
5102 return -EINVAL;
5103
5104 if (channel_type != NL80211_CHAN_NO_HT &&
5105 !(wiphy->features & NL80211_FEATURE_HT_IBSS))
5106 return -EINVAL;
5107
5108 ibss.channel_type = channel_type;
5109 } else {
5110 ibss.channel_type = NL80211_CHAN_NO_HT;
5111 }
5112
5113 ibss.channel = rdev_freq_to_chan(rdev,
5114 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
5115 ibss.channel_type);
04a773ad
JB
5116 if (!ibss.channel ||
5117 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
4c476991
JB
5118 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
5119 return -EINVAL;
04a773ad 5120
54858ee5
AS
5121 /* Both channels should be able to initiate communication */
5122 if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
5123 ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
5124 !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
5125 ibss.channel_type))
5126 return -EINVAL;
5127
04a773ad 5128 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
5129 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
5130
fbd2c8dc
TP
5131 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
5132 u8 *rates =
5133 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5134 int n_rates =
5135 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5136 struct ieee80211_supported_band *sband =
5137 wiphy->bands[ibss.channel->band];
fbd2c8dc 5138
34850ab2
JB
5139 err = ieee80211_get_ratemask(sband, rates, n_rates,
5140 &ibss.basic_rates);
5141 if (err)
5142 return err;
fbd2c8dc 5143 }
dd5b4cc7
FF
5144
5145 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
5146 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
5147 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
5148 return -EINVAL;
fbd2c8dc 5149
4c476991
JB
5150 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
5151 connkeys = nl80211_parse_connkeys(rdev,
5152 info->attrs[NL80211_ATTR_KEYS]);
5153 if (IS_ERR(connkeys))
5154 return PTR_ERR(connkeys);
5155 }
04a773ad 5156
267335d6
AQ
5157 ibss.control_port =
5158 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
5159
4c476991 5160 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934
JB
5161 if (err)
5162 kfree(connkeys);
04a773ad
JB
5163 return err;
5164}
5165
5166static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
5167{
4c476991
JB
5168 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5169 struct net_device *dev = info->user_ptr[1];
04a773ad 5170
4c476991
JB
5171 if (!rdev->ops->leave_ibss)
5172 return -EOPNOTSUPP;
04a773ad 5173
4c476991
JB
5174 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
5175 return -EOPNOTSUPP;
04a773ad 5176
4c476991 5177 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
5178}
5179
aff89a9b
JB
5180#ifdef CONFIG_NL80211_TESTMODE
5181static struct genl_multicast_group nl80211_testmode_mcgrp = {
5182 .name = "testmode",
5183};
5184
5185static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
5186{
4c476991 5187 struct cfg80211_registered_device *rdev = info->user_ptr[0];
aff89a9b
JB
5188 int err;
5189
5190 if (!info->attrs[NL80211_ATTR_TESTDATA])
5191 return -EINVAL;
5192
aff89a9b
JB
5193 err = -EOPNOTSUPP;
5194 if (rdev->ops->testmode_cmd) {
5195 rdev->testmode_info = info;
5196 err = rdev->ops->testmode_cmd(&rdev->wiphy,
5197 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
5198 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
5199 rdev->testmode_info = NULL;
5200 }
5201
aff89a9b
JB
5202 return err;
5203}
5204
71063f0e
WYG
5205static int nl80211_testmode_dump(struct sk_buff *skb,
5206 struct netlink_callback *cb)
5207{
00918d33 5208 struct cfg80211_registered_device *rdev;
71063f0e
WYG
5209 int err;
5210 long phy_idx;
5211 void *data = NULL;
5212 int data_len = 0;
5213
5214 if (cb->args[0]) {
5215 /*
5216 * 0 is a valid index, but not valid for args[0],
5217 * so we need to offset by 1.
5218 */
5219 phy_idx = cb->args[0] - 1;
5220 } else {
5221 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
5222 nl80211_fam.attrbuf, nl80211_fam.maxattr,
5223 nl80211_policy);
5224 if (err)
5225 return err;
00918d33
JB
5226 if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) {
5227 phy_idx = nla_get_u32(
5228 nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]);
5229 } else {
5230 struct net_device *netdev;
5231
5232 err = get_rdev_dev_by_ifindex(sock_net(skb->sk),
5233 nl80211_fam.attrbuf,
5234 &rdev, &netdev);
5235 if (err)
5236 return err;
5237 dev_put(netdev);
5238 phy_idx = rdev->wiphy_idx;
5239 cfg80211_unlock_rdev(rdev);
5240 }
71063f0e
WYG
5241 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
5242 cb->args[1] =
5243 (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA];
5244 }
5245
5246 if (cb->args[1]) {
5247 data = nla_data((void *)cb->args[1]);
5248 data_len = nla_len((void *)cb->args[1]);
5249 }
5250
5251 mutex_lock(&cfg80211_mutex);
00918d33
JB
5252 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
5253 if (!rdev) {
71063f0e
WYG
5254 mutex_unlock(&cfg80211_mutex);
5255 return -ENOENT;
5256 }
00918d33 5257 cfg80211_lock_rdev(rdev);
71063f0e
WYG
5258 mutex_unlock(&cfg80211_mutex);
5259
00918d33 5260 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
5261 err = -EOPNOTSUPP;
5262 goto out_err;
5263 }
5264
5265 while (1) {
5266 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid,
5267 cb->nlh->nlmsg_seq, NLM_F_MULTI,
5268 NL80211_CMD_TESTMODE);
5269 struct nlattr *tmdata;
5270
9360ffd1 5271 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
5272 genlmsg_cancel(skb, hdr);
5273 break;
5274 }
5275
5276 tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
5277 if (!tmdata) {
5278 genlmsg_cancel(skb, hdr);
5279 break;
5280 }
00918d33
JB
5281 err = rdev->ops->testmode_dump(&rdev->wiphy, skb, cb,
5282 data, data_len);
71063f0e
WYG
5283 nla_nest_end(skb, tmdata);
5284
5285 if (err == -ENOBUFS || err == -ENOENT) {
5286 genlmsg_cancel(skb, hdr);
5287 break;
5288 } else if (err) {
5289 genlmsg_cancel(skb, hdr);
5290 goto out_err;
5291 }
5292
5293 genlmsg_end(skb, hdr);
5294 }
5295
5296 err = skb->len;
5297 /* see above */
5298 cb->args[0] = phy_idx + 1;
5299 out_err:
00918d33 5300 cfg80211_unlock_rdev(rdev);
71063f0e
WYG
5301 return err;
5302}
5303
aff89a9b
JB
5304static struct sk_buff *
5305__cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev,
5306 int approxlen, u32 pid, u32 seq, gfp_t gfp)
5307{
5308 struct sk_buff *skb;
5309 void *hdr;
5310 struct nlattr *data;
5311
5312 skb = nlmsg_new(approxlen + 100, gfp);
5313 if (!skb)
5314 return NULL;
5315
5316 hdr = nl80211hdr_put(skb, pid, seq, 0, NL80211_CMD_TESTMODE);
5317 if (!hdr) {
5318 kfree_skb(skb);
5319 return NULL;
5320 }
5321
9360ffd1
DM
5322 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
5323 goto nla_put_failure;
aff89a9b
JB
5324 data = nla_nest_start(skb, NL80211_ATTR_TESTDATA);
5325
5326 ((void **)skb->cb)[0] = rdev;
5327 ((void **)skb->cb)[1] = hdr;
5328 ((void **)skb->cb)[2] = data;
5329
5330 return skb;
5331
5332 nla_put_failure:
5333 kfree_skb(skb);
5334 return NULL;
5335}
5336
5337struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy,
5338 int approxlen)
5339{
5340 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
5341
5342 if (WARN_ON(!rdev->testmode_info))
5343 return NULL;
5344
5345 return __cfg80211_testmode_alloc_skb(rdev, approxlen,
5346 rdev->testmode_info->snd_pid,
5347 rdev->testmode_info->snd_seq,
5348 GFP_KERNEL);
5349}
5350EXPORT_SYMBOL(cfg80211_testmode_alloc_reply_skb);
5351
5352int cfg80211_testmode_reply(struct sk_buff *skb)
5353{
5354 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
5355 void *hdr = ((void **)skb->cb)[1];
5356 struct nlattr *data = ((void **)skb->cb)[2];
5357
5358 if (WARN_ON(!rdev->testmode_info)) {
5359 kfree_skb(skb);
5360 return -EINVAL;
5361 }
5362
5363 nla_nest_end(skb, data);
5364 genlmsg_end(skb, hdr);
5365 return genlmsg_reply(skb, rdev->testmode_info);
5366}
5367EXPORT_SYMBOL(cfg80211_testmode_reply);
5368
5369struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy,
5370 int approxlen, gfp_t gfp)
5371{
5372 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
5373
5374 return __cfg80211_testmode_alloc_skb(rdev, approxlen, 0, 0, gfp);
5375}
5376EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb);
5377
5378void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
5379{
5380 void *hdr = ((void **)skb->cb)[1];
5381 struct nlattr *data = ((void **)skb->cb)[2];
5382
5383 nla_nest_end(skb, data);
5384 genlmsg_end(skb, hdr);
5385 genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp);
5386}
5387EXPORT_SYMBOL(cfg80211_testmode_event);
5388#endif
5389
b23aa676
SO
5390static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
5391{
4c476991
JB
5392 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5393 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
5394 struct cfg80211_connect_params connect;
5395 struct wiphy *wiphy;
fffd0934 5396 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
5397 int err;
5398
5399 memset(&connect, 0, sizeof(connect));
5400
5401 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5402 return -EINVAL;
5403
5404 if (!info->attrs[NL80211_ATTR_SSID] ||
5405 !nla_len(info->attrs[NL80211_ATTR_SSID]))
5406 return -EINVAL;
5407
5408 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
5409 connect.auth_type =
5410 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
5411 if (!nl80211_valid_auth_type(connect.auth_type))
5412 return -EINVAL;
5413 } else
5414 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
5415
5416 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
5417
c0692b8f 5418 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 5419 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
5420 if (err)
5421 return err;
b23aa676 5422
074ac8df 5423 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
5424 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
5425 return -EOPNOTSUPP;
b23aa676 5426
79c97e97 5427 wiphy = &rdev->wiphy;
b23aa676 5428
4486ea98
BS
5429 connect.bg_scan_period = -1;
5430 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
5431 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
5432 connect.bg_scan_period =
5433 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
5434 }
5435
b23aa676
SO
5436 if (info->attrs[NL80211_ATTR_MAC])
5437 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
5438 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
5439 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
5440
5441 if (info->attrs[NL80211_ATTR_IE]) {
5442 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
5443 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5444 }
5445
5446 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
5447 connect.channel =
5448 ieee80211_get_channel(wiphy,
5449 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
5450 if (!connect.channel ||
4c476991
JB
5451 connect.channel->flags & IEEE80211_CHAN_DISABLED)
5452 return -EINVAL;
b23aa676
SO
5453 }
5454
fffd0934
JB
5455 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
5456 connkeys = nl80211_parse_connkeys(rdev,
5457 info->attrs[NL80211_ATTR_KEYS]);
4c476991
JB
5458 if (IS_ERR(connkeys))
5459 return PTR_ERR(connkeys);
fffd0934
JB
5460 }
5461
7e7c8926
BG
5462 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
5463 connect.flags |= ASSOC_REQ_DISABLE_HT;
5464
5465 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
5466 memcpy(&connect.ht_capa_mask,
5467 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
5468 sizeof(connect.ht_capa_mask));
5469
5470 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
5471 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
5472 return -EINVAL;
5473 memcpy(&connect.ht_capa,
5474 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
5475 sizeof(connect.ht_capa));
5476 }
5477
fffd0934 5478 err = cfg80211_connect(rdev, dev, &connect, connkeys);
fffd0934
JB
5479 if (err)
5480 kfree(connkeys);
b23aa676
SO
5481 return err;
5482}
5483
5484static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
5485{
4c476991
JB
5486 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5487 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
5488 u16 reason;
5489
5490 if (!info->attrs[NL80211_ATTR_REASON_CODE])
5491 reason = WLAN_REASON_DEAUTH_LEAVING;
5492 else
5493 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5494
5495 if (reason == 0)
5496 return -EINVAL;
5497
074ac8df 5498 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
5499 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
5500 return -EOPNOTSUPP;
b23aa676 5501
4c476991 5502 return cfg80211_disconnect(rdev, dev, reason, true);
b23aa676
SO
5503}
5504
463d0183
JB
5505static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
5506{
4c476991 5507 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
5508 struct net *net;
5509 int err;
5510 u32 pid;
5511
5512 if (!info->attrs[NL80211_ATTR_PID])
5513 return -EINVAL;
5514
5515 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
5516
463d0183 5517 net = get_net_ns_by_pid(pid);
4c476991
JB
5518 if (IS_ERR(net))
5519 return PTR_ERR(net);
463d0183
JB
5520
5521 err = 0;
5522
5523 /* check if anything to do */
4c476991
JB
5524 if (!net_eq(wiphy_net(&rdev->wiphy), net))
5525 err = cfg80211_switch_netns(rdev, net);
463d0183 5526
463d0183 5527 put_net(net);
463d0183
JB
5528 return err;
5529}
5530
67fbb16b
SO
5531static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
5532{
4c476991 5533 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
5534 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
5535 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 5536 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
5537 struct cfg80211_pmksa pmksa;
5538
5539 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
5540
5541 if (!info->attrs[NL80211_ATTR_MAC])
5542 return -EINVAL;
5543
5544 if (!info->attrs[NL80211_ATTR_PMKID])
5545 return -EINVAL;
5546
67fbb16b
SO
5547 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
5548 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
5549
074ac8df 5550 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
5551 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
5552 return -EOPNOTSUPP;
67fbb16b
SO
5553
5554 switch (info->genlhdr->cmd) {
5555 case NL80211_CMD_SET_PMKSA:
5556 rdev_ops = rdev->ops->set_pmksa;
5557 break;
5558 case NL80211_CMD_DEL_PMKSA:
5559 rdev_ops = rdev->ops->del_pmksa;
5560 break;
5561 default:
5562 WARN_ON(1);
5563 break;
5564 }
5565
4c476991
JB
5566 if (!rdev_ops)
5567 return -EOPNOTSUPP;
67fbb16b 5568
4c476991 5569 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
5570}
5571
5572static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
5573{
4c476991
JB
5574 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5575 struct net_device *dev = info->user_ptr[1];
67fbb16b 5576
074ac8df 5577 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
5578 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
5579 return -EOPNOTSUPP;
67fbb16b 5580
4c476991
JB
5581 if (!rdev->ops->flush_pmksa)
5582 return -EOPNOTSUPP;
67fbb16b 5583
4c476991 5584 return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
67fbb16b
SO
5585}
5586
109086ce
AN
5587static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
5588{
5589 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5590 struct net_device *dev = info->user_ptr[1];
5591 u8 action_code, dialog_token;
5592 u16 status_code;
5593 u8 *peer;
5594
5595 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
5596 !rdev->ops->tdls_mgmt)
5597 return -EOPNOTSUPP;
5598
5599 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
5600 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
5601 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
5602 !info->attrs[NL80211_ATTR_IE] ||
5603 !info->attrs[NL80211_ATTR_MAC])
5604 return -EINVAL;
5605
5606 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
5607 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
5608 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
5609 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
5610
5611 return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
5612 dialog_token, status_code,
5613 nla_data(info->attrs[NL80211_ATTR_IE]),
5614 nla_len(info->attrs[NL80211_ATTR_IE]));
5615}
5616
5617static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
5618{
5619 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5620 struct net_device *dev = info->user_ptr[1];
5621 enum nl80211_tdls_operation operation;
5622 u8 *peer;
5623
5624 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
5625 !rdev->ops->tdls_oper)
5626 return -EOPNOTSUPP;
5627
5628 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
5629 !info->attrs[NL80211_ATTR_MAC])
5630 return -EINVAL;
5631
5632 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
5633 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
5634
5635 return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation);
5636}
5637
9588bbd5
JM
5638static int nl80211_remain_on_channel(struct sk_buff *skb,
5639 struct genl_info *info)
5640{
4c476991
JB
5641 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5642 struct net_device *dev = info->user_ptr[1];
9588bbd5
JM
5643 struct ieee80211_channel *chan;
5644 struct sk_buff *msg;
5645 void *hdr;
5646 u64 cookie;
5647 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
5648 u32 freq, duration;
5649 int err;
5650
5651 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
5652 !info->attrs[NL80211_ATTR_DURATION])
5653 return -EINVAL;
5654
5655 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
5656
ebf348fc
JB
5657 if (!rdev->ops->remain_on_channel ||
5658 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
5659 return -EOPNOTSUPP;
5660
9588bbd5 5661 /*
ebf348fc
JB
5662 * We should be on that channel for at least a minimum amount of
5663 * time (10ms) but no longer than the driver supports.
9588bbd5 5664 */
ebf348fc 5665 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 5666 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
5667 return -EINVAL;
5668
cd6c6598
JB
5669 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
5670 !nl80211_valid_channel_type(info, &channel_type))
5671 return -EINVAL;
9588bbd5
JM
5672
5673 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5674 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4c476991
JB
5675 if (chan == NULL)
5676 return -EINVAL;
9588bbd5
JM
5677
5678 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
5679 if (!msg)
5680 return -ENOMEM;
9588bbd5
JM
5681
5682 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
5683 NL80211_CMD_REMAIN_ON_CHANNEL);
5684
5685 if (IS_ERR(hdr)) {
5686 err = PTR_ERR(hdr);
5687 goto free_msg;
5688 }
5689
5690 err = rdev->ops->remain_on_channel(&rdev->wiphy, dev, chan,
5691 channel_type, duration, &cookie);
5692
5693 if (err)
5694 goto free_msg;
5695
9360ffd1
DM
5696 if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
5697 goto nla_put_failure;
9588bbd5
JM
5698
5699 genlmsg_end(msg, hdr);
4c476991
JB
5700
5701 return genlmsg_reply(msg, info);
9588bbd5
JM
5702
5703 nla_put_failure:
5704 err = -ENOBUFS;
5705 free_msg:
5706 nlmsg_free(msg);
9588bbd5
JM
5707 return err;
5708}
5709
5710static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
5711 struct genl_info *info)
5712{
4c476991
JB
5713 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5714 struct net_device *dev = info->user_ptr[1];
9588bbd5 5715 u64 cookie;
9588bbd5
JM
5716
5717 if (!info->attrs[NL80211_ATTR_COOKIE])
5718 return -EINVAL;
5719
4c476991
JB
5720 if (!rdev->ops->cancel_remain_on_channel)
5721 return -EOPNOTSUPP;
9588bbd5 5722
9588bbd5
JM
5723 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
5724
4c476991 5725 return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie);
9588bbd5
JM
5726}
5727
13ae75b1
JM
5728static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
5729 u8 *rates, u8 rates_len)
5730{
5731 u8 i;
5732 u32 mask = 0;
5733
5734 for (i = 0; i < rates_len; i++) {
5735 int rate = (rates[i] & 0x7f) * 5;
5736 int ridx;
5737 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
5738 struct ieee80211_rate *srate =
5739 &sband->bitrates[ridx];
5740 if (rate == srate->bitrate) {
5741 mask |= 1 << ridx;
5742 break;
5743 }
5744 }
5745 if (ridx == sband->n_bitrates)
5746 return 0; /* rate not found */
5747 }
5748
5749 return mask;
5750}
5751
24db78c0
SW
5752static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
5753 u8 *rates, u8 rates_len,
5754 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
5755{
5756 u8 i;
5757
5758 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
5759
5760 for (i = 0; i < rates_len; i++) {
5761 int ridx, rbit;
5762
5763 ridx = rates[i] / 8;
5764 rbit = BIT(rates[i] % 8);
5765
5766 /* check validity */
910570b5 5767 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
24db78c0
SW
5768 return false;
5769
5770 /* check availability */
5771 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
5772 mcs[ridx] |= rbit;
5773 else
5774 return false;
5775 }
5776
5777 return true;
5778}
5779
b54452b0 5780static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
13ae75b1
JM
5781 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
5782 .len = NL80211_MAX_SUPP_RATES },
24db78c0
SW
5783 [NL80211_TXRATE_MCS] = { .type = NLA_BINARY,
5784 .len = NL80211_MAX_SUPP_HT_RATES },
13ae75b1
JM
5785};
5786
5787static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
5788 struct genl_info *info)
5789{
5790 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4c476991 5791 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13ae75b1 5792 struct cfg80211_bitrate_mask mask;
4c476991
JB
5793 int rem, i;
5794 struct net_device *dev = info->user_ptr[1];
13ae75b1
JM
5795 struct nlattr *tx_rates;
5796 struct ieee80211_supported_band *sband;
5797
5798 if (info->attrs[NL80211_ATTR_TX_RATES] == NULL)
5799 return -EINVAL;
5800
4c476991
JB
5801 if (!rdev->ops->set_bitrate_mask)
5802 return -EOPNOTSUPP;
13ae75b1
JM
5803
5804 memset(&mask, 0, sizeof(mask));
5805 /* Default to all rates enabled */
5806 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
5807 sband = rdev->wiphy.bands[i];
5808 mask.control[i].legacy =
5809 sband ? (1 << sband->n_bitrates) - 1 : 0;
24db78c0
SW
5810 if (sband)
5811 memcpy(mask.control[i].mcs,
5812 sband->ht_cap.mcs.rx_mask,
5813 sizeof(mask.control[i].mcs));
5814 else
5815 memset(mask.control[i].mcs, 0,
5816 sizeof(mask.control[i].mcs));
13ae75b1
JM
5817 }
5818
5819 /*
5820 * The nested attribute uses enum nl80211_band as the index. This maps
5821 * directly to the enum ieee80211_band values used in cfg80211.
5822 */
24db78c0 5823 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
13ae75b1
JM
5824 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
5825 {
5826 enum ieee80211_band band = nla_type(tx_rates);
4c476991
JB
5827 if (band < 0 || band >= IEEE80211_NUM_BANDS)
5828 return -EINVAL;
13ae75b1 5829 sband = rdev->wiphy.bands[band];
4c476991
JB
5830 if (sband == NULL)
5831 return -EINVAL;
13ae75b1
JM
5832 nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
5833 nla_len(tx_rates), nl80211_txattr_policy);
5834 if (tb[NL80211_TXRATE_LEGACY]) {
5835 mask.control[band].legacy = rateset_to_mask(
5836 sband,
5837 nla_data(tb[NL80211_TXRATE_LEGACY]),
5838 nla_len(tb[NL80211_TXRATE_LEGACY]));
218d2e26
BS
5839 if ((mask.control[band].legacy == 0) &&
5840 nla_len(tb[NL80211_TXRATE_LEGACY]))
5841 return -EINVAL;
24db78c0
SW
5842 }
5843 if (tb[NL80211_TXRATE_MCS]) {
5844 if (!ht_rateset_to_mask(
5845 sband,
5846 nla_data(tb[NL80211_TXRATE_MCS]),
5847 nla_len(tb[NL80211_TXRATE_MCS]),
5848 mask.control[band].mcs))
5849 return -EINVAL;
5850 }
5851
5852 if (mask.control[band].legacy == 0) {
5853 /* don't allow empty legacy rates if HT
5854 * is not even supported. */
5855 if (!rdev->wiphy.bands[band]->ht_cap.ht_supported)
5856 return -EINVAL;
5857
5858 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
5859 if (mask.control[band].mcs[i])
5860 break;
5861
5862 /* legacy and mcs rates may not be both empty */
5863 if (i == IEEE80211_HT_MCS_MASK_LEN)
4c476991 5864 return -EINVAL;
13ae75b1
JM
5865 }
5866 }
5867
4c476991 5868 return rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask);
13ae75b1
JM
5869}
5870
2e161f78 5871static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 5872{
4c476991
JB
5873 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5874 struct net_device *dev = info->user_ptr[1];
2e161f78 5875 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
5876
5877 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
5878 return -EINVAL;
5879
2e161f78
JB
5880 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
5881 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 5882
9d38d85d 5883 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
074ac8df 5884 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
663fcafd
JB
5885 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
5886 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5887 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
c7108a71 5888 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5889 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5890 return -EOPNOTSUPP;
026331c4
JM
5891
5892 /* not much point in registering if we can't reply */
4c476991
JB
5893 if (!rdev->ops->mgmt_tx)
5894 return -EOPNOTSUPP;
026331c4 5895
4c476991 5896 return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid,
2e161f78 5897 frame_type,
026331c4
JM
5898 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
5899 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
5900}
5901
2e161f78 5902static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 5903{
4c476991
JB
5904 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5905 struct net_device *dev = info->user_ptr[1];
026331c4
JM
5906 struct ieee80211_channel *chan;
5907 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
252aa631 5908 bool channel_type_valid = false;
026331c4
JM
5909 u32 freq;
5910 int err;
d64d373f 5911 void *hdr = NULL;
026331c4 5912 u64 cookie;
e247bd90 5913 struct sk_buff *msg = NULL;
f7ca38df 5914 unsigned int wait = 0;
e247bd90
JB
5915 bool offchan, no_cck, dont_wait_for_ack;
5916
5917 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
026331c4
JM
5918
5919 if (!info->attrs[NL80211_ATTR_FRAME] ||
5920 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
5921 return -EINVAL;
5922
4c476991
JB
5923 if (!rdev->ops->mgmt_tx)
5924 return -EOPNOTSUPP;
026331c4 5925
9d38d85d 5926 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
074ac8df 5927 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
663fcafd
JB
5928 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
5929 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5930 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
c7108a71 5931 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5932 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5933 return -EOPNOTSUPP;
026331c4 5934
f7ca38df 5935 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 5936 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df
JB
5937 return -EINVAL;
5938 wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
5939
5940 /*
5941 * We should wait on the channel for at least a minimum amount
5942 * of time (10ms) but no longer than the driver supports.
5943 */
5944 if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
5945 wait > rdev->wiphy.max_remain_on_channel_duration)
5946 return -EINVAL;
5947
f7ca38df
JB
5948 }
5949
026331c4 5950 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
cd6c6598 5951 if (!nl80211_valid_channel_type(info, &channel_type))
4c476991 5952 return -EINVAL;
252aa631 5953 channel_type_valid = true;
026331c4
JM
5954 }
5955
f7ca38df
JB
5956 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
5957
7c4ef712
JB
5958 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
5959 return -EINVAL;
5960
e9f935e3
RM
5961 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
5962
026331c4
JM
5963 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5964 chan = rdev_freq_to_chan(rdev, freq, channel_type);
4c476991
JB
5965 if (chan == NULL)
5966 return -EINVAL;
026331c4 5967
e247bd90
JB
5968 if (!dont_wait_for_ack) {
5969 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5970 if (!msg)
5971 return -ENOMEM;
026331c4 5972
e247bd90
JB
5973 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
5974 NL80211_CMD_FRAME);
026331c4 5975
e247bd90
JB
5976 if (IS_ERR(hdr)) {
5977 err = PTR_ERR(hdr);
5978 goto free_msg;
5979 }
026331c4 5980 }
e247bd90 5981
f7ca38df
JB
5982 err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type,
5983 channel_type_valid, wait,
2e161f78
JB
5984 nla_data(info->attrs[NL80211_ATTR_FRAME]),
5985 nla_len(info->attrs[NL80211_ATTR_FRAME]),
e247bd90 5986 no_cck, dont_wait_for_ack, &cookie);
026331c4
JM
5987 if (err)
5988 goto free_msg;
5989
e247bd90 5990 if (msg) {
9360ffd1
DM
5991 if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
5992 goto nla_put_failure;
026331c4 5993
e247bd90
JB
5994 genlmsg_end(msg, hdr);
5995 return genlmsg_reply(msg, info);
5996 }
5997
5998 return 0;
026331c4
JM
5999
6000 nla_put_failure:
6001 err = -ENOBUFS;
6002 free_msg:
6003 nlmsg_free(msg);
026331c4
JM
6004 return err;
6005}
6006
f7ca38df
JB
6007static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
6008{
6009 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6010 struct net_device *dev = info->user_ptr[1];
6011 u64 cookie;
6012
6013 if (!info->attrs[NL80211_ATTR_COOKIE])
6014 return -EINVAL;
6015
6016 if (!rdev->ops->mgmt_tx_cancel_wait)
6017 return -EOPNOTSUPP;
6018
6019 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
6020 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
6021 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
6022 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
6023 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
6024 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6025 return -EOPNOTSUPP;
6026
6027 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
6028
6029 return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, dev, cookie);
6030}
6031
ffb9eb3d
KV
6032static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
6033{
4c476991 6034 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 6035 struct wireless_dev *wdev;
4c476991 6036 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
6037 u8 ps_state;
6038 bool state;
6039 int err;
6040
4c476991
JB
6041 if (!info->attrs[NL80211_ATTR_PS_STATE])
6042 return -EINVAL;
ffb9eb3d
KV
6043
6044 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
6045
4c476991
JB
6046 if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED)
6047 return -EINVAL;
ffb9eb3d
KV
6048
6049 wdev = dev->ieee80211_ptr;
6050
4c476991
JB
6051 if (!rdev->ops->set_power_mgmt)
6052 return -EOPNOTSUPP;
ffb9eb3d
KV
6053
6054 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
6055
6056 if (state == wdev->ps)
4c476991 6057 return 0;
ffb9eb3d 6058
4c476991
JB
6059 err = rdev->ops->set_power_mgmt(wdev->wiphy, dev, state,
6060 wdev->ps_timeout);
6061 if (!err)
6062 wdev->ps = state;
ffb9eb3d
KV
6063 return err;
6064}
6065
6066static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
6067{
4c476991 6068 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
6069 enum nl80211_ps_state ps_state;
6070 struct wireless_dev *wdev;
4c476991 6071 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
6072 struct sk_buff *msg;
6073 void *hdr;
6074 int err;
6075
ffb9eb3d
KV
6076 wdev = dev->ieee80211_ptr;
6077
4c476991
JB
6078 if (!rdev->ops->set_power_mgmt)
6079 return -EOPNOTSUPP;
ffb9eb3d
KV
6080
6081 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
6082 if (!msg)
6083 return -ENOMEM;
ffb9eb3d
KV
6084
6085 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
6086 NL80211_CMD_GET_POWER_SAVE);
6087 if (!hdr) {
4c476991 6088 err = -ENOBUFS;
ffb9eb3d
KV
6089 goto free_msg;
6090 }
6091
6092 if (wdev->ps)
6093 ps_state = NL80211_PS_ENABLED;
6094 else
6095 ps_state = NL80211_PS_DISABLED;
6096
9360ffd1
DM
6097 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
6098 goto nla_put_failure;
ffb9eb3d
KV
6099
6100 genlmsg_end(msg, hdr);
4c476991 6101 return genlmsg_reply(msg, info);
ffb9eb3d 6102
4c476991 6103 nla_put_failure:
ffb9eb3d 6104 err = -ENOBUFS;
4c476991 6105 free_msg:
ffb9eb3d 6106 nlmsg_free(msg);
ffb9eb3d
KV
6107 return err;
6108}
6109
d6dc1a38
JO
6110static struct nla_policy
6111nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = {
6112 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 },
6113 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
6114 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
6115};
6116
6117static int nl80211_set_cqm_rssi(struct genl_info *info,
6118 s32 threshold, u32 hysteresis)
6119{
4c476991 6120 struct cfg80211_registered_device *rdev = info->user_ptr[0];
d6dc1a38 6121 struct wireless_dev *wdev;
4c476991 6122 struct net_device *dev = info->user_ptr[1];
d6dc1a38
JO
6123
6124 if (threshold > 0)
6125 return -EINVAL;
6126
d6dc1a38
JO
6127 wdev = dev->ieee80211_ptr;
6128
4c476991
JB
6129 if (!rdev->ops->set_cqm_rssi_config)
6130 return -EOPNOTSUPP;
d6dc1a38 6131
074ac8df 6132 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
6133 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
6134 return -EOPNOTSUPP;
d6dc1a38 6135
4c476991
JB
6136 return rdev->ops->set_cqm_rssi_config(wdev->wiphy, dev,
6137 threshold, hysteresis);
d6dc1a38
JO
6138}
6139
6140static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
6141{
6142 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
6143 struct nlattr *cqm;
6144 int err;
6145
6146 cqm = info->attrs[NL80211_ATTR_CQM];
6147 if (!cqm) {
6148 err = -EINVAL;
6149 goto out;
6150 }
6151
6152 err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
6153 nl80211_attr_cqm_policy);
6154 if (err)
6155 goto out;
6156
6157 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
6158 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
6159 s32 threshold;
6160 u32 hysteresis;
6161 threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
6162 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
6163 err = nl80211_set_cqm_rssi(info, threshold, hysteresis);
6164 } else
6165 err = -EINVAL;
6166
6167out:
6168 return err;
6169}
6170
29cbe68c
JB
6171static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
6172{
6173 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6174 struct net_device *dev = info->user_ptr[1];
6175 struct mesh_config cfg;
c80d545d 6176 struct mesh_setup setup;
29cbe68c
JB
6177 int err;
6178
6179 /* start with default */
6180 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 6181 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 6182
24bdd9f4 6183 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 6184 /* and parse parameters if given */
24bdd9f4 6185 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
6186 if (err)
6187 return err;
6188 }
6189
6190 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
6191 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
6192 return -EINVAL;
6193
c80d545d
JC
6194 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
6195 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
6196
4bb62344
CYY
6197 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
6198 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
6199 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
6200 return -EINVAL;
6201
c80d545d
JC
6202 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
6203 /* parse additional setup parameters if given */
6204 err = nl80211_parse_mesh_setup(info, &setup);
6205 if (err)
6206 return err;
6207 }
6208
cc1d2806
JB
6209 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
6210 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
6211
6212 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
6213 !nl80211_valid_channel_type(info, &channel_type))
6214 return -EINVAL;
6215
6216 setup.channel = rdev_freq_to_chan(rdev,
6217 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
6218 channel_type);
6219 if (!setup.channel)
6220 return -EINVAL;
6221 setup.channel_type = channel_type;
6222 } else {
6223 /* cfg80211_join_mesh() will sort it out */
6224 setup.channel = NULL;
6225 }
6226
c80d545d 6227 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
29cbe68c
JB
6228}
6229
6230static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
6231{
6232 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6233 struct net_device *dev = info->user_ptr[1];
6234
6235 return cfg80211_leave_mesh(rdev, dev);
6236}
6237
ff1b6e69
JB
6238static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
6239{
6240 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6241 struct sk_buff *msg;
6242 void *hdr;
6243
6244 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
6245 return -EOPNOTSUPP;
6246
6247 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6248 if (!msg)
6249 return -ENOMEM;
6250
6251 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
6252 NL80211_CMD_GET_WOWLAN);
6253 if (!hdr)
6254 goto nla_put_failure;
6255
6256 if (rdev->wowlan) {
6257 struct nlattr *nl_wowlan;
6258
6259 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
6260 if (!nl_wowlan)
6261 goto nla_put_failure;
6262
9360ffd1
DM
6263 if ((rdev->wowlan->any &&
6264 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6265 (rdev->wowlan->disconnect &&
6266 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6267 (rdev->wowlan->magic_pkt &&
6268 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6269 (rdev->wowlan->gtk_rekey_failure &&
6270 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6271 (rdev->wowlan->eap_identity_req &&
6272 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6273 (rdev->wowlan->four_way_handshake &&
6274 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6275 (rdev->wowlan->rfkill_release &&
6276 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
6277 goto nla_put_failure;
ff1b6e69
JB
6278 if (rdev->wowlan->n_patterns) {
6279 struct nlattr *nl_pats, *nl_pat;
6280 int i, pat_len;
6281
6282 nl_pats = nla_nest_start(msg,
6283 NL80211_WOWLAN_TRIG_PKT_PATTERN);
6284 if (!nl_pats)
6285 goto nla_put_failure;
6286
6287 for (i = 0; i < rdev->wowlan->n_patterns; i++) {
6288 nl_pat = nla_nest_start(msg, i + 1);
6289 if (!nl_pat)
6290 goto nla_put_failure;
6291 pat_len = rdev->wowlan->patterns[i].pattern_len;
9360ffd1
DM
6292 if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK,
6293 DIV_ROUND_UP(pat_len, 8),
6294 rdev->wowlan->patterns[i].mask) ||
6295 nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN,
6296 pat_len,
6297 rdev->wowlan->patterns[i].pattern))
6298 goto nla_put_failure;
ff1b6e69
JB
6299 nla_nest_end(msg, nl_pat);
6300 }
6301 nla_nest_end(msg, nl_pats);
6302 }
6303
6304 nla_nest_end(msg, nl_wowlan);
6305 }
6306
6307 genlmsg_end(msg, hdr);
6308 return genlmsg_reply(msg, info);
6309
6310nla_put_failure:
6311 nlmsg_free(msg);
6312 return -ENOBUFS;
6313}
6314
6315static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
6316{
6317 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6318 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
6319 struct cfg80211_wowlan no_triggers = {};
6320 struct cfg80211_wowlan new_triggers = {};
6321 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan;
6322 int err, i;
6d52563f 6323 bool prev_enabled = rdev->wowlan;
ff1b6e69
JB
6324
6325 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns)
6326 return -EOPNOTSUPP;
6327
6328 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS])
6329 goto no_triggers;
6330
6331 err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG,
6332 nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
6333 nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]),
6334 nl80211_wowlan_policy);
6335 if (err)
6336 return err;
6337
6338 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
6339 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
6340 return -EINVAL;
6341 new_triggers.any = true;
6342 }
6343
6344 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
6345 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
6346 return -EINVAL;
6347 new_triggers.disconnect = true;
6348 }
6349
6350 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
6351 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
6352 return -EINVAL;
6353 new_triggers.magic_pkt = true;
6354 }
6355
77dbbb13
JB
6356 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
6357 return -EINVAL;
6358
6359 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
6360 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
6361 return -EINVAL;
6362 new_triggers.gtk_rekey_failure = true;
6363 }
6364
6365 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
6366 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
6367 return -EINVAL;
6368 new_triggers.eap_identity_req = true;
6369 }
6370
6371 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
6372 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
6373 return -EINVAL;
6374 new_triggers.four_way_handshake = true;
6375 }
6376
6377 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
6378 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
6379 return -EINVAL;
6380 new_triggers.rfkill_release = true;
6381 }
6382
ff1b6e69
JB
6383 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
6384 struct nlattr *pat;
6385 int n_patterns = 0;
6386 int rem, pat_len, mask_len;
6387 struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT];
6388
6389 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
6390 rem)
6391 n_patterns++;
6392 if (n_patterns > wowlan->n_patterns)
6393 return -EINVAL;
6394
6395 new_triggers.patterns = kcalloc(n_patterns,
6396 sizeof(new_triggers.patterns[0]),
6397 GFP_KERNEL);
6398 if (!new_triggers.patterns)
6399 return -ENOMEM;
6400
6401 new_triggers.n_patterns = n_patterns;
6402 i = 0;
6403
6404 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
6405 rem) {
6406 nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT,
6407 nla_data(pat), nla_len(pat), NULL);
6408 err = -EINVAL;
6409 if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] ||
6410 !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN])
6411 goto error;
6412 pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]);
6413 mask_len = DIV_ROUND_UP(pat_len, 8);
6414 if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) !=
6415 mask_len)
6416 goto error;
6417 if (pat_len > wowlan->pattern_max_len ||
6418 pat_len < wowlan->pattern_min_len)
6419 goto error;
6420
6421 new_triggers.patterns[i].mask =
6422 kmalloc(mask_len + pat_len, GFP_KERNEL);
6423 if (!new_triggers.patterns[i].mask) {
6424 err = -ENOMEM;
6425 goto error;
6426 }
6427 new_triggers.patterns[i].pattern =
6428 new_triggers.patterns[i].mask + mask_len;
6429 memcpy(new_triggers.patterns[i].mask,
6430 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]),
6431 mask_len);
6432 new_triggers.patterns[i].pattern_len = pat_len;
6433 memcpy(new_triggers.patterns[i].pattern,
6434 nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]),
6435 pat_len);
6436 i++;
6437 }
6438 }
6439
6440 if (memcmp(&new_triggers, &no_triggers, sizeof(new_triggers))) {
6441 struct cfg80211_wowlan *ntrig;
6442 ntrig = kmemdup(&new_triggers, sizeof(new_triggers),
6443 GFP_KERNEL);
6444 if (!ntrig) {
6445 err = -ENOMEM;
6446 goto error;
6447 }
6448 cfg80211_rdev_free_wowlan(rdev);
6449 rdev->wowlan = ntrig;
6450 } else {
6451 no_triggers:
6452 cfg80211_rdev_free_wowlan(rdev);
6453 rdev->wowlan = NULL;
6454 }
6455
6d52563f
JB
6456 if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan)
6457 rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan);
6458
ff1b6e69
JB
6459 return 0;
6460 error:
6461 for (i = 0; i < new_triggers.n_patterns; i++)
6462 kfree(new_triggers.patterns[i].mask);
6463 kfree(new_triggers.patterns);
6464 return err;
6465}
6466
e5497d76
JB
6467static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
6468{
6469 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6470 struct net_device *dev = info->user_ptr[1];
6471 struct wireless_dev *wdev = dev->ieee80211_ptr;
6472 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
6473 struct cfg80211_gtk_rekey_data rekey_data;
6474 int err;
6475
6476 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
6477 return -EINVAL;
6478
6479 err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
6480 nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
6481 nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
6482 nl80211_rekey_policy);
6483 if (err)
6484 return err;
6485
6486 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
6487 return -ERANGE;
6488 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
6489 return -ERANGE;
6490 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
6491 return -ERANGE;
6492
6493 memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]),
6494 NL80211_KEK_LEN);
6495 memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]),
6496 NL80211_KCK_LEN);
6497 memcpy(rekey_data.replay_ctr,
6498 nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]),
6499 NL80211_REPLAY_CTR_LEN);
6500
6501 wdev_lock(wdev);
6502 if (!wdev->current_bss) {
6503 err = -ENOTCONN;
6504 goto out;
6505 }
6506
6507 if (!rdev->ops->set_rekey_data) {
6508 err = -EOPNOTSUPP;
6509 goto out;
6510 }
6511
6512 err = rdev->ops->set_rekey_data(&rdev->wiphy, dev, &rekey_data);
6513 out:
6514 wdev_unlock(wdev);
6515 return err;
6516}
6517
28946da7
JB
6518static int nl80211_register_unexpected_frame(struct sk_buff *skb,
6519 struct genl_info *info)
6520{
6521 struct net_device *dev = info->user_ptr[1];
6522 struct wireless_dev *wdev = dev->ieee80211_ptr;
6523
6524 if (wdev->iftype != NL80211_IFTYPE_AP &&
6525 wdev->iftype != NL80211_IFTYPE_P2P_GO)
6526 return -EINVAL;
6527
6528 if (wdev->ap_unexpected_nlpid)
6529 return -EBUSY;
6530
6531 wdev->ap_unexpected_nlpid = info->snd_pid;
6532 return 0;
6533}
6534
7f6cf311
JB
6535static int nl80211_probe_client(struct sk_buff *skb,
6536 struct genl_info *info)
6537{
6538 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6539 struct net_device *dev = info->user_ptr[1];
6540 struct wireless_dev *wdev = dev->ieee80211_ptr;
6541 struct sk_buff *msg;
6542 void *hdr;
6543 const u8 *addr;
6544 u64 cookie;
6545 int err;
6546
6547 if (wdev->iftype != NL80211_IFTYPE_AP &&
6548 wdev->iftype != NL80211_IFTYPE_P2P_GO)
6549 return -EOPNOTSUPP;
6550
6551 if (!info->attrs[NL80211_ATTR_MAC])
6552 return -EINVAL;
6553
6554 if (!rdev->ops->probe_client)
6555 return -EOPNOTSUPP;
6556
6557 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6558 if (!msg)
6559 return -ENOMEM;
6560
6561 hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
6562 NL80211_CMD_PROBE_CLIENT);
6563
6564 if (IS_ERR(hdr)) {
6565 err = PTR_ERR(hdr);
6566 goto free_msg;
6567 }
6568
6569 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6570
6571 err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie);
6572 if (err)
6573 goto free_msg;
6574
9360ffd1
DM
6575 if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
6576 goto nla_put_failure;
7f6cf311
JB
6577
6578 genlmsg_end(msg, hdr);
6579
6580 return genlmsg_reply(msg, info);
6581
6582 nla_put_failure:
6583 err = -ENOBUFS;
6584 free_msg:
6585 nlmsg_free(msg);
6586 return err;
6587}
6588
5e760230
JB
6589static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
6590{
6591 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6592
6593 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
6594 return -EOPNOTSUPP;
6595
6596 if (rdev->ap_beacons_nlpid)
6597 return -EBUSY;
6598
6599 rdev->ap_beacons_nlpid = info->snd_pid;
6600
6601 return 0;
6602}
6603
4c476991
JB
6604#define NL80211_FLAG_NEED_WIPHY 0x01
6605#define NL80211_FLAG_NEED_NETDEV 0x02
6606#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
6607#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
6608#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
6609 NL80211_FLAG_CHECK_NETDEV_UP)
4c476991
JB
6610
6611static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
6612 struct genl_info *info)
6613{
6614 struct cfg80211_registered_device *rdev;
6615 struct net_device *dev;
6616 int err;
6617 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
6618
6619 if (rtnl)
6620 rtnl_lock();
6621
6622 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
6623 rdev = cfg80211_get_dev_from_info(info);
6624 if (IS_ERR(rdev)) {
6625 if (rtnl)
6626 rtnl_unlock();
6627 return PTR_ERR(rdev);
6628 }
6629 info->user_ptr[0] = rdev;
6630 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
00918d33
JB
6631 err = get_rdev_dev_by_ifindex(genl_info_net(info), info->attrs,
6632 &rdev, &dev);
4c476991
JB
6633 if (err) {
6634 if (rtnl)
6635 rtnl_unlock();
6636 return err;
6637 }
41265714
JB
6638 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
6639 !netif_running(dev)) {
d537f5fd
JB
6640 cfg80211_unlock_rdev(rdev);
6641 dev_put(dev);
41265714
JB
6642 if (rtnl)
6643 rtnl_unlock();
6644 return -ENETDOWN;
6645 }
4c476991
JB
6646 info->user_ptr[0] = rdev;
6647 info->user_ptr[1] = dev;
6648 }
6649
6650 return 0;
6651}
6652
6653static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
6654 struct genl_info *info)
6655{
6656 if (info->user_ptr[0])
6657 cfg80211_unlock_rdev(info->user_ptr[0]);
6658 if (info->user_ptr[1])
6659 dev_put(info->user_ptr[1]);
6660 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
6661 rtnl_unlock();
6662}
6663
55682965
JB
6664static struct genl_ops nl80211_ops[] = {
6665 {
6666 .cmd = NL80211_CMD_GET_WIPHY,
6667 .doit = nl80211_get_wiphy,
6668 .dumpit = nl80211_dump_wiphy,
6669 .policy = nl80211_policy,
6670 /* can be retrieved by unprivileged users */
4c476991 6671 .internal_flags = NL80211_FLAG_NEED_WIPHY,
55682965
JB
6672 },
6673 {
6674 .cmd = NL80211_CMD_SET_WIPHY,
6675 .doit = nl80211_set_wiphy,
6676 .policy = nl80211_policy,
6677 .flags = GENL_ADMIN_PERM,
4c476991 6678 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
6679 },
6680 {
6681 .cmd = NL80211_CMD_GET_INTERFACE,
6682 .doit = nl80211_get_interface,
6683 .dumpit = nl80211_dump_interface,
6684 .policy = nl80211_policy,
6685 /* can be retrieved by unprivileged users */
4c476991 6686 .internal_flags = NL80211_FLAG_NEED_NETDEV,
55682965
JB
6687 },
6688 {
6689 .cmd = NL80211_CMD_SET_INTERFACE,
6690 .doit = nl80211_set_interface,
6691 .policy = nl80211_policy,
6692 .flags = GENL_ADMIN_PERM,
4c476991
JB
6693 .internal_flags = NL80211_FLAG_NEED_NETDEV |
6694 NL80211_FLAG_NEED_RTNL,
55682965
JB
6695 },
6696 {
6697 .cmd = NL80211_CMD_NEW_INTERFACE,
6698 .doit = nl80211_new_interface,
6699 .policy = nl80211_policy,
6700 .flags = GENL_ADMIN_PERM,
4c476991
JB
6701 .internal_flags = NL80211_FLAG_NEED_WIPHY |
6702 NL80211_FLAG_NEED_RTNL,
55682965
JB
6703 },
6704 {
6705 .cmd = NL80211_CMD_DEL_INTERFACE,
6706 .doit = nl80211_del_interface,
6707 .policy = nl80211_policy,
41ade00f 6708 .flags = GENL_ADMIN_PERM,
4c476991
JB
6709 .internal_flags = NL80211_FLAG_NEED_NETDEV |
6710 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
6711 },
6712 {
6713 .cmd = NL80211_CMD_GET_KEY,
6714 .doit = nl80211_get_key,
6715 .policy = nl80211_policy,
6716 .flags = GENL_ADMIN_PERM,
2b5f8b0b 6717 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6718 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
6719 },
6720 {
6721 .cmd = NL80211_CMD_SET_KEY,
6722 .doit = nl80211_set_key,
6723 .policy = nl80211_policy,
6724 .flags = GENL_ADMIN_PERM,
41265714 6725 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6726 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
6727 },
6728 {
6729 .cmd = NL80211_CMD_NEW_KEY,
6730 .doit = nl80211_new_key,
6731 .policy = nl80211_policy,
6732 .flags = GENL_ADMIN_PERM,
41265714 6733 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6734 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
6735 },
6736 {
6737 .cmd = NL80211_CMD_DEL_KEY,
6738 .doit = nl80211_del_key,
6739 .policy = nl80211_policy,
55682965 6740 .flags = GENL_ADMIN_PERM,
41265714 6741 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6742 NL80211_FLAG_NEED_RTNL,
55682965 6743 },
ed1b6cc7
JB
6744 {
6745 .cmd = NL80211_CMD_SET_BEACON,
6746 .policy = nl80211_policy,
6747 .flags = GENL_ADMIN_PERM,
8860020e 6748 .doit = nl80211_set_beacon,
2b5f8b0b 6749 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6750 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
6751 },
6752 {
8860020e 6753 .cmd = NL80211_CMD_START_AP,
ed1b6cc7
JB
6754 .policy = nl80211_policy,
6755 .flags = GENL_ADMIN_PERM,
8860020e 6756 .doit = nl80211_start_ap,
2b5f8b0b 6757 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6758 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
6759 },
6760 {
8860020e 6761 .cmd = NL80211_CMD_STOP_AP,
ed1b6cc7
JB
6762 .policy = nl80211_policy,
6763 .flags = GENL_ADMIN_PERM,
8860020e 6764 .doit = nl80211_stop_ap,
2b5f8b0b 6765 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6766 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 6767 },
5727ef1b
JB
6768 {
6769 .cmd = NL80211_CMD_GET_STATION,
6770 .doit = nl80211_get_station,
2ec600d6 6771 .dumpit = nl80211_dump_station,
5727ef1b 6772 .policy = nl80211_policy,
4c476991
JB
6773 .internal_flags = NL80211_FLAG_NEED_NETDEV |
6774 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
6775 },
6776 {
6777 .cmd = NL80211_CMD_SET_STATION,
6778 .doit = nl80211_set_station,
6779 .policy = nl80211_policy,
6780 .flags = GENL_ADMIN_PERM,
2b5f8b0b 6781 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6782 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
6783 },
6784 {
6785 .cmd = NL80211_CMD_NEW_STATION,
6786 .doit = nl80211_new_station,
6787 .policy = nl80211_policy,
6788 .flags = GENL_ADMIN_PERM,
41265714 6789 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6790 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
6791 },
6792 {
6793 .cmd = NL80211_CMD_DEL_STATION,
6794 .doit = nl80211_del_station,
6795 .policy = nl80211_policy,
2ec600d6 6796 .flags = GENL_ADMIN_PERM,
2b5f8b0b 6797 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6798 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
6799 },
6800 {
6801 .cmd = NL80211_CMD_GET_MPATH,
6802 .doit = nl80211_get_mpath,
6803 .dumpit = nl80211_dump_mpath,
6804 .policy = nl80211_policy,
6805 .flags = GENL_ADMIN_PERM,
41265714 6806 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6807 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
6808 },
6809 {
6810 .cmd = NL80211_CMD_SET_MPATH,
6811 .doit = nl80211_set_mpath,
6812 .policy = nl80211_policy,
6813 .flags = GENL_ADMIN_PERM,
41265714 6814 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6815 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
6816 },
6817 {
6818 .cmd = NL80211_CMD_NEW_MPATH,
6819 .doit = nl80211_new_mpath,
6820 .policy = nl80211_policy,
6821 .flags = GENL_ADMIN_PERM,
41265714 6822 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6823 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
6824 },
6825 {
6826 .cmd = NL80211_CMD_DEL_MPATH,
6827 .doit = nl80211_del_mpath,
6828 .policy = nl80211_policy,
9f1ba906 6829 .flags = GENL_ADMIN_PERM,
2b5f8b0b 6830 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6831 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
6832 },
6833 {
6834 .cmd = NL80211_CMD_SET_BSS,
6835 .doit = nl80211_set_bss,
6836 .policy = nl80211_policy,
b2e1b302 6837 .flags = GENL_ADMIN_PERM,
2b5f8b0b 6838 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6839 NL80211_FLAG_NEED_RTNL,
b2e1b302 6840 },
f130347c
LR
6841 {
6842 .cmd = NL80211_CMD_GET_REG,
6843 .doit = nl80211_get_reg,
6844 .policy = nl80211_policy,
6845 /* can be retrieved by unprivileged users */
6846 },
b2e1b302
LR
6847 {
6848 .cmd = NL80211_CMD_SET_REG,
6849 .doit = nl80211_set_reg,
6850 .policy = nl80211_policy,
6851 .flags = GENL_ADMIN_PERM,
6852 },
6853 {
6854 .cmd = NL80211_CMD_REQ_SET_REG,
6855 .doit = nl80211_req_set_reg,
6856 .policy = nl80211_policy,
93da9cc1 6857 .flags = GENL_ADMIN_PERM,
6858 },
6859 {
24bdd9f4
JC
6860 .cmd = NL80211_CMD_GET_MESH_CONFIG,
6861 .doit = nl80211_get_mesh_config,
93da9cc1 6862 .policy = nl80211_policy,
6863 /* can be retrieved by unprivileged users */
2b5f8b0b 6864 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6865 NL80211_FLAG_NEED_RTNL,
93da9cc1 6866 },
6867 {
24bdd9f4
JC
6868 .cmd = NL80211_CMD_SET_MESH_CONFIG,
6869 .doit = nl80211_update_mesh_config,
93da9cc1 6870 .policy = nl80211_policy,
9aed3cc1 6871 .flags = GENL_ADMIN_PERM,
29cbe68c 6872 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6873 NL80211_FLAG_NEED_RTNL,
9aed3cc1 6874 },
2a519311
JB
6875 {
6876 .cmd = NL80211_CMD_TRIGGER_SCAN,
6877 .doit = nl80211_trigger_scan,
6878 .policy = nl80211_policy,
6879 .flags = GENL_ADMIN_PERM,
41265714 6880 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6881 NL80211_FLAG_NEED_RTNL,
2a519311
JB
6882 },
6883 {
6884 .cmd = NL80211_CMD_GET_SCAN,
6885 .policy = nl80211_policy,
6886 .dumpit = nl80211_dump_scan,
6887 },
807f8a8c
LC
6888 {
6889 .cmd = NL80211_CMD_START_SCHED_SCAN,
6890 .doit = nl80211_start_sched_scan,
6891 .policy = nl80211_policy,
6892 .flags = GENL_ADMIN_PERM,
6893 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6894 NL80211_FLAG_NEED_RTNL,
6895 },
6896 {
6897 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
6898 .doit = nl80211_stop_sched_scan,
6899 .policy = nl80211_policy,
6900 .flags = GENL_ADMIN_PERM,
6901 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6902 NL80211_FLAG_NEED_RTNL,
6903 },
636a5d36
JM
6904 {
6905 .cmd = NL80211_CMD_AUTHENTICATE,
6906 .doit = nl80211_authenticate,
6907 .policy = nl80211_policy,
6908 .flags = GENL_ADMIN_PERM,
41265714 6909 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6910 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
6911 },
6912 {
6913 .cmd = NL80211_CMD_ASSOCIATE,
6914 .doit = nl80211_associate,
6915 .policy = nl80211_policy,
6916 .flags = GENL_ADMIN_PERM,
41265714 6917 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6918 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
6919 },
6920 {
6921 .cmd = NL80211_CMD_DEAUTHENTICATE,
6922 .doit = nl80211_deauthenticate,
6923 .policy = nl80211_policy,
6924 .flags = GENL_ADMIN_PERM,
41265714 6925 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6926 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
6927 },
6928 {
6929 .cmd = NL80211_CMD_DISASSOCIATE,
6930 .doit = nl80211_disassociate,
6931 .policy = nl80211_policy,
6932 .flags = GENL_ADMIN_PERM,
41265714 6933 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6934 NL80211_FLAG_NEED_RTNL,
636a5d36 6935 },
04a773ad
JB
6936 {
6937 .cmd = NL80211_CMD_JOIN_IBSS,
6938 .doit = nl80211_join_ibss,
6939 .policy = nl80211_policy,
6940 .flags = GENL_ADMIN_PERM,
41265714 6941 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6942 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
6943 },
6944 {
6945 .cmd = NL80211_CMD_LEAVE_IBSS,
6946 .doit = nl80211_leave_ibss,
6947 .policy = nl80211_policy,
6948 .flags = GENL_ADMIN_PERM,
41265714 6949 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6950 NL80211_FLAG_NEED_RTNL,
04a773ad 6951 },
aff89a9b
JB
6952#ifdef CONFIG_NL80211_TESTMODE
6953 {
6954 .cmd = NL80211_CMD_TESTMODE,
6955 .doit = nl80211_testmode_do,
71063f0e 6956 .dumpit = nl80211_testmode_dump,
aff89a9b
JB
6957 .policy = nl80211_policy,
6958 .flags = GENL_ADMIN_PERM,
4c476991
JB
6959 .internal_flags = NL80211_FLAG_NEED_WIPHY |
6960 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
6961 },
6962#endif
b23aa676
SO
6963 {
6964 .cmd = NL80211_CMD_CONNECT,
6965 .doit = nl80211_connect,
6966 .policy = nl80211_policy,
6967 .flags = GENL_ADMIN_PERM,
41265714 6968 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6969 NL80211_FLAG_NEED_RTNL,
b23aa676
SO
6970 },
6971 {
6972 .cmd = NL80211_CMD_DISCONNECT,
6973 .doit = nl80211_disconnect,
6974 .policy = nl80211_policy,
6975 .flags = GENL_ADMIN_PERM,
41265714 6976 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6977 NL80211_FLAG_NEED_RTNL,
b23aa676 6978 },
463d0183
JB
6979 {
6980 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
6981 .doit = nl80211_wiphy_netns,
6982 .policy = nl80211_policy,
6983 .flags = GENL_ADMIN_PERM,
4c476991
JB
6984 .internal_flags = NL80211_FLAG_NEED_WIPHY |
6985 NL80211_FLAG_NEED_RTNL,
463d0183 6986 },
61fa713c
HS
6987 {
6988 .cmd = NL80211_CMD_GET_SURVEY,
6989 .policy = nl80211_policy,
6990 .dumpit = nl80211_dump_survey,
6991 },
67fbb16b
SO
6992 {
6993 .cmd = NL80211_CMD_SET_PMKSA,
6994 .doit = nl80211_setdel_pmksa,
6995 .policy = nl80211_policy,
6996 .flags = GENL_ADMIN_PERM,
2b5f8b0b 6997 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 6998 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
6999 },
7000 {
7001 .cmd = NL80211_CMD_DEL_PMKSA,
7002 .doit = nl80211_setdel_pmksa,
7003 .policy = nl80211_policy,
7004 .flags = GENL_ADMIN_PERM,
2b5f8b0b 7005 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 7006 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
7007 },
7008 {
7009 .cmd = NL80211_CMD_FLUSH_PMKSA,
7010 .doit = nl80211_flush_pmksa,
7011 .policy = nl80211_policy,
7012 .flags = GENL_ADMIN_PERM,
2b5f8b0b 7013 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 7014 NL80211_FLAG_NEED_RTNL,
67fbb16b 7015 },
9588bbd5
JM
7016 {
7017 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
7018 .doit = nl80211_remain_on_channel,
7019 .policy = nl80211_policy,
7020 .flags = GENL_ADMIN_PERM,
41265714 7021 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 7022 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
7023 },
7024 {
7025 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
7026 .doit = nl80211_cancel_remain_on_channel,
7027 .policy = nl80211_policy,
7028 .flags = GENL_ADMIN_PERM,
41265714 7029 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 7030 NL80211_FLAG_NEED_RTNL,
9588bbd5 7031 },
13ae75b1
JM
7032 {
7033 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
7034 .doit = nl80211_set_tx_bitrate_mask,
7035 .policy = nl80211_policy,
7036 .flags = GENL_ADMIN_PERM,
4c476991
JB
7037 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7038 NL80211_FLAG_NEED_RTNL,
13ae75b1 7039 },
026331c4 7040 {
2e161f78
JB
7041 .cmd = NL80211_CMD_REGISTER_FRAME,
7042 .doit = nl80211_register_mgmt,
026331c4
JM
7043 .policy = nl80211_policy,
7044 .flags = GENL_ADMIN_PERM,
4c476991
JB
7045 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7046 NL80211_FLAG_NEED_RTNL,
026331c4
JM
7047 },
7048 {
2e161f78
JB
7049 .cmd = NL80211_CMD_FRAME,
7050 .doit = nl80211_tx_mgmt,
026331c4 7051 .policy = nl80211_policy,
f7ca38df
JB
7052 .flags = GENL_ADMIN_PERM,
7053 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7054 NL80211_FLAG_NEED_RTNL,
7055 },
7056 {
7057 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
7058 .doit = nl80211_tx_mgmt_cancel_wait,
7059 .policy = nl80211_policy,
026331c4 7060 .flags = GENL_ADMIN_PERM,
41265714 7061 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 7062 NL80211_FLAG_NEED_RTNL,
026331c4 7063 },
ffb9eb3d
KV
7064 {
7065 .cmd = NL80211_CMD_SET_POWER_SAVE,
7066 .doit = nl80211_set_power_save,
7067 .policy = nl80211_policy,
7068 .flags = GENL_ADMIN_PERM,
4c476991
JB
7069 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7070 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
7071 },
7072 {
7073 .cmd = NL80211_CMD_GET_POWER_SAVE,
7074 .doit = nl80211_get_power_save,
7075 .policy = nl80211_policy,
7076 /* can be retrieved by unprivileged users */
4c476991
JB
7077 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7078 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 7079 },
d6dc1a38
JO
7080 {
7081 .cmd = NL80211_CMD_SET_CQM,
7082 .doit = nl80211_set_cqm,
7083 .policy = nl80211_policy,
7084 .flags = GENL_ADMIN_PERM,
4c476991
JB
7085 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7086 NL80211_FLAG_NEED_RTNL,
d6dc1a38 7087 },
f444de05
JB
7088 {
7089 .cmd = NL80211_CMD_SET_CHANNEL,
7090 .doit = nl80211_set_channel,
7091 .policy = nl80211_policy,
7092 .flags = GENL_ADMIN_PERM,
4c476991
JB
7093 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7094 NL80211_FLAG_NEED_RTNL,
f444de05 7095 },
e8347eba
BJ
7096 {
7097 .cmd = NL80211_CMD_SET_WDS_PEER,
7098 .doit = nl80211_set_wds_peer,
7099 .policy = nl80211_policy,
7100 .flags = GENL_ADMIN_PERM,
43b19952
JB
7101 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7102 NL80211_FLAG_NEED_RTNL,
e8347eba 7103 },
29cbe68c
JB
7104 {
7105 .cmd = NL80211_CMD_JOIN_MESH,
7106 .doit = nl80211_join_mesh,
7107 .policy = nl80211_policy,
7108 .flags = GENL_ADMIN_PERM,
7109 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7110 NL80211_FLAG_NEED_RTNL,
7111 },
7112 {
7113 .cmd = NL80211_CMD_LEAVE_MESH,
7114 .doit = nl80211_leave_mesh,
7115 .policy = nl80211_policy,
7116 .flags = GENL_ADMIN_PERM,
7117 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7118 NL80211_FLAG_NEED_RTNL,
7119 },
ff1b6e69
JB
7120 {
7121 .cmd = NL80211_CMD_GET_WOWLAN,
7122 .doit = nl80211_get_wowlan,
7123 .policy = nl80211_policy,
7124 /* can be retrieved by unprivileged users */
7125 .internal_flags = NL80211_FLAG_NEED_WIPHY |
7126 NL80211_FLAG_NEED_RTNL,
7127 },
7128 {
7129 .cmd = NL80211_CMD_SET_WOWLAN,
7130 .doit = nl80211_set_wowlan,
7131 .policy = nl80211_policy,
7132 .flags = GENL_ADMIN_PERM,
7133 .internal_flags = NL80211_FLAG_NEED_WIPHY |
7134 NL80211_FLAG_NEED_RTNL,
7135 },
e5497d76
JB
7136 {
7137 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
7138 .doit = nl80211_set_rekey_data,
7139 .policy = nl80211_policy,
7140 .flags = GENL_ADMIN_PERM,
7141 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7142 NL80211_FLAG_NEED_RTNL,
7143 },
109086ce
AN
7144 {
7145 .cmd = NL80211_CMD_TDLS_MGMT,
7146 .doit = nl80211_tdls_mgmt,
7147 .policy = nl80211_policy,
7148 .flags = GENL_ADMIN_PERM,
7149 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7150 NL80211_FLAG_NEED_RTNL,
7151 },
7152 {
7153 .cmd = NL80211_CMD_TDLS_OPER,
7154 .doit = nl80211_tdls_oper,
7155 .policy = nl80211_policy,
7156 .flags = GENL_ADMIN_PERM,
7157 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7158 NL80211_FLAG_NEED_RTNL,
7159 },
28946da7
JB
7160 {
7161 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
7162 .doit = nl80211_register_unexpected_frame,
7163 .policy = nl80211_policy,
7164 .flags = GENL_ADMIN_PERM,
7165 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7166 NL80211_FLAG_NEED_RTNL,
7167 },
7f6cf311
JB
7168 {
7169 .cmd = NL80211_CMD_PROBE_CLIENT,
7170 .doit = nl80211_probe_client,
7171 .policy = nl80211_policy,
7172 .flags = GENL_ADMIN_PERM,
2b5f8b0b 7173 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
7174 NL80211_FLAG_NEED_RTNL,
7175 },
5e760230
JB
7176 {
7177 .cmd = NL80211_CMD_REGISTER_BEACONS,
7178 .doit = nl80211_register_beacons,
7179 .policy = nl80211_policy,
7180 .flags = GENL_ADMIN_PERM,
7181 .internal_flags = NL80211_FLAG_NEED_WIPHY |
7182 NL80211_FLAG_NEED_RTNL,
7183 },
1d9d9213
SW
7184 {
7185 .cmd = NL80211_CMD_SET_NOACK_MAP,
7186 .doit = nl80211_set_noack_map,
7187 .policy = nl80211_policy,
7188 .flags = GENL_ADMIN_PERM,
7189 .internal_flags = NL80211_FLAG_NEED_NETDEV |
7190 NL80211_FLAG_NEED_RTNL,
7191 },
7192
55682965 7193};
9588bbd5 7194
6039f6d2
JM
7195static struct genl_multicast_group nl80211_mlme_mcgrp = {
7196 .name = "mlme",
7197};
55682965
JB
7198
7199/* multicast groups */
7200static struct genl_multicast_group nl80211_config_mcgrp = {
7201 .name = "config",
7202};
2a519311
JB
7203static struct genl_multicast_group nl80211_scan_mcgrp = {
7204 .name = "scan",
7205};
73d54c9e
LR
7206static struct genl_multicast_group nl80211_regulatory_mcgrp = {
7207 .name = "regulatory",
7208};
55682965
JB
7209
7210/* notification functions */
7211
7212void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
7213{
7214 struct sk_buff *msg;
7215
fd2120ca 7216 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
7217 if (!msg)
7218 return;
7219
7220 if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) {
7221 nlmsg_free(msg);
7222 return;
7223 }
7224
463d0183
JB
7225 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7226 nl80211_config_mcgrp.id, GFP_KERNEL);
55682965
JB
7227}
7228
362a415d
JB
7229static int nl80211_add_scan_req(struct sk_buff *msg,
7230 struct cfg80211_registered_device *rdev)
7231{
7232 struct cfg80211_scan_request *req = rdev->scan_req;
7233 struct nlattr *nest;
7234 int i;
7235
667503dd
JB
7236 ASSERT_RDEV_LOCK(rdev);
7237
362a415d
JB
7238 if (WARN_ON(!req))
7239 return 0;
7240
7241 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
7242 if (!nest)
7243 goto nla_put_failure;
9360ffd1
DM
7244 for (i = 0; i < req->n_ssids; i++) {
7245 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
7246 goto nla_put_failure;
7247 }
362a415d
JB
7248 nla_nest_end(msg, nest);
7249
7250 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
7251 if (!nest)
7252 goto nla_put_failure;
9360ffd1
DM
7253 for (i = 0; i < req->n_channels; i++) {
7254 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
7255 goto nla_put_failure;
7256 }
362a415d
JB
7257 nla_nest_end(msg, nest);
7258
9360ffd1
DM
7259 if (req->ie &&
7260 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
7261 goto nla_put_failure;
362a415d
JB
7262
7263 return 0;
7264 nla_put_failure:
7265 return -ENOBUFS;
7266}
7267
a538e2d5
JB
7268static int nl80211_send_scan_msg(struct sk_buff *msg,
7269 struct cfg80211_registered_device *rdev,
7270 struct net_device *netdev,
7271 u32 pid, u32 seq, int flags,
7272 u32 cmd)
2a519311
JB
7273{
7274 void *hdr;
7275
7276 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
7277 if (!hdr)
7278 return -1;
7279
9360ffd1
DM
7280 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7281 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
7282 goto nla_put_failure;
2a519311 7283
362a415d
JB
7284 /* ignore errors and send incomplete event anyway */
7285 nl80211_add_scan_req(msg, rdev);
2a519311
JB
7286
7287 return genlmsg_end(msg, hdr);
7288
7289 nla_put_failure:
7290 genlmsg_cancel(msg, hdr);
7291 return -EMSGSIZE;
7292}
7293
807f8a8c
LC
7294static int
7295nl80211_send_sched_scan_msg(struct sk_buff *msg,
7296 struct cfg80211_registered_device *rdev,
7297 struct net_device *netdev,
7298 u32 pid, u32 seq, int flags, u32 cmd)
7299{
7300 void *hdr;
7301
7302 hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
7303 if (!hdr)
7304 return -1;
7305
9360ffd1
DM
7306 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7307 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
7308 goto nla_put_failure;
807f8a8c
LC
7309
7310 return genlmsg_end(msg, hdr);
7311
7312 nla_put_failure:
7313 genlmsg_cancel(msg, hdr);
7314 return -EMSGSIZE;
7315}
7316
a538e2d5
JB
7317void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
7318 struct net_device *netdev)
7319{
7320 struct sk_buff *msg;
7321
7322 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
7323 if (!msg)
7324 return;
7325
7326 if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
7327 NL80211_CMD_TRIGGER_SCAN) < 0) {
7328 nlmsg_free(msg);
7329 return;
7330 }
7331
463d0183
JB
7332 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7333 nl80211_scan_mcgrp.id, GFP_KERNEL);
a538e2d5
JB
7334}
7335
2a519311
JB
7336void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
7337 struct net_device *netdev)
7338{
7339 struct sk_buff *msg;
7340
fd2120ca 7341 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311
JB
7342 if (!msg)
7343 return;
7344
a538e2d5
JB
7345 if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
7346 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311
JB
7347 nlmsg_free(msg);
7348 return;
7349 }
7350
463d0183
JB
7351 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7352 nl80211_scan_mcgrp.id, GFP_KERNEL);
2a519311
JB
7353}
7354
7355void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
7356 struct net_device *netdev)
7357{
7358 struct sk_buff *msg;
7359
fd2120ca 7360 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311
JB
7361 if (!msg)
7362 return;
7363
a538e2d5
JB
7364 if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0,
7365 NL80211_CMD_SCAN_ABORTED) < 0) {
2a519311
JB
7366 nlmsg_free(msg);
7367 return;
7368 }
7369
463d0183
JB
7370 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7371 nl80211_scan_mcgrp.id, GFP_KERNEL);
2a519311
JB
7372}
7373
807f8a8c
LC
7374void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
7375 struct net_device *netdev)
7376{
7377 struct sk_buff *msg;
7378
7379 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7380 if (!msg)
7381 return;
7382
7383 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0,
7384 NL80211_CMD_SCHED_SCAN_RESULTS) < 0) {
7385 nlmsg_free(msg);
7386 return;
7387 }
7388
7389 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7390 nl80211_scan_mcgrp.id, GFP_KERNEL);
7391}
7392
7393void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
7394 struct net_device *netdev, u32 cmd)
7395{
7396 struct sk_buff *msg;
7397
7398 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
7399 if (!msg)
7400 return;
7401
7402 if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
7403 nlmsg_free(msg);
7404 return;
7405 }
7406
7407 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7408 nl80211_scan_mcgrp.id, GFP_KERNEL);
7409}
7410
73d54c9e
LR
7411/*
7412 * This can happen on global regulatory changes or device specific settings
7413 * based on custom world regulatory domains.
7414 */
7415void nl80211_send_reg_change_event(struct regulatory_request *request)
7416{
7417 struct sk_buff *msg;
7418 void *hdr;
7419
fd2120ca 7420 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
73d54c9e
LR
7421 if (!msg)
7422 return;
7423
7424 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE);
7425 if (!hdr) {
7426 nlmsg_free(msg);
7427 return;
7428 }
7429
7430 /* Userspace can always count this one always being set */
9360ffd1
DM
7431 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
7432 goto nla_put_failure;
7433
7434 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
7435 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
7436 NL80211_REGDOM_TYPE_WORLD))
7437 goto nla_put_failure;
7438 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
7439 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
7440 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
7441 goto nla_put_failure;
7442 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
7443 request->intersect) {
7444 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
7445 NL80211_REGDOM_TYPE_INTERSECTION))
7446 goto nla_put_failure;
7447 } else {
7448 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
7449 NL80211_REGDOM_TYPE_COUNTRY) ||
7450 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
7451 request->alpha2))
7452 goto nla_put_failure;
7453 }
7454
7455 if (wiphy_idx_valid(request->wiphy_idx) &&
7456 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
7457 goto nla_put_failure;
73d54c9e 7458
3b7b72ee 7459 genlmsg_end(msg, hdr);
73d54c9e 7460
bc43b28c 7461 rcu_read_lock();
463d0183 7462 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
bc43b28c
JB
7463 GFP_ATOMIC);
7464 rcu_read_unlock();
73d54c9e
LR
7465
7466 return;
7467
7468nla_put_failure:
7469 genlmsg_cancel(msg, hdr);
7470 nlmsg_free(msg);
7471}
7472
6039f6d2
JM
7473static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
7474 struct net_device *netdev,
7475 const u8 *buf, size_t len,
e6d6e342 7476 enum nl80211_commands cmd, gfp_t gfp)
6039f6d2
JM
7477{
7478 struct sk_buff *msg;
7479 void *hdr;
7480
e6d6e342 7481 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
6039f6d2
JM
7482 if (!msg)
7483 return;
7484
7485 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
7486 if (!hdr) {
7487 nlmsg_free(msg);
7488 return;
7489 }
7490
9360ffd1
DM
7491 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7492 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7493 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
7494 goto nla_put_failure;
6039f6d2 7495
3b7b72ee 7496 genlmsg_end(msg, hdr);
6039f6d2 7497
463d0183
JB
7498 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7499 nl80211_mlme_mcgrp.id, gfp);
6039f6d2
JM
7500 return;
7501
7502 nla_put_failure:
7503 genlmsg_cancel(msg, hdr);
7504 nlmsg_free(msg);
7505}
7506
7507void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
7508 struct net_device *netdev, const u8 *buf,
7509 size_t len, gfp_t gfp)
6039f6d2
JM
7510{
7511 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 7512 NL80211_CMD_AUTHENTICATE, gfp);
6039f6d2
JM
7513}
7514
7515void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
7516 struct net_device *netdev, const u8 *buf,
e6d6e342 7517 size_t len, gfp_t gfp)
6039f6d2 7518{
e6d6e342
JB
7519 nl80211_send_mlme_event(rdev, netdev, buf, len,
7520 NL80211_CMD_ASSOCIATE, gfp);
6039f6d2
JM
7521}
7522
53b46b84 7523void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
7524 struct net_device *netdev, const u8 *buf,
7525 size_t len, gfp_t gfp)
6039f6d2
JM
7526{
7527 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 7528 NL80211_CMD_DEAUTHENTICATE, gfp);
6039f6d2
JM
7529}
7530
53b46b84
JM
7531void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
7532 struct net_device *netdev, const u8 *buf,
e6d6e342 7533 size_t len, gfp_t gfp)
6039f6d2
JM
7534{
7535 nl80211_send_mlme_event(rdev, netdev, buf, len,
e6d6e342 7536 NL80211_CMD_DISASSOCIATE, gfp);
6039f6d2
JM
7537}
7538
cf4e594e
JM
7539void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev,
7540 struct net_device *netdev, const u8 *buf,
7541 size_t len, gfp_t gfp)
7542{
7543 nl80211_send_mlme_event(rdev, netdev, buf, len,
7544 NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp);
7545}
7546
7547void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev,
7548 struct net_device *netdev, const u8 *buf,
7549 size_t len, gfp_t gfp)
7550{
7551 nl80211_send_mlme_event(rdev, netdev, buf, len,
7552 NL80211_CMD_UNPROT_DISASSOCIATE, gfp);
7553}
7554
1b06bb40
LR
7555static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
7556 struct net_device *netdev, int cmd,
e6d6e342 7557 const u8 *addr, gfp_t gfp)
1965c853
JM
7558{
7559 struct sk_buff *msg;
7560 void *hdr;
7561
e6d6e342 7562 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
7563 if (!msg)
7564 return;
7565
7566 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
7567 if (!hdr) {
7568 nlmsg_free(msg);
7569 return;
7570 }
7571
9360ffd1
DM
7572 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7573 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7574 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
7575 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
7576 goto nla_put_failure;
1965c853 7577
3b7b72ee 7578 genlmsg_end(msg, hdr);
1965c853 7579
463d0183
JB
7580 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7581 nl80211_mlme_mcgrp.id, gfp);
1965c853
JM
7582 return;
7583
7584 nla_put_failure:
7585 genlmsg_cancel(msg, hdr);
7586 nlmsg_free(msg);
7587}
7588
7589void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
7590 struct net_device *netdev, const u8 *addr,
7591 gfp_t gfp)
1965c853
JM
7592{
7593 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 7594 addr, gfp);
1965c853
JM
7595}
7596
7597void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
7598 struct net_device *netdev, const u8 *addr,
7599 gfp_t gfp)
1965c853 7600{
e6d6e342
JB
7601 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
7602 addr, gfp);
1965c853
JM
7603}
7604
b23aa676
SO
7605void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
7606 struct net_device *netdev, const u8 *bssid,
7607 const u8 *req_ie, size_t req_ie_len,
7608 const u8 *resp_ie, size_t resp_ie_len,
7609 u16 status, gfp_t gfp)
7610{
7611 struct sk_buff *msg;
7612 void *hdr;
7613
7614 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7615 if (!msg)
7616 return;
7617
7618 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
7619 if (!hdr) {
7620 nlmsg_free(msg);
7621 return;
7622 }
7623
9360ffd1
DM
7624 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7625 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7626 (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) ||
7627 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status) ||
7628 (req_ie &&
7629 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
7630 (resp_ie &&
7631 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
7632 goto nla_put_failure;
b23aa676 7633
3b7b72ee 7634 genlmsg_end(msg, hdr);
b23aa676 7635
463d0183
JB
7636 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7637 nl80211_mlme_mcgrp.id, gfp);
b23aa676
SO
7638 return;
7639
7640 nla_put_failure:
7641 genlmsg_cancel(msg, hdr);
7642 nlmsg_free(msg);
7643
7644}
7645
7646void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
7647 struct net_device *netdev, const u8 *bssid,
7648 const u8 *req_ie, size_t req_ie_len,
7649 const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
7650{
7651 struct sk_buff *msg;
7652 void *hdr;
7653
7654 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7655 if (!msg)
7656 return;
7657
7658 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
7659 if (!hdr) {
7660 nlmsg_free(msg);
7661 return;
7662 }
7663
9360ffd1
DM
7664 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7665 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7666 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
7667 (req_ie &&
7668 nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
7669 (resp_ie &&
7670 nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
7671 goto nla_put_failure;
b23aa676 7672
3b7b72ee 7673 genlmsg_end(msg, hdr);
b23aa676 7674
463d0183
JB
7675 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7676 nl80211_mlme_mcgrp.id, gfp);
b23aa676
SO
7677 return;
7678
7679 nla_put_failure:
7680 genlmsg_cancel(msg, hdr);
7681 nlmsg_free(msg);
7682
7683}
7684
7685void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
7686 struct net_device *netdev, u16 reason,
667503dd 7687 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
7688{
7689 struct sk_buff *msg;
7690 void *hdr;
7691
667503dd 7692 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
b23aa676
SO
7693 if (!msg)
7694 return;
7695
7696 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
7697 if (!hdr) {
7698 nlmsg_free(msg);
7699 return;
7700 }
7701
9360ffd1
DM
7702 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7703 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7704 (from_ap && reason &&
7705 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
7706 (from_ap &&
7707 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
7708 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
7709 goto nla_put_failure;
b23aa676 7710
3b7b72ee 7711 genlmsg_end(msg, hdr);
b23aa676 7712
463d0183
JB
7713 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7714 nl80211_mlme_mcgrp.id, GFP_KERNEL);
b23aa676
SO
7715 return;
7716
7717 nla_put_failure:
7718 genlmsg_cancel(msg, hdr);
7719 nlmsg_free(msg);
7720
7721}
7722
04a773ad
JB
7723void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
7724 struct net_device *netdev, const u8 *bssid,
7725 gfp_t gfp)
7726{
7727 struct sk_buff *msg;
7728 void *hdr;
7729
fd2120ca 7730 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
7731 if (!msg)
7732 return;
7733
7734 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
7735 if (!hdr) {
7736 nlmsg_free(msg);
7737 return;
7738 }
7739
9360ffd1
DM
7740 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7741 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7742 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
7743 goto nla_put_failure;
04a773ad 7744
3b7b72ee 7745 genlmsg_end(msg, hdr);
04a773ad 7746
463d0183
JB
7747 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7748 nl80211_mlme_mcgrp.id, gfp);
04a773ad
JB
7749 return;
7750
7751 nla_put_failure:
7752 genlmsg_cancel(msg, hdr);
7753 nlmsg_free(msg);
7754}
7755
c93b5e71
JC
7756void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev,
7757 struct net_device *netdev,
7758 const u8 *macaddr, const u8* ie, u8 ie_len,
7759 gfp_t gfp)
7760{
7761 struct sk_buff *msg;
7762 void *hdr;
7763
7764 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7765 if (!msg)
7766 return;
7767
7768 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
7769 if (!hdr) {
7770 nlmsg_free(msg);
7771 return;
7772 }
7773
9360ffd1
DM
7774 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7775 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7776 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr) ||
7777 (ie_len && ie &&
7778 nla_put(msg, NL80211_ATTR_IE, ie_len , ie)))
7779 goto nla_put_failure;
c93b5e71 7780
3b7b72ee 7781 genlmsg_end(msg, hdr);
c93b5e71
JC
7782
7783 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7784 nl80211_mlme_mcgrp.id, gfp);
7785 return;
7786
7787 nla_put_failure:
7788 genlmsg_cancel(msg, hdr);
7789 nlmsg_free(msg);
7790}
7791
a3b8b056
JM
7792void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
7793 struct net_device *netdev, const u8 *addr,
7794 enum nl80211_key_type key_type, int key_id,
e6d6e342 7795 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
7796{
7797 struct sk_buff *msg;
7798 void *hdr;
7799
e6d6e342 7800 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
7801 if (!msg)
7802 return;
7803
7804 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
7805 if (!hdr) {
7806 nlmsg_free(msg);
7807 return;
7808 }
7809
9360ffd1
DM
7810 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7811 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7812 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
7813 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
7814 (key_id != -1 &&
7815 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
7816 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
7817 goto nla_put_failure;
a3b8b056 7818
3b7b72ee 7819 genlmsg_end(msg, hdr);
a3b8b056 7820
463d0183
JB
7821 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7822 nl80211_mlme_mcgrp.id, gfp);
a3b8b056
JM
7823 return;
7824
7825 nla_put_failure:
7826 genlmsg_cancel(msg, hdr);
7827 nlmsg_free(msg);
7828}
7829
6bad8766
LR
7830void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
7831 struct ieee80211_channel *channel_before,
7832 struct ieee80211_channel *channel_after)
7833{
7834 struct sk_buff *msg;
7835 void *hdr;
7836 struct nlattr *nl_freq;
7837
fd2120ca 7838 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
7839 if (!msg)
7840 return;
7841
7842 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
7843 if (!hdr) {
7844 nlmsg_free(msg);
7845 return;
7846 }
7847
7848 /*
7849 * Since we are applying the beacon hint to a wiphy we know its
7850 * wiphy_idx is valid
7851 */
9360ffd1
DM
7852 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
7853 goto nla_put_failure;
6bad8766
LR
7854
7855 /* Before */
7856 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
7857 if (!nl_freq)
7858 goto nla_put_failure;
7859 if (nl80211_msg_put_channel(msg, channel_before))
7860 goto nla_put_failure;
7861 nla_nest_end(msg, nl_freq);
7862
7863 /* After */
7864 nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
7865 if (!nl_freq)
7866 goto nla_put_failure;
7867 if (nl80211_msg_put_channel(msg, channel_after))
7868 goto nla_put_failure;
7869 nla_nest_end(msg, nl_freq);
7870
3b7b72ee 7871 genlmsg_end(msg, hdr);
6bad8766 7872
463d0183
JB
7873 rcu_read_lock();
7874 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
7875 GFP_ATOMIC);
7876 rcu_read_unlock();
6bad8766
LR
7877
7878 return;
7879
7880nla_put_failure:
7881 genlmsg_cancel(msg, hdr);
7882 nlmsg_free(msg);
7883}
7884
9588bbd5
JM
7885static void nl80211_send_remain_on_chan_event(
7886 int cmd, struct cfg80211_registered_device *rdev,
7887 struct net_device *netdev, u64 cookie,
7888 struct ieee80211_channel *chan,
7889 enum nl80211_channel_type channel_type,
7890 unsigned int duration, gfp_t gfp)
7891{
7892 struct sk_buff *msg;
7893 void *hdr;
7894
7895 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7896 if (!msg)
7897 return;
7898
7899 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
7900 if (!hdr) {
7901 nlmsg_free(msg);
7902 return;
7903 }
7904
9360ffd1
DM
7905 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
7906 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
7907 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
7908 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) ||
7909 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie))
7910 goto nla_put_failure;
9588bbd5 7911
9360ffd1
DM
7912 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
7913 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
7914 goto nla_put_failure;
9588bbd5 7915
3b7b72ee 7916 genlmsg_end(msg, hdr);
9588bbd5
JM
7917
7918 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7919 nl80211_mlme_mcgrp.id, gfp);
7920 return;
7921
7922 nla_put_failure:
7923 genlmsg_cancel(msg, hdr);
7924 nlmsg_free(msg);
7925}
7926
7927void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev,
7928 struct net_device *netdev, u64 cookie,
7929 struct ieee80211_channel *chan,
7930 enum nl80211_channel_type channel_type,
7931 unsigned int duration, gfp_t gfp)
7932{
7933 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
7934 rdev, netdev, cookie, chan,
7935 channel_type, duration, gfp);
7936}
7937
7938void nl80211_send_remain_on_channel_cancel(
7939 struct cfg80211_registered_device *rdev, struct net_device *netdev,
7940 u64 cookie, struct ieee80211_channel *chan,
7941 enum nl80211_channel_type channel_type, gfp_t gfp)
7942{
7943 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
7944 rdev, netdev, cookie, chan,
7945 channel_type, 0, gfp);
7946}
7947
98b62183
JB
7948void nl80211_send_sta_event(struct cfg80211_registered_device *rdev,
7949 struct net_device *dev, const u8 *mac_addr,
7950 struct station_info *sinfo, gfp_t gfp)
7951{
7952 struct sk_buff *msg;
7953
7954 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7955 if (!msg)
7956 return;
7957
66266b3a
JL
7958 if (nl80211_send_station(msg, 0, 0, 0,
7959 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
7960 nlmsg_free(msg);
7961 return;
7962 }
7963
7964 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7965 nl80211_mlme_mcgrp.id, gfp);
7966}
7967
ec15e68b
JM
7968void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
7969 struct net_device *dev, const u8 *mac_addr,
7970 gfp_t gfp)
7971{
7972 struct sk_buff *msg;
7973 void *hdr;
7974
7975 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
7976 if (!msg)
7977 return;
7978
7979 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION);
7980 if (!hdr) {
7981 nlmsg_free(msg);
7982 return;
7983 }
7984
9360ffd1
DM
7985 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
7986 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
7987 goto nla_put_failure;
ec15e68b 7988
3b7b72ee 7989 genlmsg_end(msg, hdr);
ec15e68b
JM
7990
7991 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
7992 nl80211_mlme_mcgrp.id, gfp);
7993 return;
7994
7995 nla_put_failure:
7996 genlmsg_cancel(msg, hdr);
7997 nlmsg_free(msg);
7998}
7999
b92ab5d8
JB
8000static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
8001 const u8 *addr, gfp_t gfp)
28946da7
JB
8002{
8003 struct wireless_dev *wdev = dev->ieee80211_ptr;
8004 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
8005 struct sk_buff *msg;
8006 void *hdr;
8007 int err;
8008 u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid);
8009
8010 if (!nlpid)
8011 return false;
8012
8013 msg = nlmsg_new(100, gfp);
8014 if (!msg)
8015 return true;
8016
b92ab5d8 8017 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
8018 if (!hdr) {
8019 nlmsg_free(msg);
8020 return true;
8021 }
8022
9360ffd1
DM
8023 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8024 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
8025 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
8026 goto nla_put_failure;
28946da7
JB
8027
8028 err = genlmsg_end(msg, hdr);
8029 if (err < 0) {
8030 nlmsg_free(msg);
8031 return true;
8032 }
8033
8034 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
8035 return true;
8036
8037 nla_put_failure:
8038 genlmsg_cancel(msg, hdr);
8039 nlmsg_free(msg);
8040 return true;
8041}
8042
b92ab5d8
JB
8043bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp)
8044{
8045 return __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
8046 addr, gfp);
8047}
8048
8049bool nl80211_unexpected_4addr_frame(struct net_device *dev,
8050 const u8 *addr, gfp_t gfp)
8051{
8052 return __nl80211_unexpected_frame(dev,
8053 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
8054 addr, gfp);
8055}
8056
2e161f78
JB
8057int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
8058 struct net_device *netdev, u32 nlpid,
804483e9
JB
8059 int freq, int sig_dbm,
8060 const u8 *buf, size_t len, gfp_t gfp)
026331c4
JM
8061{
8062 struct sk_buff *msg;
8063 void *hdr;
026331c4
JM
8064
8065 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
8066 if (!msg)
8067 return -ENOMEM;
8068
2e161f78 8069 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
8070 if (!hdr) {
8071 nlmsg_free(msg);
8072 return -ENOMEM;
8073 }
8074
9360ffd1
DM
8075 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8076 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
8077 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
8078 (sig_dbm &&
8079 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
8080 nla_put(msg, NL80211_ATTR_FRAME, len, buf))
8081 goto nla_put_failure;
026331c4 8082
3b7b72ee 8083 genlmsg_end(msg, hdr);
026331c4 8084
3b7b72ee 8085 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
026331c4
JM
8086
8087 nla_put_failure:
8088 genlmsg_cancel(msg, hdr);
8089 nlmsg_free(msg);
8090 return -ENOBUFS;
8091}
8092
2e161f78
JB
8093void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev,
8094 struct net_device *netdev, u64 cookie,
8095 const u8 *buf, size_t len, bool ack,
8096 gfp_t gfp)
026331c4
JM
8097{
8098 struct sk_buff *msg;
8099 void *hdr;
8100
8101 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
8102 if (!msg)
8103 return;
8104
2e161f78 8105 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
8106 if (!hdr) {
8107 nlmsg_free(msg);
8108 return;
8109 }
8110
9360ffd1
DM
8111 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8112 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
8113 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
8114 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
8115 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
8116 goto nla_put_failure;
026331c4 8117
3b7b72ee 8118 genlmsg_end(msg, hdr);
026331c4
JM
8119
8120 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
8121 return;
8122
8123 nla_put_failure:
8124 genlmsg_cancel(msg, hdr);
8125 nlmsg_free(msg);
8126}
8127
d6dc1a38
JO
8128void
8129nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
8130 struct net_device *netdev,
8131 enum nl80211_cqm_rssi_threshold_event rssi_event,
8132 gfp_t gfp)
8133{
8134 struct sk_buff *msg;
8135 struct nlattr *pinfoattr;
8136 void *hdr;
8137
8138 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8139 if (!msg)
8140 return;
8141
8142 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
8143 if (!hdr) {
8144 nlmsg_free(msg);
8145 return;
8146 }
8147
9360ffd1
DM
8148 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8149 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
8150 goto nla_put_failure;
d6dc1a38
JO
8151
8152 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
8153 if (!pinfoattr)
8154 goto nla_put_failure;
8155
9360ffd1
DM
8156 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
8157 rssi_event))
8158 goto nla_put_failure;
d6dc1a38
JO
8159
8160 nla_nest_end(msg, pinfoattr);
8161
3b7b72ee 8162 genlmsg_end(msg, hdr);
d6dc1a38
JO
8163
8164 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8165 nl80211_mlme_mcgrp.id, gfp);
8166 return;
8167
8168 nla_put_failure:
8169 genlmsg_cancel(msg, hdr);
8170 nlmsg_free(msg);
8171}
8172
e5497d76
JB
8173void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
8174 struct net_device *netdev, const u8 *bssid,
8175 const u8 *replay_ctr, gfp_t gfp)
8176{
8177 struct sk_buff *msg;
8178 struct nlattr *rekey_attr;
8179 void *hdr;
8180
8181 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8182 if (!msg)
8183 return;
8184
8185 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
8186 if (!hdr) {
8187 nlmsg_free(msg);
8188 return;
8189 }
8190
9360ffd1
DM
8191 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8192 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
8193 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
8194 goto nla_put_failure;
e5497d76
JB
8195
8196 rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
8197 if (!rekey_attr)
8198 goto nla_put_failure;
8199
9360ffd1
DM
8200 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
8201 NL80211_REPLAY_CTR_LEN, replay_ctr))
8202 goto nla_put_failure;
e5497d76
JB
8203
8204 nla_nest_end(msg, rekey_attr);
8205
3b7b72ee 8206 genlmsg_end(msg, hdr);
e5497d76
JB
8207
8208 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8209 nl80211_mlme_mcgrp.id, gfp);
8210 return;
8211
8212 nla_put_failure:
8213 genlmsg_cancel(msg, hdr);
8214 nlmsg_free(msg);
8215}
8216
c9df56b4
JM
8217void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8218 struct net_device *netdev, int index,
8219 const u8 *bssid, bool preauth, gfp_t gfp)
8220{
8221 struct sk_buff *msg;
8222 struct nlattr *attr;
8223 void *hdr;
8224
8225 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8226 if (!msg)
8227 return;
8228
8229 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
8230 if (!hdr) {
8231 nlmsg_free(msg);
8232 return;
8233 }
8234
9360ffd1
DM
8235 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8236 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
8237 goto nla_put_failure;
c9df56b4
JM
8238
8239 attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
8240 if (!attr)
8241 goto nla_put_failure;
8242
9360ffd1
DM
8243 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
8244 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
8245 (preauth &&
8246 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
8247 goto nla_put_failure;
c9df56b4
JM
8248
8249 nla_nest_end(msg, attr);
8250
3b7b72ee 8251 genlmsg_end(msg, hdr);
c9df56b4
JM
8252
8253 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8254 nl80211_mlme_mcgrp.id, gfp);
8255 return;
8256
8257 nla_put_failure:
8258 genlmsg_cancel(msg, hdr);
8259 nlmsg_free(msg);
8260}
8261
5314526b
TP
8262void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8263 struct net_device *netdev, int freq,
8264 enum nl80211_channel_type type, gfp_t gfp)
8265{
8266 struct sk_buff *msg;
8267 void *hdr;
8268
8269 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8270 if (!msg)
8271 return;
8272
8273 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY);
8274 if (!hdr) {
8275 nlmsg_free(msg);
8276 return;
8277 }
8278
7eab0f64
JL
8279 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
8280 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
8281 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type))
8282 goto nla_put_failure;
5314526b
TP
8283
8284 genlmsg_end(msg, hdr);
8285
8286 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8287 nl80211_mlme_mcgrp.id, gfp);
8288 return;
8289
8290 nla_put_failure:
8291 genlmsg_cancel(msg, hdr);
8292 nlmsg_free(msg);
8293}
8294
c063dbf5
JB
8295void
8296nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
8297 struct net_device *netdev, const u8 *peer,
8298 u32 num_packets, gfp_t gfp)
8299{
8300 struct sk_buff *msg;
8301 struct nlattr *pinfoattr;
8302 void *hdr;
8303
8304 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8305 if (!msg)
8306 return;
8307
8308 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
8309 if (!hdr) {
8310 nlmsg_free(msg);
8311 return;
8312 }
8313
9360ffd1
DM
8314 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8315 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
8316 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer))
8317 goto nla_put_failure;
c063dbf5
JB
8318
8319 pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM);
8320 if (!pinfoattr)
8321 goto nla_put_failure;
8322
9360ffd1
DM
8323 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
8324 goto nla_put_failure;
c063dbf5
JB
8325
8326 nla_nest_end(msg, pinfoattr);
8327
3b7b72ee 8328 genlmsg_end(msg, hdr);
c063dbf5
JB
8329
8330 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8331 nl80211_mlme_mcgrp.id, gfp);
8332 return;
8333
8334 nla_put_failure:
8335 genlmsg_cancel(msg, hdr);
8336 nlmsg_free(msg);
8337}
8338
7f6cf311
JB
8339void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
8340 u64 cookie, bool acked, gfp_t gfp)
8341{
8342 struct wireless_dev *wdev = dev->ieee80211_ptr;
8343 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
8344 struct sk_buff *msg;
8345 void *hdr;
8346 int err;
8347
8348 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
8349 if (!msg)
8350 return;
8351
8352 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
8353 if (!hdr) {
8354 nlmsg_free(msg);
8355 return;
8356 }
8357
9360ffd1
DM
8358 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8359 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
8360 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
8361 nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) ||
8362 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
8363 goto nla_put_failure;
7f6cf311
JB
8364
8365 err = genlmsg_end(msg, hdr);
8366 if (err < 0) {
8367 nlmsg_free(msg);
8368 return;
8369 }
8370
8371 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
8372 nl80211_mlme_mcgrp.id, gfp);
8373 return;
8374
8375 nla_put_failure:
8376 genlmsg_cancel(msg, hdr);
8377 nlmsg_free(msg);
8378}
8379EXPORT_SYMBOL(cfg80211_probe_status);
8380
5e760230
JB
8381void cfg80211_report_obss_beacon(struct wiphy *wiphy,
8382 const u8 *frame, size_t len,
804483e9 8383 int freq, int sig_dbm, gfp_t gfp)
5e760230
JB
8384{
8385 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
8386 struct sk_buff *msg;
8387 void *hdr;
8388 u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid);
8389
8390 if (!nlpid)
8391 return;
8392
8393 msg = nlmsg_new(len + 100, gfp);
8394 if (!msg)
8395 return;
8396
8397 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
8398 if (!hdr) {
8399 nlmsg_free(msg);
8400 return;
8401 }
8402
9360ffd1
DM
8403 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
8404 (freq &&
8405 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
8406 (sig_dbm &&
8407 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
8408 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
8409 goto nla_put_failure;
5e760230
JB
8410
8411 genlmsg_end(msg, hdr);
8412
8413 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
8414 return;
8415
8416 nla_put_failure:
8417 genlmsg_cancel(msg, hdr);
8418 nlmsg_free(msg);
8419}
8420EXPORT_SYMBOL(cfg80211_report_obss_beacon);
8421
026331c4
JM
8422static int nl80211_netlink_notify(struct notifier_block * nb,
8423 unsigned long state,
8424 void *_notify)
8425{
8426 struct netlink_notify *notify = _notify;
8427 struct cfg80211_registered_device *rdev;
8428 struct wireless_dev *wdev;
8429
8430 if (state != NETLINK_URELEASE)
8431 return NOTIFY_DONE;
8432
8433 rcu_read_lock();
8434
5e760230 8435 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
026331c4 8436 list_for_each_entry_rcu(wdev, &rdev->netdev_list, list)
2e161f78 8437 cfg80211_mlme_unregister_socket(wdev, notify->pid);
5e760230
JB
8438 if (rdev->ap_beacons_nlpid == notify->pid)
8439 rdev->ap_beacons_nlpid = 0;
8440 }
026331c4
JM
8441
8442 rcu_read_unlock();
8443
8444 return NOTIFY_DONE;
8445}
8446
8447static struct notifier_block nl80211_netlink_notifier = {
8448 .notifier_call = nl80211_netlink_notify,
8449};
8450
55682965
JB
8451/* initialisation/exit functions */
8452
8453int nl80211_init(void)
8454{
0d63cbb5 8455 int err;
55682965 8456
0d63cbb5
MM
8457 err = genl_register_family_with_ops(&nl80211_fam,
8458 nl80211_ops, ARRAY_SIZE(nl80211_ops));
55682965
JB
8459 if (err)
8460 return err;
8461
55682965
JB
8462 err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
8463 if (err)
8464 goto err_out;
8465
2a519311
JB
8466 err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp);
8467 if (err)
8468 goto err_out;
8469
73d54c9e
LR
8470 err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp);
8471 if (err)
8472 goto err_out;
8473
6039f6d2
JM
8474 err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp);
8475 if (err)
8476 goto err_out;
8477
aff89a9b
JB
8478#ifdef CONFIG_NL80211_TESTMODE
8479 err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp);
8480 if (err)
8481 goto err_out;
8482#endif
8483
026331c4
JM
8484 err = netlink_register_notifier(&nl80211_netlink_notifier);
8485 if (err)
8486 goto err_out;
8487
55682965
JB
8488 return 0;
8489 err_out:
8490 genl_unregister_family(&nl80211_fam);
8491 return err;
8492}
8493
8494void nl80211_exit(void)
8495{
026331c4 8496 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
8497 genl_unregister_family(&nl80211_fam);
8498}