nl80211: Add support to configure TID specific AMPDU configuration
[linux-block.git] / net / wireless / nl80211.c
CommitLineData
457c8996 1// SPDX-License-Identifier: GPL-2.0-only
55682965
JB
2/*
3 * This is the new netlink-based wireless configuration interface.
4 *
026331c4 5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
2740f0cf 6 * Copyright 2013-2014 Intel Mobile Communications GmbH
66cd794e 7 * Copyright 2015-2017 Intel Deutschland GmbH
55c1fdf0 8 * Copyright (C) 2018-2019 Intel Corporation
55682965
JB
9 */
10
11#include <linux/if.h>
12#include <linux/module.h>
13#include <linux/err.h>
5a0e3ad6 14#include <linux/slab.h>
55682965
JB
15#include <linux/list.h>
16#include <linux/if_ether.h>
17#include <linux/ieee80211.h>
18#include <linux/nl80211.h>
19#include <linux/rtnetlink.h>
20#include <linux/netlink.h>
259d8c1e 21#include <linux/nospec.h>
2a519311 22#include <linux/etherdevice.h>
463d0183 23#include <net/net_namespace.h>
55682965
JB
24#include <net/genetlink.h>
25#include <net/cfg80211.h>
463d0183 26#include <net/sock.h>
2a0e047e 27#include <net/inet_connection_sock.h>
55682965
JB
28#include "core.h"
29#include "nl80211.h"
b2e1b302 30#include "reg.h"
e35e4d28 31#include "rdev-ops.h"
55682965 32
5fb628e9
JM
33static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
34 struct genl_info *info,
35 struct cfg80211_crypto_settings *settings,
36 int cipher_limit);
37
55682965 38/* the netlink family */
489111e5 39static struct genl_family nl80211_fam;
55682965 40
2a94fe48
JB
41/* multicast groups */
42enum nl80211_multicast_groups {
43 NL80211_MCGRP_CONFIG,
44 NL80211_MCGRP_SCAN,
45 NL80211_MCGRP_REGULATORY,
46 NL80211_MCGRP_MLME,
567ffc35 47 NL80211_MCGRP_VENDOR,
50bcd31d 48 NL80211_MCGRP_NAN,
2a94fe48
JB
49 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
50};
51
52static const struct genl_multicast_group nl80211_mcgrps[] = {
71b836ec
JB
53 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
54 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
55 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
56 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
57 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
50bcd31d 58 [NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
2a94fe48 59#ifdef CONFIG_NL80211_TESTMODE
71b836ec 60 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
2a94fe48
JB
61#endif
62};
63
89a54e48
JB
64/* returns ERR_PTR values */
65static struct wireless_dev *
66__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
55682965 67{
89a54e48
JB
68 struct cfg80211_registered_device *rdev;
69 struct wireless_dev *result = NULL;
70 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
71 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
72 u64 wdev_id;
73 int wiphy_idx = -1;
74 int ifidx = -1;
55682965 75
5fe231e8 76 ASSERT_RTNL();
55682965 77
89a54e48
JB
78 if (!have_ifidx && !have_wdev_id)
79 return ERR_PTR(-EINVAL);
55682965 80
89a54e48
JB
81 if (have_ifidx)
82 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
83 if (have_wdev_id) {
84 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
85 wiphy_idx = wdev_id >> 32;
55682965
JB
86 }
87
89a54e48
JB
88 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
89 struct wireless_dev *wdev;
90
91 if (wiphy_net(&rdev->wiphy) != netns)
92 continue;
93
94 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
95 continue;
96
53873f13 97 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
89a54e48
JB
98 if (have_ifidx && wdev->netdev &&
99 wdev->netdev->ifindex == ifidx) {
100 result = wdev;
101 break;
102 }
103 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
104 result = wdev;
105 break;
106 }
107 }
89a54e48
JB
108
109 if (result)
110 break;
111 }
112
113 if (result)
114 return result;
115 return ERR_PTR(-ENODEV);
55682965
JB
116}
117
a9455408 118static struct cfg80211_registered_device *
878d9ec7 119__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 120{
7fee4778
JB
121 struct cfg80211_registered_device *rdev = NULL, *tmp;
122 struct net_device *netdev;
a9455408 123
5fe231e8 124 ASSERT_RTNL();
a9455408 125
878d9ec7 126 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
127 !attrs[NL80211_ATTR_IFINDEX] &&
128 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
129 return ERR_PTR(-EINVAL);
130
878d9ec7 131 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 132 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 133 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 134
89a54e48
JB
135 if (attrs[NL80211_ATTR_WDEV]) {
136 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
137 struct wireless_dev *wdev;
138 bool found = false;
139
140 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
141 if (tmp) {
142 /* make sure wdev exists */
53873f13 143 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
89a54e48
JB
144 if (wdev->identifier != (u32)wdev_id)
145 continue;
146 found = true;
147 break;
148 }
89a54e48
JB
149
150 if (!found)
151 tmp = NULL;
152
153 if (rdev && tmp != rdev)
154 return ERR_PTR(-EINVAL);
155 rdev = tmp;
156 }
157 }
158
878d9ec7
JB
159 if (attrs[NL80211_ATTR_IFINDEX]) {
160 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7a087e74 161
7f2b8562 162 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
163 if (netdev) {
164 if (netdev->ieee80211_ptr)
f26cbf40
ZG
165 tmp = wiphy_to_rdev(
166 netdev->ieee80211_ptr->wiphy);
7fee4778
JB
167 else
168 tmp = NULL;
169
7fee4778
JB
170 /* not wireless device -- return error */
171 if (!tmp)
172 return ERR_PTR(-EINVAL);
173
174 /* mismatch -- return error */
175 if (rdev && tmp != rdev)
176 return ERR_PTR(-EINVAL);
177
178 rdev = tmp;
a9455408 179 }
a9455408 180 }
a9455408 181
4f7eff10
JB
182 if (!rdev)
183 return ERR_PTR(-ENODEV);
a9455408 184
4f7eff10
JB
185 if (netns != wiphy_net(&rdev->wiphy))
186 return ERR_PTR(-ENODEV);
187
188 return rdev;
a9455408
JB
189}
190
191/*
192 * This function returns a pointer to the driver
193 * that the genl_info item that is passed refers to.
a9455408
JB
194 *
195 * The result of this can be a PTR_ERR and hence must
196 * be checked with IS_ERR() for errors.
197 */
198static struct cfg80211_registered_device *
4f7eff10 199cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 200{
5fe231e8 201 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
202}
203
f88eb7c0
JB
204static int validate_beacon_head(const struct nlattr *attr,
205 struct netlink_ext_ack *extack)
206{
207 const u8 *data = nla_data(attr);
208 unsigned int len = nla_len(attr);
209 const struct element *elem;
210 const struct ieee80211_mgmt *mgmt = (void *)data;
211 unsigned int fixedlen = offsetof(struct ieee80211_mgmt,
212 u.beacon.variable);
213
214 if (len < fixedlen)
215 goto err;
216
217 if (ieee80211_hdrlen(mgmt->frame_control) !=
218 offsetof(struct ieee80211_mgmt, u.beacon))
219 goto err;
220
221 data += fixedlen;
222 len -= fixedlen;
223
224 for_each_element(elem, data, len) {
225 /* nothing */
226 }
227
228 if (for_each_element_completed(elem, data, len))
229 return 0;
230
231err:
232 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
233 return -EINVAL;
234}
235
3d7af878
JB
236static int validate_ie_attr(const struct nlattr *attr,
237 struct netlink_ext_ack *extack)
238{
9f308616
JB
239 const u8 *data = nla_data(attr);
240 unsigned int len = nla_len(attr);
7388afe0 241 const struct element *elem;
3d7af878 242
9f308616
JB
243 for_each_element(elem, data, len) {
244 /* nothing */
3d7af878
JB
245 }
246
9f308616
JB
247 if (for_each_element_completed(elem, data, len))
248 return 0;
249
3d7af878
JB
250 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed information elements");
251 return -EINVAL;
252}
253
55682965 254/* policy for the attributes */
81e54d08
PKC
255static const struct nla_policy
256nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
257 [NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
258 [NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
259 .len = U8_MAX },
260 [NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
261 .len = U8_MAX },
262};
263
9bb7e0f2
JB
264static const struct nla_policy
265nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
266 [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
267 [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
268 [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
269 NLA_POLICY_MAX(NLA_U8, 15),
270 [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
271 [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
272 NLA_POLICY_MAX(NLA_U8, 15),
273 [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
ea18709a 274 NLA_POLICY_MAX(NLA_U8, 31),
9bb7e0f2
JB
275 [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
276 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
277 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
278};
279
280static const struct nla_policy
281nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
282 [NL80211_PMSR_TYPE_FTM] =
23323289 283 NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
9bb7e0f2
JB
284};
285
286static const struct nla_policy
287nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
288 [NL80211_PMSR_REQ_ATTR_DATA] =
23323289 289 NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
9bb7e0f2
JB
290 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
291};
292
293static const struct nla_policy
294nl80211_psmr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
295 [NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
296 /*
297 * we could specify this again to be the top-level policy,
298 * but that would open us up to recursion problems ...
299 */
300 [NL80211_PMSR_PEER_ATTR_CHAN] = { .type = NLA_NESTED },
301 [NL80211_PMSR_PEER_ATTR_REQ] =
23323289 302 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
9bb7e0f2
JB
303 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
304};
305
306static const struct nla_policy
307nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
308 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
309 [NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
310 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
311 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
312 [NL80211_PMSR_ATTR_PEERS] =
23323289 313 NLA_POLICY_NESTED_ARRAY(nl80211_psmr_peer_attr_policy),
9bb7e0f2
JB
314};
315
796e90f4
JC
316static const struct nla_policy
317he_obss_pd_policy[NL80211_HE_OBSS_PD_ATTR_MAX + 1] = {
318 [NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] =
319 NLA_POLICY_RANGE(NLA_U8, 1, 20),
320 [NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET] =
321 NLA_POLICY_RANGE(NLA_U8, 1, 20),
322};
323
5c5e52d1
JC
324static const struct nla_policy
325he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
326 [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63),
327 [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG },
328 [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
329};
330
77f576de
T
331static const struct nla_policy
332nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
3710a8a6
JB
333 [NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
334 [NL80211_TID_CONFIG_ATTR_PEER_SUPP] = { .type = NLA_U64 },
77f576de 335 [NL80211_TID_CONFIG_ATTR_OVERRIDE] = { .type = NLA_FLAG },
3710a8a6 336 [NL80211_TID_CONFIG_ATTR_TIDS] = NLA_POLICY_RANGE(NLA_U16, 1, 0xff),
77f576de
T
337 [NL80211_TID_CONFIG_ATTR_NOACK] =
338 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
6a21d16c
T
339 [NL80211_TID_CONFIG_ATTR_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
340 [NL80211_TID_CONFIG_ATTR_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
ade274b2
T
341 [NL80211_TID_CONFIG_ATTR_AMPDU_CTRL] =
342 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
77f576de
T
343};
344
9bb7e0f2 345const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
6d4dd4ef 346 [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
55682965
JB
347 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
348 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 349 .len = 20-1 },
31888487 350 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 351
72bdcf34 352 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 353 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
2a38075c
AAL
354 [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
355 NL80211_EDMG_CHANNELS_MIN,
356 NL80211_EDMG_CHANNELS_MAX),
357 [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
358 NL80211_EDMG_BW_CONFIG_MIN,
359 NL80211_EDMG_BW_CONFIG_MAX),
360
3d9d1d66
JB
361 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
362 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
363 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
364
ab0d76f6
JB
365 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
366 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
b9a5f8ca
JM
367 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
368 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 369 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 370 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965 371
ab0d76f6 372 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
55682965
JB
373 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
374 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 375
1a28ed21
JB
376 [NL80211_ATTR_MAC] = { .type = NLA_EXACT_LEN_WARN, .len = ETH_ALEN },
377 [NL80211_ATTR_PREV_BSSID] = {
378 .type = NLA_EXACT_LEN_WARN,
379 .len = ETH_ALEN
380 },
41ade00f 381
b9454e83 382 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
383 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
384 .len = WLAN_MAX_KEY_LEN },
56be393f 385 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
41ade00f
JB
386 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
387 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 388 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
ab0d76f6
JB
389 [NL80211_ATTR_KEY_TYPE] =
390 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
ed1b6cc7
JB
391
392 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
393 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
f88eb7c0
JB
394 [NL80211_ATTR_BEACON_HEAD] =
395 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
396 IEEE80211_MAX_DATA_LEN),
3d7af878
JB
397 [NL80211_ATTR_BEACON_TAIL] =
398 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
399 IEEE80211_MAX_DATA_LEN),
ab0d76f6
JB
400 [NL80211_ATTR_STA_AID] =
401 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
5727ef1b
JB
402 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
403 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
404 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
405 .len = NL80211_MAX_SUPP_RATES },
ab0d76f6
JB
406 [NL80211_ATTR_STA_PLINK_ACTION] =
407 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
e96d1cd2
ARN
408 [NL80211_ATTR_STA_TX_POWER_SETTING] =
409 NLA_POLICY_RANGE(NLA_U8,
410 NL80211_TX_POWER_AUTOMATIC,
411 NL80211_TX_POWER_FIXED),
412 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
5727ef1b 413 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 414 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 415 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 416 .len = IEEE80211_MAX_MESH_ID_LEN },
1fab1b89 417 [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
9f1ba906 418
b2e1b302
LR
419 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
420 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
421
9f1ba906
JM
422 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
423 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
424 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
425 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
426 .len = NL80211_MAX_SUPP_RATES },
50b12f59 427 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 428
24bdd9f4 429 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 430 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 431
1a28ed21
JB
432 [NL80211_ATTR_HT_CAPABILITY] = {
433 .type = NLA_EXACT_LEN_WARN,
434 .len = NL80211_HT_CAPABILITY_LEN
435 },
9aed3cc1
JM
436
437 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
3d7af878
JB
438 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
439 validate_ie_attr,
440 IEEE80211_MAX_DATA_LEN),
2a519311
JB
441 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
442 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
443
444 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
445 .len = IEEE80211_MAX_SSID_LEN },
446 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
447 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 448 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 449 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
ab0d76f6
JB
450 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
451 NL80211_MFP_NO,
452 NL80211_MFP_OPTIONAL),
eccb8e8f
JB
453 [NL80211_ATTR_STA_FLAGS2] = {
454 .len = sizeof(struct nl80211_sta_flag_update),
455 },
3f77316c 456 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
457 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
458 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
64bf3d4b 459 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
b23aa676 460 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
ea750801 461 [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
b23aa676
SO
462 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
463 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 464 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 465 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
1a28ed21
JB
466 [NL80211_ATTR_PMKID] = {
467 .type = NLA_EXACT_LEN_WARN,
468 .len = WLAN_PMKID_LEN
469 },
9588bbd5
JM
470 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
471 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 472 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
473 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
474 .len = IEEE80211_MAX_DATA_LEN },
475 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ab0d76f6
JB
476 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
477 NL80211_PS_DISABLED,
478 NL80211_PS_ENABLED),
d6dc1a38 479 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 480 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 481 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
482 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
483 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 484 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
485 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
486 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 487 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 488 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 489 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 490 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
ab0d76f6
JB
491 [NL80211_ATTR_STA_PLINK_STATE] =
492 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
493 [NL80211_ATTR_MESH_PEER_AID] =
494 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
bbe6ad6d 495 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 496 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 497 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
ab0d76f6
JB
498 [NL80211_ATTR_HIDDEN_SSID] =
499 NLA_POLICY_RANGE(NLA_U32,
500 NL80211_HIDDEN_SSID_NOT_IN_USE,
501 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
3d7af878
JB
502 [NL80211_ATTR_IE_PROBE_RESP] =
503 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
504 IEEE80211_MAX_DATA_LEN),
505 [NL80211_ATTR_IE_ASSOC_RESP] =
506 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
507 IEEE80211_MAX_DATA_LEN),
f4b34b55 508 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 509 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 510 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
511 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
512 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
513 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
514 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
515 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 516 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 517 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
518 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
519 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 520 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
521 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
522 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
523 .len = NL80211_HT_CAPABILITY_LEN
524 },
1d9d9213 525 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 526 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 527 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 528 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 529 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
11b6b5a4 530 [NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
1a28ed21
JB
531 [NL80211_ATTR_VHT_CAPABILITY] = {
532 .type = NLA_EXACT_LEN_WARN,
533 .len = NL80211_VHT_CAPABILITY_LEN
534 },
ed473771 535 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
ab0d76f6
JB
536 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
537 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
538 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
539 NLA_POLICY_RANGE(NLA_U32,
540 NL80211_MESH_POWER_UNKNOWN + 1,
541 NL80211_MESH_POWER_MAX),
77765eaf
VT
542 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
543 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
544 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
545 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 546 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
547 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
548 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
549 .len = NL80211_VHT_CAPABILITY_LEN,
550 },
355199e0
JM
551 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
552 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
553 .len = IEEE80211_MAX_DATA_LEN },
ab0d76f6
JB
554 [NL80211_ATTR_PEER_AID] =
555 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
16ef1fe2
SW
556 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
557 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
558 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
9a774c78
AO
559 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
560 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
c01fc9ad
SD
561 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
562 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
5336fa88 563 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 564 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
565 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
566 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
567 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
fa9ffc74
KP
568 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
569 .len = IEEE80211_QOS_MAP_LEN_MAX },
1a28ed21
JB
570 [NL80211_ATTR_MAC_HINT] = {
571 .type = NLA_EXACT_LEN_WARN,
572 .len = ETH_ALEN
573 },
1df4a510 574 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 575 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 576 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 577 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 578 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
ab0d76f6
JB
579 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
580 [NL80211_ATTR_USER_PRIO] =
581 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
960d01ac 582 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 583 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
1a28ed21
JB
584 [NL80211_ATTR_MAC_MASK] = {
585 .type = NLA_EXACT_LEN_WARN,
586 .len = ETH_ALEN
587 },
1bdd716c 588 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 589 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 590 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 591 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 592 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 593 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
ab0d76f6
JB
594 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
595 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
c6e6a0c8
AE
596 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
597 .len = VHT_MUMIMO_GROUPS_DATA_LEN
598 },
1a28ed21
JB
599 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = {
600 .type = NLA_EXACT_LEN_WARN,
601 .len = ETH_ALEN
602 },
ab0d76f6 603 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
8585989d 604 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
a442b761 605 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
348bd456
JM
606 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
607 .len = FILS_MAX_KEK_LEN },
1a28ed21
JB
608 [NL80211_ATTR_FILS_NONCES] = {
609 .type = NLA_EXACT_LEN_WARN,
610 .len = 2 * FILS_NONCE_LEN
611 },
ce0ce13a 612 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
1a28ed21 613 [NL80211_ATTR_BSSID] = { .type = NLA_EXACT_LEN_WARN, .len = ETH_ALEN },
bf95ecdb 614 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
615 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
616 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
617 },
3093ebbe 618 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
a3caf744
VK
619 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
620 .len = FILS_ERP_MAX_USERNAME_LEN },
621 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
622 .len = FILS_ERP_MAX_REALM_LEN },
623 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
624 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
625 .len = FILS_ERP_MAX_RRK_LEN },
1a28ed21 626 [NL80211_ATTR_FILS_CACHE_ID] = { .type = NLA_EXACT_LEN_WARN, .len = 2 },
a3caf744 627 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
ca986ad9 628 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
40cbfa90 629 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
52539ca8
THJ
630
631 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
632 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
633 [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
c4cbaf79
LC
634 [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
635 .len = NL80211_HE_MAX_CAPABILITY_LEN },
81e54d08
PKC
636
637 [NL80211_ATTR_FTM_RESPONDER] = {
638 .type = NLA_NESTED,
639 .validation_data = nl80211_ftm_responder_policy,
640 },
9bb7e0f2
JB
641 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
642 [NL80211_ATTR_PEER_MEASUREMENTS] =
23323289 643 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
36647055 644 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
26f7044e
CHH
645 [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
646 .len = SAE_PASSWORD_MAX_LEN },
a0de1ca3 647 [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
796e90f4 648 [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
14f34e36 649 [NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
5c5e52d1 650 [NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
77f576de
T
651 [NL80211_ATTR_TID_CONFIG] =
652 NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
55682965
JB
653};
654
e31b8213 655/* policy for the key attributes */
b54452b0 656static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 657 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
658 [NL80211_KEY_IDX] = { .type = NLA_U8 },
659 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 660 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
661 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
662 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
ab0d76f6 663 [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
dbd2fd65 664 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
6cdd3979 665 [NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
dbd2fd65
JB
666};
667
668/* policy for the key default flags */
669static const struct nla_policy
670nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
671 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
672 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
673};
674
f83ace3b 675#ifdef CONFIG_PM
ff1b6e69
JB
676/* policy for WoWLAN attributes */
677static const struct nla_policy
678nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
679 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
680 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
681 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
682 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
683 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
684 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
685 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
686 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 687 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 688 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
689};
690
691static const struct nla_policy
692nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
693 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
694 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
1a28ed21
JB
695 [NL80211_WOWLAN_TCP_DST_MAC] = {
696 .type = NLA_EXACT_LEN_WARN,
697 .len = ETH_ALEN
698 },
2a0e047e
JB
699 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
700 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
1a28ed21 701 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .type = NLA_MIN_LEN, .len = 1 },
2a0e047e
JB
702 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
703 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
704 },
705 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
706 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
707 },
708 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
1a28ed21
JB
709 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .type = NLA_MIN_LEN, .len = 1 },
710 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .type = NLA_MIN_LEN, .len = 1 },
ff1b6e69 711};
f83ace3b 712#endif /* CONFIG_PM */
ff1b6e69 713
be29b99a
AK
714/* policy for coalesce rule attributes */
715static const struct nla_policy
716nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
717 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
ab0d76f6
JB
718 [NL80211_ATTR_COALESCE_RULE_CONDITION] =
719 NLA_POLICY_RANGE(NLA_U32,
720 NL80211_COALESCE_CONDITION_MATCH,
721 NL80211_COALESCE_CONDITION_NO_MATCH),
be29b99a
AK
722 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
723};
724
e5497d76
JB
725/* policy for GTK rekey offload attributes */
726static const struct nla_policy
727nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
180aa422
JB
728 [NL80211_REKEY_DATA_KEK] = {
729 .type = NLA_EXACT_LEN_WARN,
730 .len = NL80211_KEK_LEN,
731 },
732 [NL80211_REKEY_DATA_KCK] = {
733 .type = NLA_EXACT_LEN_WARN,
734 .len = NL80211_KCK_LEN,
735 },
1a28ed21
JB
736 [NL80211_REKEY_DATA_REPLAY_CTR] = {
737 .type = NLA_EXACT_LEN_WARN,
738 .len = NL80211_REPLAY_CTR_LEN
739 },
e5497d76
JB
740};
741
1e1b11b6 742static const struct nla_policy
743nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
744 [NL80211_BAND_2GHZ] = { .type = NLA_S32 },
745 [NL80211_BAND_5GHZ] = { .type = NLA_S32 },
e548a1c3 746 [NL80211_BAND_6GHZ] = { .type = NLA_S32 },
1e1b11b6 747 [NL80211_BAND_60GHZ] = { .type = NLA_S32 },
748};
749
a1f1c21c
LC
750static const struct nla_policy
751nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 752 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 753 .len = IEEE80211_MAX_SSID_LEN },
1a28ed21
JB
754 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = {
755 .type = NLA_EXACT_LEN_WARN,
756 .len = ETH_ALEN
757 },
88e920b4 758 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
1e1b11b6 759 [NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
760 NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
a1f1c21c
LC
761};
762
3b06d277
AS
763static const struct nla_policy
764nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
765 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
766 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
767};
768
38de03d2
AS
769static const struct nla_policy
770nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
771 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
772 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
773 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
774 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
775 },
776};
777
a442b761
AB
778/* policy for NAN function attributes */
779static const struct nla_policy
780nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
781 [NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 },
0a27844c 782 [NL80211_NAN_FUNC_SERVICE_ID] = {
a442b761
AB
783 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
784 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
785 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
786 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
787 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
788 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
1a28ed21
JB
789 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = {
790 .type = NLA_EXACT_LEN_WARN,
791 .len = ETH_ALEN
792 },
a442b761
AB
793 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
794 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
795 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
796 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
797 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
798 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
799 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
800 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
801 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
802};
803
804/* policy for Service Response Filter attributes */
805static const struct nla_policy
806nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
807 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
808 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
809 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
810 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
811 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
812};
813
ad670233
PX
814/* policy for packet pattern attributes */
815static const struct nla_policy
816nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
817 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
818 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
819 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
820};
821
9bb7e0f2
JB
822int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
823 struct cfg80211_registered_device **rdev,
824 struct wireless_dev **wdev)
a043897a 825{
97990a06 826 int err;
a043897a 827
97990a06 828 if (!cb->args[0]) {
50508d94
JB
829 struct nlattr **attrbuf;
830
831 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
832 GFP_KERNEL);
833 if (!attrbuf)
834 return -ENOMEM;
835
8cb08174
JB
836 err = nlmsg_parse_deprecated(cb->nlh,
837 GENL_HDRLEN + nl80211_fam.hdrsize,
50508d94 838 attrbuf, nl80211_fam.maxattr,
8cb08174 839 nl80211_policy, NULL);
50508d94
JB
840 if (err) {
841 kfree(attrbuf);
ea90e0dc 842 return err;
50508d94 843 }
67748893 844
50508d94
JB
845 *wdev = __cfg80211_wdev_from_attrs(sock_net(cb->skb->sk),
846 attrbuf);
847 kfree(attrbuf);
ea90e0dc
JB
848 if (IS_ERR(*wdev))
849 return PTR_ERR(*wdev);
f26cbf40 850 *rdev = wiphy_to_rdev((*wdev)->wiphy);
c319d50b
JB
851 /* 0 is the first index - add 1 to parse only once */
852 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
853 cb->args[1] = (*wdev)->identifier;
854 } else {
c319d50b
JB
855 /* subtract the 1 again here */
856 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 857 struct wireless_dev *tmp;
67748893 858
ea90e0dc
JB
859 if (!wiphy)
860 return -ENODEV;
f26cbf40 861 *rdev = wiphy_to_rdev(wiphy);
97990a06 862 *wdev = NULL;
67748893 863
53873f13 864 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
865 if (tmp->identifier == cb->args[1]) {
866 *wdev = tmp;
867 break;
868 }
869 }
67748893 870
ea90e0dc
JB
871 if (!*wdev)
872 return -ENODEV;
67748893
JB
873 }
874
67748893 875 return 0;
67748893
JB
876}
877
55682965 878/* message building helper */
9bb7e0f2
JB
879void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
880 int flags, u8 cmd)
55682965
JB
881{
882 /* since there is no private header just add the generic one */
15e47304 883 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
884}
885
50f32718
HD
886static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
887 const struct ieee80211_reg_rule *rule)
888{
889 int j;
890 struct nlattr *nl_wmm_rules =
ae0be8de 891 nla_nest_start_noflag(msg, NL80211_FREQUENCY_ATTR_WMM);
50f32718
HD
892
893 if (!nl_wmm_rules)
894 goto nla_put_failure;
895
896 for (j = 0; j < IEEE80211_NUM_ACS; j++) {
ae0be8de 897 struct nlattr *nl_wmm_rule = nla_nest_start_noflag(msg, j);
50f32718
HD
898
899 if (!nl_wmm_rule)
900 goto nla_put_failure;
901
902 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
38cb87ee 903 rule->wmm_rule.client[j].cw_min) ||
50f32718 904 nla_put_u16(msg, NL80211_WMMR_CW_MAX,
38cb87ee 905 rule->wmm_rule.client[j].cw_max) ||
50f32718 906 nla_put_u8(msg, NL80211_WMMR_AIFSN,
38cb87ee 907 rule->wmm_rule.client[j].aifsn) ||
d3c89bbc
HD
908 nla_put_u16(msg, NL80211_WMMR_TXOP,
909 rule->wmm_rule.client[j].cot))
50f32718
HD
910 goto nla_put_failure;
911
912 nla_nest_end(msg, nl_wmm_rule);
913 }
914 nla_nest_end(msg, nl_wmm_rules);
915
916 return 0;
917
918nla_put_failure:
919 return -ENOBUFS;
920}
921
922static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
cdc89b97
JB
923 struct ieee80211_channel *chan,
924 bool large)
5dab3b8a 925{
ea077c1c
RL
926 /* Some channels must be completely excluded from the
927 * list to protect old user-space tools from breaking
928 */
929 if (!large && chan->flags &
930 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
931 return 0;
932
9360ffd1
DM
933 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
934 chan->center_freq))
935 goto nla_put_failure;
5dab3b8a 936
9360ffd1
DM
937 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
938 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
939 goto nla_put_failure;
8fe02e16
LR
940 if (chan->flags & IEEE80211_CHAN_NO_IR) {
941 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
942 goto nla_put_failure;
943 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
944 goto nla_put_failure;
945 }
cdc89b97
JB
946 if (chan->flags & IEEE80211_CHAN_RADAR) {
947 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
948 goto nla_put_failure;
949 if (large) {
950 u32 time;
951
952 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
953
954 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
955 chan->dfs_state))
956 goto nla_put_failure;
957 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
958 time))
959 goto nla_put_failure;
089027e5
JD
960 if (nla_put_u32(msg,
961 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
962 chan->dfs_cac_ms))
963 goto nla_put_failure;
cdc89b97
JB
964 }
965 }
5dab3b8a 966
fe1abafd
JB
967 if (large) {
968 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
969 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
970 goto nla_put_failure;
971 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
972 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
973 goto nla_put_failure;
974 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
975 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
976 goto nla_put_failure;
977 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
978 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
979 goto nla_put_failure;
570dbde1
DS
980 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
981 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
982 goto nla_put_failure;
06f207fc
AN
983 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
984 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 985 goto nla_put_failure;
ea077c1c
RL
986 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
987 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
988 goto nla_put_failure;
989 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
990 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
991 goto nla_put_failure;
1e61d82c
HD
992 if ((chan->flags & IEEE80211_CHAN_NO_HE) &&
993 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE))
994 goto nla_put_failure;
fe1abafd
JB
995 }
996
9360ffd1
DM
997 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
998 DBM_TO_MBM(chan->max_power)))
999 goto nla_put_failure;
5dab3b8a 1000
50f32718
HD
1001 if (large) {
1002 const struct ieee80211_reg_rule *rule =
b88d26d9 1003 freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
50f32718 1004
38cb87ee 1005 if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
50f32718
HD
1006 if (nl80211_msg_put_wmm_rules(msg, rule))
1007 goto nla_put_failure;
1008 }
1009 }
1010
5dab3b8a
LR
1011 return 0;
1012
1013 nla_put_failure:
1014 return -ENOBUFS;
1015}
1016
52539ca8
THJ
1017static bool nl80211_put_txq_stats(struct sk_buff *msg,
1018 struct cfg80211_txq_stats *txqstats,
1019 int attrtype)
1020{
1021 struct nlattr *txqattr;
1022
1023#define PUT_TXQVAL_U32(attr, memb) do { \
1024 if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) && \
1025 nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
1026 return false; \
1027 } while (0)
1028
ae0be8de 1029 txqattr = nla_nest_start_noflag(msg, attrtype);
52539ca8
THJ
1030 if (!txqattr)
1031 return false;
1032
1033 PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
1034 PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
1035 PUT_TXQVAL_U32(FLOWS, flows);
1036 PUT_TXQVAL_U32(DROPS, drops);
1037 PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
1038 PUT_TXQVAL_U32(OVERLIMIT, overlimit);
1039 PUT_TXQVAL_U32(OVERMEMORY, overmemory);
1040 PUT_TXQVAL_U32(COLLISIONS, collisions);
1041 PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
1042 PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
1043 PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
1044 nla_nest_end(msg, txqattr);
1045
1046#undef PUT_TXQVAL_U32
1047 return true;
1048}
1049
55682965
JB
1050/* netlink command implementations */
1051
b9454e83
JB
1052struct key_parse {
1053 struct key_params p;
1054 int idx;
e31b8213 1055 int type;
56be393f 1056 bool def, defmgmt, defbeacon;
dbd2fd65 1057 bool def_uni, def_multi;
b9454e83
JB
1058};
1059
768075eb
JB
1060static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
1061 struct key_parse *k)
b9454e83
JB
1062{
1063 struct nlattr *tb[NL80211_KEY_MAX + 1];
8cb08174
JB
1064 int err = nla_parse_nested_deprecated(tb, NL80211_KEY_MAX, key,
1065 nl80211_key_policy,
1066 info->extack);
b9454e83
JB
1067 if (err)
1068 return err;
1069
1070 k->def = !!tb[NL80211_KEY_DEFAULT];
1071 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
56be393f 1072 k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
b9454e83 1073
dbd2fd65
JB
1074 if (k->def) {
1075 k->def_uni = true;
1076 k->def_multi = true;
1077 }
56be393f 1078 if (k->defmgmt || k->defbeacon)
dbd2fd65
JB
1079 k->def_multi = true;
1080
b9454e83
JB
1081 if (tb[NL80211_KEY_IDX])
1082 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
1083
1084 if (tb[NL80211_KEY_DATA]) {
1085 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
1086 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
1087 }
1088
1089 if (tb[NL80211_KEY_SEQ]) {
1090 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
1091 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
1092 }
1093
1094 if (tb[NL80211_KEY_CIPHER])
1095 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
1096
ab0d76f6 1097 if (tb[NL80211_KEY_TYPE])
e31b8213 1098 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
e31b8213 1099
dbd2fd65
JB
1100 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
1101 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 1102
8cb08174
JB
1103 err = nla_parse_nested_deprecated(kdt,
1104 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1105 tb[NL80211_KEY_DEFAULT_TYPES],
1106 nl80211_key_default_policy,
1107 info->extack);
dbd2fd65
JB
1108 if (err)
1109 return err;
1110
1111 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1112 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1113 }
1114
6cdd3979
AW
1115 if (tb[NL80211_KEY_MODE])
1116 k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
1117
b9454e83
JB
1118 return 0;
1119}
1120
1121static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
1122{
1123 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
1124 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
1125 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1126 }
1127
1128 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1129 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1130 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1131 }
1132
1133 if (info->attrs[NL80211_ATTR_KEY_IDX])
1134 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1135
1136 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
1137 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1138
1139 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
1140 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
1141
dbd2fd65
JB
1142 if (k->def) {
1143 k->def_uni = true;
1144 k->def_multi = true;
1145 }
1146 if (k->defmgmt)
1147 k->def_multi = true;
1148
ab0d76f6 1149 if (info->attrs[NL80211_ATTR_KEY_TYPE])
e31b8213 1150 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
e31b8213 1151
dbd2fd65
JB
1152 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
1153 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
8cb08174
JB
1154 int err = nla_parse_nested_deprecated(kdt,
1155 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1156 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
1157 nl80211_key_default_policy,
1158 info->extack);
dbd2fd65
JB
1159 if (err)
1160 return err;
1161
1162 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1163 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1164 }
1165
b9454e83
JB
1166 return 0;
1167}
1168
1169static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
1170{
1171 int err;
1172
1173 memset(k, 0, sizeof(*k));
1174 k->idx = -1;
e31b8213 1175 k->type = -1;
b9454e83
JB
1176
1177 if (info->attrs[NL80211_ATTR_KEY])
768075eb 1178 err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
b9454e83
JB
1179 else
1180 err = nl80211_parse_key_old(info, k);
1181
1182 if (err)
1183 return err;
1184
56be393f
JM
1185 if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
1186 (k->defbeacon ? 1 : 0) > 1) {
1187 GENL_SET_ERR_MSG(info,
1188 "key with multiple default flags is invalid");
b9454e83 1189 return -EINVAL;
768075eb 1190 }
b9454e83 1191
56be393f 1192 if (k->defmgmt || k->defbeacon) {
768075eb 1193 if (k->def_uni || !k->def_multi) {
56be393f
JM
1194 GENL_SET_ERR_MSG(info,
1195 "defmgmt/defbeacon key must be mcast");
dbd2fd65 1196 return -EINVAL;
768075eb 1197 }
dbd2fd65
JB
1198 }
1199
b9454e83
JB
1200 if (k->idx != -1) {
1201 if (k->defmgmt) {
768075eb
JB
1202 if (k->idx < 4 || k->idx > 5) {
1203 GENL_SET_ERR_MSG(info,
1204 "defmgmt key idx not 4 or 5");
b9454e83 1205 return -EINVAL;
768075eb 1206 }
56be393f
JM
1207 } else if (k->defbeacon) {
1208 if (k->idx < 6 || k->idx > 7) {
1209 GENL_SET_ERR_MSG(info,
1210 "defbeacon key idx not 6 or 7");
1211 return -EINVAL;
1212 }
b9454e83 1213 } else if (k->def) {
768075eb
JB
1214 if (k->idx < 0 || k->idx > 3) {
1215 GENL_SET_ERR_MSG(info, "def key idx not 0-3");
b9454e83 1216 return -EINVAL;
768075eb 1217 }
b9454e83 1218 } else {
56be393f
JM
1219 if (k->idx < 0 || k->idx > 7) {
1220 GENL_SET_ERR_MSG(info, "key idx not 0-7");
b9454e83 1221 return -EINVAL;
768075eb 1222 }
b9454e83
JB
1223 }
1224 }
1225
1226 return 0;
1227}
1228
fffd0934
JB
1229static struct cfg80211_cached_keys *
1230nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
768075eb 1231 struct genl_info *info, bool *no_ht)
fffd0934 1232{
768075eb 1233 struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
fffd0934
JB
1234 struct key_parse parse;
1235 struct nlattr *key;
1236 struct cfg80211_cached_keys *result;
1237 int rem, err, def = 0;
f1c1f17a
JB
1238 bool have_key = false;
1239
1240 nla_for_each_nested(key, keys, rem) {
1241 have_key = true;
1242 break;
1243 }
1244
1245 if (!have_key)
1246 return NULL;
fffd0934
JB
1247
1248 result = kzalloc(sizeof(*result), GFP_KERNEL);
1249 if (!result)
1250 return ERR_PTR(-ENOMEM);
1251
1252 result->def = -1;
fffd0934
JB
1253
1254 nla_for_each_nested(key, keys, rem) {
1255 memset(&parse, 0, sizeof(parse));
1256 parse.idx = -1;
1257
768075eb 1258 err = nl80211_parse_key_new(info, key, &parse);
fffd0934
JB
1259 if (err)
1260 goto error;
1261 err = -EINVAL;
1262 if (!parse.p.key)
1263 goto error;
768075eb
JB
1264 if (parse.idx < 0 || parse.idx > 3) {
1265 GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
fffd0934 1266 goto error;
768075eb 1267 }
fffd0934 1268 if (parse.def) {
768075eb
JB
1269 if (def) {
1270 GENL_SET_ERR_MSG(info,
1271 "only one key can be default");
fffd0934 1272 goto error;
768075eb 1273 }
fffd0934
JB
1274 def = 1;
1275 result->def = parse.idx;
dbd2fd65
JB
1276 if (!parse.def_uni || !parse.def_multi)
1277 goto error;
fffd0934
JB
1278 } else if (parse.defmgmt)
1279 goto error;
1280 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 1281 parse.idx, false, NULL);
fffd0934
JB
1282 if (err)
1283 goto error;
386b1f27
JB
1284 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1285 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
768075eb 1286 GENL_SET_ERR_MSG(info, "connect key must be WEP");
386b1f27
JB
1287 err = -EINVAL;
1288 goto error;
1289 }
fffd0934
JB
1290 result->params[parse.idx].cipher = parse.p.cipher;
1291 result->params[parse.idx].key_len = parse.p.key_len;
1292 result->params[parse.idx].key = result->data[parse.idx];
1293 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 1294
386b1f27
JB
1295 /* must be WEP key if we got here */
1296 if (no_ht)
1297 *no_ht = true;
fffd0934
JB
1298 }
1299
f1c1f17a
JB
1300 if (result->def < 0) {
1301 err = -EINVAL;
768075eb 1302 GENL_SET_ERR_MSG(info, "need a default/TX key");
f1c1f17a
JB
1303 goto error;
1304 }
1305
fffd0934
JB
1306 return result;
1307 error:
1308 kfree(result);
1309 return ERR_PTR(err);
1310}
1311
1312static int nl80211_key_allowed(struct wireless_dev *wdev)
1313{
1314 ASSERT_WDEV_LOCK(wdev);
1315
fffd0934
JB
1316 switch (wdev->iftype) {
1317 case NL80211_IFTYPE_AP:
1318 case NL80211_IFTYPE_AP_VLAN:
074ac8df 1319 case NL80211_IFTYPE_P2P_GO:
ff973af7 1320 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
1321 break;
1322 case NL80211_IFTYPE_ADHOC:
fffd0934 1323 case NL80211_IFTYPE_STATION:
074ac8df 1324 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 1325 if (!wdev->current_bss)
fffd0934
JB
1326 return -ENOLINK;
1327 break;
de4fcbad 1328 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 1329 case NL80211_IFTYPE_OCB:
de4fcbad 1330 case NL80211_IFTYPE_MONITOR:
cb3b7d87 1331 case NL80211_IFTYPE_NAN:
de4fcbad
JB
1332 case NL80211_IFTYPE_P2P_DEVICE:
1333 case NL80211_IFTYPE_WDS:
1334 case NUM_NL80211_IFTYPES:
fffd0934
JB
1335 return -EINVAL;
1336 }
1337
1338 return 0;
1339}
1340
664834de
JM
1341static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
1342 struct nlattr *tb)
1343{
1344 struct ieee80211_channel *chan;
1345
1346 if (tb == NULL)
1347 return NULL;
1348 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
1349 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1350 return NULL;
1351 return chan;
1352}
1353
7527a782
JB
1354static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1355{
ae0be8de 1356 struct nlattr *nl_modes = nla_nest_start_noflag(msg, attr);
7527a782
JB
1357 int i;
1358
1359 if (!nl_modes)
1360 goto nla_put_failure;
1361
1362 i = 0;
1363 while (ifmodes) {
9360ffd1
DM
1364 if ((ifmodes & 1) && nla_put_flag(msg, i))
1365 goto nla_put_failure;
7527a782
JB
1366 ifmodes >>= 1;
1367 i++;
1368 }
1369
1370 nla_nest_end(msg, nl_modes);
1371 return 0;
1372
1373nla_put_failure:
1374 return -ENOBUFS;
1375}
1376
1377static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1378 struct sk_buff *msg,
1379 bool large)
7527a782
JB
1380{
1381 struct nlattr *nl_combis;
1382 int i, j;
1383
ae0be8de
MK
1384 nl_combis = nla_nest_start_noflag(msg,
1385 NL80211_ATTR_INTERFACE_COMBINATIONS);
7527a782
JB
1386 if (!nl_combis)
1387 goto nla_put_failure;
1388
1389 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1390 const struct ieee80211_iface_combination *c;
1391 struct nlattr *nl_combi, *nl_limits;
1392
1393 c = &wiphy->iface_combinations[i];
1394
ae0be8de 1395 nl_combi = nla_nest_start_noflag(msg, i + 1);
7527a782
JB
1396 if (!nl_combi)
1397 goto nla_put_failure;
1398
ae0be8de
MK
1399 nl_limits = nla_nest_start_noflag(msg,
1400 NL80211_IFACE_COMB_LIMITS);
7527a782
JB
1401 if (!nl_limits)
1402 goto nla_put_failure;
1403
1404 for (j = 0; j < c->n_limits; j++) {
1405 struct nlattr *nl_limit;
1406
ae0be8de 1407 nl_limit = nla_nest_start_noflag(msg, j + 1);
7527a782
JB
1408 if (!nl_limit)
1409 goto nla_put_failure;
9360ffd1
DM
1410 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1411 c->limits[j].max))
1412 goto nla_put_failure;
7527a782
JB
1413 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1414 c->limits[j].types))
1415 goto nla_put_failure;
1416 nla_nest_end(msg, nl_limit);
1417 }
1418
1419 nla_nest_end(msg, nl_limits);
1420
9360ffd1
DM
1421 if (c->beacon_int_infra_match &&
1422 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1423 goto nla_put_failure;
1424 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1425 c->num_different_channels) ||
1426 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1427 c->max_interfaces))
1428 goto nla_put_failure;
cdc89b97 1429 if (large &&
8c48b50a
FF
1430 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1431 c->radar_detect_widths) ||
1432 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1433 c->radar_detect_regions)))
cdc89b97 1434 goto nla_put_failure;
0c317a02
PK
1435 if (c->beacon_int_min_gcd &&
1436 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1437 c->beacon_int_min_gcd))
1438 goto nla_put_failure;
7527a782
JB
1439
1440 nla_nest_end(msg, nl_combi);
1441 }
1442
1443 nla_nest_end(msg, nl_combis);
1444
1445 return 0;
1446nla_put_failure:
1447 return -ENOBUFS;
1448}
1449
3713b4e3 1450#ifdef CONFIG_PM
b56cf720
JB
1451static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1452 struct sk_buff *msg)
1453{
964dc9e2 1454 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1455 struct nlattr *nl_tcp;
1456
1457 if (!tcp)
1458 return 0;
1459
ae0be8de
MK
1460 nl_tcp = nla_nest_start_noflag(msg,
1461 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
b56cf720
JB
1462 if (!nl_tcp)
1463 return -ENOBUFS;
1464
1465 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1466 tcp->data_payload_max))
1467 return -ENOBUFS;
1468
1469 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1470 tcp->data_payload_max))
1471 return -ENOBUFS;
1472
1473 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1474 return -ENOBUFS;
1475
1476 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1477 sizeof(*tcp->tok), tcp->tok))
1478 return -ENOBUFS;
1479
1480 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1481 tcp->data_interval_max))
1482 return -ENOBUFS;
1483
1484 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1485 tcp->wake_payload_max))
1486 return -ENOBUFS;
1487
1488 nla_nest_end(msg, nl_tcp);
1489 return 0;
1490}
1491
3713b4e3 1492static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1493 struct cfg80211_registered_device *rdev,
b56cf720 1494 bool large)
55682965 1495{
3713b4e3 1496 struct nlattr *nl_wowlan;
55682965 1497
1b8ec87a 1498 if (!rdev->wiphy.wowlan)
3713b4e3 1499 return 0;
55682965 1500
ae0be8de
MK
1501 nl_wowlan = nla_nest_start_noflag(msg,
1502 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
3713b4e3
JB
1503 if (!nl_wowlan)
1504 return -ENOBUFS;
9360ffd1 1505
1b8ec87a 1506 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1507 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1508 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1509 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1510 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1511 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1512 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1513 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1514 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1515 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1516 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1517 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1518 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1519 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1520 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1521 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1522 return -ENOBUFS;
9360ffd1 1523
1b8ec87a 1524 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1525 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1526 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1527 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1528 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1529 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1530 };
9360ffd1 1531
3713b4e3
JB
1532 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1533 sizeof(pat), &pat))
1534 return -ENOBUFS;
1535 }
9360ffd1 1536
75453ccb
LC
1537 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1538 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1539 rdev->wiphy.wowlan->max_nd_match_sets))
1540 return -ENOBUFS;
1541
1b8ec87a 1542 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1543 return -ENOBUFS;
1544
3713b4e3 1545 nla_nest_end(msg, nl_wowlan);
9360ffd1 1546
3713b4e3
JB
1547 return 0;
1548}
1549#endif
9360ffd1 1550
be29b99a 1551static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1552 struct cfg80211_registered_device *rdev)
be29b99a
AK
1553{
1554 struct nl80211_coalesce_rule_support rule;
1555
1b8ec87a 1556 if (!rdev->wiphy.coalesce)
be29b99a
AK
1557 return 0;
1558
1b8ec87a
ZG
1559 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1560 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1561 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1562 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1563 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1564 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1565
1566 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1567 return -ENOBUFS;
1568
1569 return 0;
1570}
1571
c4cbaf79
LC
1572static int
1573nl80211_send_iftype_data(struct sk_buff *msg,
1574 const struct ieee80211_sband_iftype_data *iftdata)
1575{
1576 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
1577
1578 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
1579 iftdata->types_mask))
1580 return -ENOBUFS;
1581
1582 if (he_cap->has_he) {
1583 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
1584 sizeof(he_cap->he_cap_elem.mac_cap_info),
1585 he_cap->he_cap_elem.mac_cap_info) ||
1586 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
1587 sizeof(he_cap->he_cap_elem.phy_cap_info),
1588 he_cap->he_cap_elem.phy_cap_info) ||
1589 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
1590 sizeof(he_cap->he_mcs_nss_supp),
1591 &he_cap->he_mcs_nss_supp) ||
1592 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
1593 sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
1594 return -ENOBUFS;
1595 }
1596
1597 return 0;
1598}
1599
3713b4e3
JB
1600static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1601 struct ieee80211_supported_band *sband)
1602{
1603 struct nlattr *nl_rates, *nl_rate;
1604 struct ieee80211_rate *rate;
1605 int i;
87bbbe22 1606
3713b4e3
JB
1607 /* add HT info */
1608 if (sband->ht_cap.ht_supported &&
1609 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1610 sizeof(sband->ht_cap.mcs),
1611 &sband->ht_cap.mcs) ||
1612 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1613 sband->ht_cap.cap) ||
1614 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1615 sband->ht_cap.ampdu_factor) ||
1616 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1617 sband->ht_cap.ampdu_density)))
1618 return -ENOBUFS;
afe0cbf8 1619
3713b4e3
JB
1620 /* add VHT info */
1621 if (sband->vht_cap.vht_supported &&
1622 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1623 sizeof(sband->vht_cap.vht_mcs),
1624 &sband->vht_cap.vht_mcs) ||
1625 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1626 sband->vht_cap.cap)))
1627 return -ENOBUFS;
f59ac048 1628
c4cbaf79
LC
1629 if (sband->n_iftype_data) {
1630 struct nlattr *nl_iftype_data =
ae0be8de
MK
1631 nla_nest_start_noflag(msg,
1632 NL80211_BAND_ATTR_IFTYPE_DATA);
c4cbaf79
LC
1633 int err;
1634
1635 if (!nl_iftype_data)
1636 return -ENOBUFS;
1637
1638 for (i = 0; i < sband->n_iftype_data; i++) {
1639 struct nlattr *iftdata;
1640
ae0be8de 1641 iftdata = nla_nest_start_noflag(msg, i + 1);
c4cbaf79
LC
1642 if (!iftdata)
1643 return -ENOBUFS;
1644
1645 err = nl80211_send_iftype_data(msg,
1646 &sband->iftype_data[i]);
1647 if (err)
1648 return err;
1649
1650 nla_nest_end(msg, iftdata);
1651 }
1652
1653 nla_nest_end(msg, nl_iftype_data);
1654 }
1655
2a38075c
AAL
1656 /* add EDMG info */
1657 if (sband->edmg_cap.channels &&
1658 (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
1659 sband->edmg_cap.channels) ||
1660 nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
1661 sband->edmg_cap.bw_config)))
1662
1663 return -ENOBUFS;
1664
3713b4e3 1665 /* add bitrates */
ae0be8de 1666 nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
3713b4e3
JB
1667 if (!nl_rates)
1668 return -ENOBUFS;
ee688b00 1669
3713b4e3 1670 for (i = 0; i < sband->n_bitrates; i++) {
ae0be8de 1671 nl_rate = nla_nest_start_noflag(msg, i);
3713b4e3
JB
1672 if (!nl_rate)
1673 return -ENOBUFS;
ee688b00 1674
3713b4e3
JB
1675 rate = &sband->bitrates[i];
1676 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1677 rate->bitrate))
1678 return -ENOBUFS;
1679 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1680 nla_put_flag(msg,
1681 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1682 return -ENOBUFS;
ee688b00 1683
3713b4e3
JB
1684 nla_nest_end(msg, nl_rate);
1685 }
d51626df 1686
3713b4e3 1687 nla_nest_end(msg, nl_rates);
bf0c111e 1688
3713b4e3
JB
1689 return 0;
1690}
ee688b00 1691
3713b4e3
JB
1692static int
1693nl80211_send_mgmt_stypes(struct sk_buff *msg,
1694 const struct ieee80211_txrx_stypes *mgmt_stypes)
1695{
1696 u16 stypes;
1697 struct nlattr *nl_ftypes, *nl_ifs;
1698 enum nl80211_iftype ift;
1699 int i;
ee688b00 1700
3713b4e3
JB
1701 if (!mgmt_stypes)
1702 return 0;
5dab3b8a 1703
ae0be8de 1704 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_TX_FRAME_TYPES);
3713b4e3
JB
1705 if (!nl_ifs)
1706 return -ENOBUFS;
e2f367f2 1707
3713b4e3 1708 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1709 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1710 if (!nl_ftypes)
1711 return -ENOBUFS;
1712 i = 0;
1713 stypes = mgmt_stypes[ift].tx;
1714 while (stypes) {
1715 if ((stypes & 1) &&
1716 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1717 (i << 4) | IEEE80211_FTYPE_MGMT))
1718 return -ENOBUFS;
1719 stypes >>= 1;
1720 i++;
ee688b00 1721 }
3713b4e3
JB
1722 nla_nest_end(msg, nl_ftypes);
1723 }
ee688b00 1724
3713b4e3 1725 nla_nest_end(msg, nl_ifs);
ee688b00 1726
ae0be8de 1727 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_RX_FRAME_TYPES);
3713b4e3
JB
1728 if (!nl_ifs)
1729 return -ENOBUFS;
ee688b00 1730
3713b4e3 1731 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1732 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1733 if (!nl_ftypes)
1734 return -ENOBUFS;
1735 i = 0;
1736 stypes = mgmt_stypes[ift].rx;
1737 while (stypes) {
1738 if ((stypes & 1) &&
1739 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1740 (i << 4) | IEEE80211_FTYPE_MGMT))
1741 return -ENOBUFS;
1742 stypes >>= 1;
1743 i++;
1744 }
1745 nla_nest_end(msg, nl_ftypes);
1746 }
1747 nla_nest_end(msg, nl_ifs);
ee688b00 1748
3713b4e3
JB
1749 return 0;
1750}
ee688b00 1751
1794899e
JB
1752#define CMD(op, n) \
1753 do { \
1754 if (rdev->ops->op) { \
1755 i++; \
1756 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1757 goto nla_put_failure; \
1758 } \
1759 } while (0)
1760
1761static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1762 struct sk_buff *msg)
1763{
1764 int i = 0;
1765
1766 /*
1767 * do *NOT* add anything into this function, new things need to be
1768 * advertised only to new versions of userspace that can deal with
1769 * the split (and they can't possibly care about new features...
1770 */
1771 CMD(add_virtual_intf, NEW_INTERFACE);
1772 CMD(change_virtual_intf, SET_INTERFACE);
1773 CMD(add_key, NEW_KEY);
1774 CMD(start_ap, START_AP);
1775 CMD(add_station, NEW_STATION);
1776 CMD(add_mpath, NEW_MPATH);
1777 CMD(update_mesh_config, SET_MESH_CONFIG);
1778 CMD(change_bss, SET_BSS);
1779 CMD(auth, AUTHENTICATE);
1780 CMD(assoc, ASSOCIATE);
1781 CMD(deauth, DEAUTHENTICATE);
1782 CMD(disassoc, DISASSOCIATE);
1783 CMD(join_ibss, JOIN_IBSS);
1784 CMD(join_mesh, JOIN_MESH);
1785 CMD(set_pmksa, SET_PMKSA);
1786 CMD(del_pmksa, DEL_PMKSA);
1787 CMD(flush_pmksa, FLUSH_PMKSA);
1788 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1789 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1790 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1791 CMD(mgmt_tx, FRAME);
1792 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1793 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1794 i++;
1795 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1796 goto nla_put_failure;
1797 }
1798 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1799 rdev->ops->join_mesh) {
1800 i++;
1801 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1802 goto nla_put_failure;
1803 }
1804 CMD(set_wds_peer, SET_WDS_PEER);
1805 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1806 CMD(tdls_mgmt, TDLS_MGMT);
1807 CMD(tdls_oper, TDLS_OPER);
1808 }
ca986ad9 1809 if (rdev->wiphy.max_sched_scan_reqs)
1794899e
JB
1810 CMD(sched_scan_start, START_SCHED_SCAN);
1811 CMD(probe_client, PROBE_CLIENT);
1812 CMD(set_noack_map, SET_NOACK_MAP);
1813 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1814 i++;
1815 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1816 goto nla_put_failure;
1817 }
1818 CMD(start_p2p_device, START_P2P_DEVICE);
1819 CMD(set_mcast_rate, SET_MCAST_RATE);
1820#ifdef CONFIG_NL80211_TESTMODE
1821 CMD(testmode_cmd, TESTMODE);
1822#endif
1823
1824 if (rdev->ops->connect || rdev->ops->auth) {
1825 i++;
1826 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1827 goto nla_put_failure;
1828 }
1829
1830 if (rdev->ops->disconnect || rdev->ops->deauth) {
1831 i++;
1832 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1833 goto nla_put_failure;
1834 }
1835
1836 return i;
1837 nla_put_failure:
1838 return -ENOBUFS;
1839}
1840
9bb7e0f2
JB
1841static int
1842nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
1843 struct sk_buff *msg)
1844{
1845 struct nlattr *ftm;
1846
1847 if (!cap->ftm.supported)
1848 return 0;
1849
ae0be8de 1850 ftm = nla_nest_start_noflag(msg, NL80211_PMSR_TYPE_FTM);
9bb7e0f2
JB
1851 if (!ftm)
1852 return -ENOBUFS;
1853
1854 if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
1855 return -ENOBUFS;
1856 if (cap->ftm.non_asap &&
1857 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
1858 return -ENOBUFS;
1859 if (cap->ftm.request_lci &&
1860 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
1861 return -ENOBUFS;
1862 if (cap->ftm.request_civicloc &&
1863 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
1864 return -ENOBUFS;
1865 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
1866 cap->ftm.preambles))
1867 return -ENOBUFS;
1868 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
1869 cap->ftm.bandwidths))
1870 return -ENOBUFS;
1871 if (cap->ftm.max_bursts_exponent >= 0 &&
1872 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
1873 cap->ftm.max_bursts_exponent))
1874 return -ENOBUFS;
1875 if (cap->ftm.max_ftms_per_burst &&
1876 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
1877 cap->ftm.max_ftms_per_burst))
1878 return -ENOBUFS;
1879
1880 nla_nest_end(msg, ftm);
1881 return 0;
1882}
1883
1884static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
1885 struct sk_buff *msg)
1886{
1887 const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
1888 struct nlattr *pmsr, *caps;
1889
1890 if (!cap)
1891 return 0;
1892
1893 /*
1894 * we don't need to clean up anything here since the caller
1895 * will genlmsg_cancel() if we fail
1896 */
1897
ae0be8de 1898 pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
9bb7e0f2
JB
1899 if (!pmsr)
1900 return -ENOBUFS;
1901
1902 if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
1903 return -ENOBUFS;
1904
1905 if (cap->report_ap_tsf &&
1906 nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
1907 return -ENOBUFS;
1908
1909 if (cap->randomize_mac_addr &&
1910 nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
1911 return -ENOBUFS;
1912
ae0be8de 1913 caps = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
9bb7e0f2
JB
1914 if (!caps)
1915 return -ENOBUFS;
1916
1917 if (nl80211_send_pmsr_ftm_capa(cap, msg))
1918 return -ENOBUFS;
1919
1920 nla_nest_end(msg, caps);
1921 nla_nest_end(msg, pmsr);
1922
1923 return 0;
1924}
1925
d6039a34
VJ
1926static int
1927nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
1928 struct sk_buff *msg)
1929{
1930 int i;
1931 struct nlattr *nested, *nested_akms;
1932 const struct wiphy_iftype_akm_suites *iftype_akms;
1933
1934 if (!rdev->wiphy.num_iftype_akm_suites ||
1935 !rdev->wiphy.iftype_akm_suites)
1936 return 0;
1937
1938 nested = nla_nest_start(msg, NL80211_ATTR_IFTYPE_AKM_SUITES);
1939 if (!nested)
1940 return -ENOBUFS;
1941
1942 for (i = 0; i < rdev->wiphy.num_iftype_akm_suites; i++) {
1943 nested_akms = nla_nest_start(msg, i + 1);
1944 if (!nested_akms)
1945 return -ENOBUFS;
1946
1947 iftype_akms = &rdev->wiphy.iftype_akm_suites[i];
1948
1949 if (nl80211_put_iftypes(msg, NL80211_IFTYPE_AKM_ATTR_IFTYPES,
1950 iftype_akms->iftypes_mask))
1951 return -ENOBUFS;
1952
1953 if (nla_put(msg, NL80211_IFTYPE_AKM_ATTR_SUITES,
1954 sizeof(u32) * iftype_akms->n_akm_suites,
1955 iftype_akms->akm_suites)) {
1956 return -ENOBUFS;
1957 }
1958 nla_nest_end(msg, nested_akms);
1959 }
1960
1961 nla_nest_end(msg, nested);
1962
1963 return 0;
1964}
1965
3710a8a6
JB
1966static int
1967nl80211_put_tid_config_support(struct cfg80211_registered_device *rdev,
1968 struct sk_buff *msg)
1969{
1970 struct nlattr *supp;
1971
1972 if (!rdev->wiphy.tid_config_support.vif &&
1973 !rdev->wiphy.tid_config_support.peer)
1974 return 0;
1975
1976 supp = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
1977 if (!supp)
1978 return -ENOSPC;
1979
1980 if (rdev->wiphy.tid_config_support.vif &&
1981 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_VIF_SUPP,
1982 rdev->wiphy.tid_config_support.vif,
1983 NL80211_TID_CONFIG_ATTR_PAD))
1984 goto fail;
1985
1986 if (rdev->wiphy.tid_config_support.peer &&
1987 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_PEER_SUPP,
1988 rdev->wiphy.tid_config_support.peer,
1989 NL80211_TID_CONFIG_ATTR_PAD))
1990 goto fail;
1991
6a21d16c
T
1992 /* for now we just use the same value ... makes more sense */
1993 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
1994 rdev->wiphy.tid_config_support.max_retry))
1995 goto fail;
1996 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG,
1997 rdev->wiphy.tid_config_support.max_retry))
1998 goto fail;
1999
3710a8a6
JB
2000 nla_nest_end(msg, supp);
2001
2002 return 0;
2003fail:
2004 nla_nest_cancel(msg, supp);
2005 return -ENOBUFS;
2006}
2007
86e8cf98
JB
2008struct nl80211_dump_wiphy_state {
2009 s64 filter_wiphy;
2010 long start;
019ae3a9 2011 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
2012 bool split;
2013};
2014
1b8ec87a 2015static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 2016 enum nl80211_commands cmd,
3713b4e3 2017 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 2018 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
2019{
2020 void *hdr;
2021 struct nlattr *nl_bands, *nl_band;
2022 struct nlattr *nl_freqs, *nl_freq;
2023 struct nlattr *nl_cmds;
57fbcce3 2024 enum nl80211_band band;
3713b4e3
JB
2025 struct ieee80211_channel *chan;
2026 int i;
2027 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 2028 rdev->wiphy.mgmt_stypes;
fe1abafd 2029 u32 features;
ee688b00 2030
3bb20556 2031 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
2032 if (!hdr)
2033 return -ENOBUFS;
ee688b00 2034
86e8cf98
JB
2035 if (WARN_ON(!state))
2036 return -EINVAL;
ee688b00 2037
1b8ec87a 2038 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 2039 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 2040 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
2041 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2042 cfg80211_rdev_list_generation))
8fdc621d
JB
2043 goto nla_put_failure;
2044
3bb20556
JB
2045 if (cmd != NL80211_CMD_NEW_WIPHY)
2046 goto finish;
2047
86e8cf98 2048 switch (state->split_start) {
3713b4e3
JB
2049 case 0:
2050 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 2051 rdev->wiphy.retry_short) ||
3713b4e3 2052 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 2053 rdev->wiphy.retry_long) ||
3713b4e3 2054 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 2055 rdev->wiphy.frag_threshold) ||
3713b4e3 2056 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 2057 rdev->wiphy.rts_threshold) ||
3713b4e3 2058 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 2059 rdev->wiphy.coverage_class) ||
3713b4e3 2060 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 2061 rdev->wiphy.max_scan_ssids) ||
3713b4e3 2062 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 2063 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 2064 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 2065 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 2066 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 2067 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 2068 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
3b06d277
AS
2069 rdev->wiphy.max_match_sets) ||
2070 nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
2071 rdev->wiphy.max_sched_scan_plans) ||
2072 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
2073 rdev->wiphy.max_sched_scan_plan_interval) ||
2074 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
2075 rdev->wiphy.max_sched_scan_plan_iterations))
9360ffd1 2076 goto nla_put_failure;
3713b4e3 2077
1b8ec87a 2078 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 2079 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 2080 goto nla_put_failure;
1b8ec87a 2081 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
2082 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
2083 goto nla_put_failure;
1b8ec87a 2084 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
2085 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
2086 goto nla_put_failure;
1b8ec87a 2087 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
2088 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
2089 goto nla_put_failure;
1b8ec87a 2090 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
2091 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
2092 goto nla_put_failure;
1b8ec87a 2093 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 2094 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 2095 goto nla_put_failure;
86e8cf98
JB
2096 state->split_start++;
2097 if (state->split)
3713b4e3 2098 break;
925b5978 2099 /* fall through */
3713b4e3
JB
2100 case 1:
2101 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
2102 sizeof(u32) * rdev->wiphy.n_cipher_suites,
2103 rdev->wiphy.cipher_suites))
3713b4e3 2104 goto nla_put_failure;
4745fc09 2105
3713b4e3 2106 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 2107 rdev->wiphy.max_num_pmkids))
3713b4e3 2108 goto nla_put_failure;
b23aa676 2109
1b8ec87a 2110 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 2111 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 2112 goto nla_put_failure;
b23aa676 2113
3713b4e3 2114 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 2115 rdev->wiphy.available_antennas_tx) ||
3713b4e3 2116 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 2117 rdev->wiphy.available_antennas_rx))
9360ffd1 2118 goto nla_put_failure;
b23aa676 2119
1b8ec87a 2120 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 2121 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 2122 rdev->wiphy.probe_resp_offload))
3713b4e3 2123 goto nla_put_failure;
8fdc621d 2124
1b8ec87a
ZG
2125 if ((rdev->wiphy.available_antennas_tx ||
2126 rdev->wiphy.available_antennas_rx) &&
2127 rdev->ops->get_antenna) {
3713b4e3
JB
2128 u32 tx_ant = 0, rx_ant = 0;
2129 int res;
7a087e74 2130
1b8ec87a 2131 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
2132 if (!res) {
2133 if (nla_put_u32(msg,
2134 NL80211_ATTR_WIPHY_ANTENNA_TX,
2135 tx_ant) ||
2136 nla_put_u32(msg,
2137 NL80211_ATTR_WIPHY_ANTENNA_RX,
2138 rx_ant))
2139 goto nla_put_failure;
2140 }
2141 }
a293911d 2142
86e8cf98
JB
2143 state->split_start++;
2144 if (state->split)
3713b4e3 2145 break;
925b5978 2146 /* fall through */
3713b4e3
JB
2147 case 2:
2148 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 2149 rdev->wiphy.interface_modes))
3713b4e3 2150 goto nla_put_failure;
86e8cf98
JB
2151 state->split_start++;
2152 if (state->split)
3713b4e3 2153 break;
925b5978 2154 /* fall through */
3713b4e3 2155 case 3:
ae0be8de
MK
2156 nl_bands = nla_nest_start_noflag(msg,
2157 NL80211_ATTR_WIPHY_BANDS);
3713b4e3
JB
2158 if (!nl_bands)
2159 goto nla_put_failure;
f7ca38df 2160
86e8cf98 2161 for (band = state->band_start;
57fbcce3 2162 band < NUM_NL80211_BANDS; band++) {
3713b4e3 2163 struct ieee80211_supported_band *sband;
2e161f78 2164
1b8ec87a 2165 sband = rdev->wiphy.bands[band];
2e161f78 2166
3713b4e3
JB
2167 if (!sband)
2168 continue;
2169
ae0be8de 2170 nl_band = nla_nest_start_noflag(msg, band);
3713b4e3 2171 if (!nl_band)
2e161f78 2172 goto nla_put_failure;
3713b4e3 2173
86e8cf98 2174 switch (state->chan_start) {
3713b4e3
JB
2175 case 0:
2176 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 2177 goto nla_put_failure;
86e8cf98
JB
2178 state->chan_start++;
2179 if (state->split)
3713b4e3 2180 break;
925b5978 2181 /* fall through */
3713b4e3
JB
2182 default:
2183 /* add frequencies */
ae0be8de
MK
2184 nl_freqs = nla_nest_start_noflag(msg,
2185 NL80211_BAND_ATTR_FREQS);
3713b4e3
JB
2186 if (!nl_freqs)
2187 goto nla_put_failure;
2188
86e8cf98 2189 for (i = state->chan_start - 1;
3713b4e3
JB
2190 i < sband->n_channels;
2191 i++) {
ae0be8de
MK
2192 nl_freq = nla_nest_start_noflag(msg,
2193 i);
3713b4e3
JB
2194 if (!nl_freq)
2195 goto nla_put_failure;
2196
2197 chan = &sband->channels[i];
2198
86e8cf98 2199 if (nl80211_msg_put_channel(
50f32718 2200 msg, &rdev->wiphy, chan,
86e8cf98 2201 state->split))
3713b4e3
JB
2202 goto nla_put_failure;
2203
2204 nla_nest_end(msg, nl_freq);
86e8cf98 2205 if (state->split)
3713b4e3
JB
2206 break;
2207 }
2208 if (i < sband->n_channels)
86e8cf98 2209 state->chan_start = i + 2;
3713b4e3 2210 else
86e8cf98 2211 state->chan_start = 0;
3713b4e3
JB
2212 nla_nest_end(msg, nl_freqs);
2213 }
2214
2215 nla_nest_end(msg, nl_band);
2216
86e8cf98 2217 if (state->split) {
3713b4e3 2218 /* start again here */
86e8cf98 2219 if (state->chan_start)
3713b4e3
JB
2220 band--;
2221 break;
2e161f78 2222 }
2e161f78 2223 }
3713b4e3 2224 nla_nest_end(msg, nl_bands);
2e161f78 2225
57fbcce3 2226 if (band < NUM_NL80211_BANDS)
86e8cf98 2227 state->band_start = band + 1;
3713b4e3 2228 else
86e8cf98 2229 state->band_start = 0;
74b70a4e 2230
3713b4e3 2231 /* if bands & channels are done, continue outside */
86e8cf98
JB
2232 if (state->band_start == 0 && state->chan_start == 0)
2233 state->split_start++;
2234 if (state->split)
3713b4e3 2235 break;
925b5978 2236 /* fall through */
3713b4e3 2237 case 4:
ae0be8de
MK
2238 nl_cmds = nla_nest_start_noflag(msg,
2239 NL80211_ATTR_SUPPORTED_COMMANDS);
3713b4e3 2240 if (!nl_cmds)
2e161f78
JB
2241 goto nla_put_failure;
2242
1794899e
JB
2243 i = nl80211_add_commands_unsplit(rdev, msg);
2244 if (i < 0)
2245 goto nla_put_failure;
86e8cf98 2246 if (state->split) {
5de17984
AS
2247 CMD(crit_proto_start, CRIT_PROTOCOL_START);
2248 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 2249 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 2250 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 2251 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
2252 if (rdev->wiphy.features &
2253 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 2254 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 2255 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 2256 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
7010998c 2257 CMD(update_ft_ies, UPDATE_FT_IES);
5de17984 2258 }
3713b4e3 2259#undef CMD
ff1b6e69 2260
3713b4e3 2261 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
2262 state->split_start++;
2263 if (state->split)
3713b4e3 2264 break;
925b5978 2265 /* fall through */
3713b4e3 2266 case 5:
1b8ec87a
ZG
2267 if (rdev->ops->remain_on_channel &&
2268 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
2269 nla_put_u32(msg,
2270 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 2271 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
2272 goto nla_put_failure;
2273
1b8ec87a 2274 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
2275 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
2276 goto nla_put_failure;
2277
2278 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
2279 goto nla_put_failure;
86e8cf98
JB
2280 state->split_start++;
2281 if (state->split)
3713b4e3 2282 break;
925b5978 2283 /* fall through */
3713b4e3
JB
2284 case 6:
2285#ifdef CONFIG_PM
1b8ec87a 2286 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 2287 goto nla_put_failure;
86e8cf98
JB
2288 state->split_start++;
2289 if (state->split)
3713b4e3
JB
2290 break;
2291#else
86e8cf98 2292 state->split_start++;
dfb89c56 2293#endif
925b5978 2294 /* fall through */
3713b4e3
JB
2295 case 7:
2296 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 2297 rdev->wiphy.software_iftypes))
3713b4e3 2298 goto nla_put_failure;
ff1b6e69 2299
1b8ec87a 2300 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 2301 state->split))
3713b4e3 2302 goto nla_put_failure;
7527a782 2303
86e8cf98
JB
2304 state->split_start++;
2305 if (state->split)
3713b4e3 2306 break;
925b5978 2307 /* fall through */
3713b4e3 2308 case 8:
1b8ec87a 2309 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 2310 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 2311 rdev->wiphy.ap_sme_capa))
3713b4e3 2312 goto nla_put_failure;
7527a782 2313
1b8ec87a 2314 features = rdev->wiphy.features;
fe1abafd
JB
2315 /*
2316 * We can only add the per-channel limit information if the
2317 * dump is split, otherwise it makes it too big. Therefore
2318 * only advertise it in that case.
2319 */
86e8cf98 2320 if (state->split)
fe1abafd
JB
2321 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
2322 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 2323 goto nla_put_failure;
562a7480 2324
1b8ec87a 2325 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 2326 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
2327 sizeof(*rdev->wiphy.ht_capa_mod_mask),
2328 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 2329 goto nla_put_failure;
1f074bd8 2330
1b8ec87a
ZG
2331 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
2332 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 2333 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 2334 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 2335 goto nla_put_failure;
7e7c8926 2336
3713b4e3
JB
2337 /*
2338 * Any information below this point is only available to
2339 * applications that can deal with it being split. This
2340 * helps ensure that newly added capabilities don't break
2341 * older tools by overrunning their buffers.
2342 *
2343 * We still increment split_start so that in the split
2344 * case we'll continue with more data in the next round,
2345 * but break unconditionally so unsplit data stops here.
2346 */
86e8cf98 2347 state->split_start++;
3713b4e3
JB
2348 break;
2349 case 9:
1b8ec87a 2350 if (rdev->wiphy.extended_capabilities &&
fe1abafd 2351 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
2352 rdev->wiphy.extended_capabilities_len,
2353 rdev->wiphy.extended_capabilities) ||
fe1abafd 2354 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
2355 rdev->wiphy.extended_capabilities_len,
2356 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 2357 goto nla_put_failure;
a50df0c4 2358
1b8ec87a 2359 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 2360 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
2361 sizeof(*rdev->wiphy.vht_capa_mod_mask),
2362 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
2363 goto nla_put_failure;
2364
ae6fa4d5
DK
2365 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
2366 rdev->wiphy.perm_addr))
2367 goto nla_put_failure;
2368
2369 if (!is_zero_ether_addr(rdev->wiphy.addr_mask) &&
2370 nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
2371 rdev->wiphy.addr_mask))
2372 goto nla_put_failure;
2373
2374 if (rdev->wiphy.n_addresses > 1) {
2375 void *attr;
2376
2377 attr = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
2378 if (!attr)
2379 goto nla_put_failure;
2380
2381 for (i = 0; i < rdev->wiphy.n_addresses; i++)
2382 if (nla_put(msg, i + 1, ETH_ALEN,
2383 rdev->wiphy.addresses[i].addr))
2384 goto nla_put_failure;
2385
2386 nla_nest_end(msg, attr);
2387 }
2388
be29b99a
AK
2389 state->split_start++;
2390 break;
2391 case 10:
1b8ec87a 2392 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
2393 goto nla_put_failure;
2394
1b8ec87a 2395 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
2396 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
2397 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
2398 goto nla_put_failure;
b43504cf 2399
1b8ec87a 2400 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 2401 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 2402 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
2403 goto nla_put_failure;
2404
ad7e718c
JB
2405 state->split_start++;
2406 break;
2407 case 11:
1b8ec87a 2408 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
2409 const struct nl80211_vendor_cmd_info *info;
2410 struct nlattr *nested;
2411
ae0be8de
MK
2412 nested = nla_nest_start_noflag(msg,
2413 NL80211_ATTR_VENDOR_DATA);
567ffc35
JB
2414 if (!nested)
2415 goto nla_put_failure;
2416
1b8ec87a
ZG
2417 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
2418 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
2419 if (nla_put(msg, i + 1, sizeof(*info), info))
2420 goto nla_put_failure;
2421 }
2422 nla_nest_end(msg, nested);
2423 }
2424
1b8ec87a 2425 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
2426 const struct nl80211_vendor_cmd_info *info;
2427 struct nlattr *nested;
ad7e718c 2428
ae0be8de
MK
2429 nested = nla_nest_start_noflag(msg,
2430 NL80211_ATTR_VENDOR_EVENTS);
567ffc35 2431 if (!nested)
ad7e718c 2432 goto nla_put_failure;
567ffc35 2433
1b8ec87a
ZG
2434 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
2435 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
2436 if (nla_put(msg, i + 1, sizeof(*info), info))
2437 goto nla_put_failure;
2438 }
2439 nla_nest_end(msg, nested);
2440 }
9a774c78
AO
2441 state->split_start++;
2442 break;
2443 case 12:
2444 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
2445 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
2446 rdev->wiphy.max_num_csa_counters))
2447 goto nla_put_failure;
01e0daa4 2448
1bdd716c
AN
2449 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2450 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
2451 goto nla_put_failure;
2452
ca986ad9
AVS
2453 if (rdev->wiphy.max_sched_scan_reqs &&
2454 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
2455 rdev->wiphy.max_sched_scan_reqs))
2456 goto nla_put_failure;
2457
d75bb06b
GKS
2458 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
2459 sizeof(rdev->wiphy.ext_features),
2460 rdev->wiphy.ext_features))
2461 goto nla_put_failure;
2462
38de03d2
AS
2463 if (rdev->wiphy.bss_select_support) {
2464 struct nlattr *nested;
2465 u32 bss_select_support = rdev->wiphy.bss_select_support;
2466
ae0be8de
MK
2467 nested = nla_nest_start_noflag(msg,
2468 NL80211_ATTR_BSS_SELECT);
38de03d2
AS
2469 if (!nested)
2470 goto nla_put_failure;
2471
2472 i = 0;
2473 while (bss_select_support) {
2474 if ((bss_select_support & 1) &&
2475 nla_put_flag(msg, i))
2476 goto nla_put_failure;
2477 i++;
2478 bss_select_support >>= 1;
2479 }
2480 nla_nest_end(msg, nested);
2481 }
2482
019ae3a9
KV
2483 state->split_start++;
2484 break;
2485 case 13:
2486 if (rdev->wiphy.num_iftype_ext_capab &&
2487 rdev->wiphy.iftype_ext_capab) {
2488 struct nlattr *nested_ext_capab, *nested;
2489
ae0be8de
MK
2490 nested = nla_nest_start_noflag(msg,
2491 NL80211_ATTR_IFTYPE_EXT_CAPA);
019ae3a9
KV
2492 if (!nested)
2493 goto nla_put_failure;
2494
2495 for (i = state->capa_start;
2496 i < rdev->wiphy.num_iftype_ext_capab; i++) {
2497 const struct wiphy_iftype_ext_capab *capab;
2498
2499 capab = &rdev->wiphy.iftype_ext_capab[i];
2500
ae0be8de
MK
2501 nested_ext_capab = nla_nest_start_noflag(msg,
2502 i);
019ae3a9
KV
2503 if (!nested_ext_capab ||
2504 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
2505 capab->iftype) ||
2506 nla_put(msg, NL80211_ATTR_EXT_CAPA,
2507 capab->extended_capabilities_len,
2508 capab->extended_capabilities) ||
2509 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
2510 capab->extended_capabilities_len,
2511 capab->extended_capabilities_mask))
2512 goto nla_put_failure;
2513
2514 nla_nest_end(msg, nested_ext_capab);
2515 if (state->split)
2516 break;
2517 }
2518 nla_nest_end(msg, nested);
2519 if (i < rdev->wiphy.num_iftype_ext_capab) {
2520 state->capa_start = i + 1;
2521 break;
2522 }
2523 }
2524
8585989d
LC
2525 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
2526 rdev->wiphy.nan_supported_bands))
2527 goto nla_put_failure;
2528
52539ca8
THJ
2529 if (wiphy_ext_feature_isset(&rdev->wiphy,
2530 NL80211_EXT_FEATURE_TXQS)) {
2531 struct cfg80211_txq_stats txqstats = {};
2532 int res;
2533
2534 res = rdev_get_txq_stats(rdev, NULL, &txqstats);
2535 if (!res &&
2536 !nl80211_put_txq_stats(msg, &txqstats,
2537 NL80211_ATTR_TXQ_STATS))
2538 goto nla_put_failure;
2539
2540 if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
2541 rdev->wiphy.txq_limit))
2542 goto nla_put_failure;
2543 if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
2544 rdev->wiphy.txq_memory_limit))
2545 goto nla_put_failure;
2546 if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
2547 rdev->wiphy.txq_quantum))
2548 goto nla_put_failure;
2549 }
2550
9bb7e0f2
JB
2551 state->split_start++;
2552 break;
2553 case 14:
2554 if (nl80211_send_pmsr_capa(rdev, msg))
2555 goto nla_put_failure;
2556
ab4dfa20
VJ
2557 state->split_start++;
2558 break;
2559 case 15:
2560 if (rdev->wiphy.akm_suites &&
2561 nla_put(msg, NL80211_ATTR_AKM_SUITES,
2562 sizeof(u32) * rdev->wiphy.n_akm_suites,
2563 rdev->wiphy.akm_suites))
2564 goto nla_put_failure;
2565
d6039a34
VJ
2566 if (nl80211_put_iftype_akm_suites(rdev, msg))
2567 goto nla_put_failure;
2568
3710a8a6
JB
2569 if (nl80211_put_tid_config_support(rdev, msg))
2570 goto nla_put_failure;
2571
3713b4e3 2572 /* done */
86e8cf98 2573 state->split_start = 0;
3713b4e3
JB
2574 break;
2575 }
3bb20556 2576 finish:
053c095a
JB
2577 genlmsg_end(msg, hdr);
2578 return 0;
55682965
JB
2579
2580 nla_put_failure:
bc3ed28c
TG
2581 genlmsg_cancel(msg, hdr);
2582 return -EMSGSIZE;
55682965
JB
2583}
2584
86e8cf98
JB
2585static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
2586 struct netlink_callback *cb,
2587 struct nl80211_dump_wiphy_state *state)
2588{
50508d94
JB
2589 struct nlattr **tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
2590 int ret;
2591
2592 if (!tb)
2593 return -ENOMEM;
2594
2595 ret = nlmsg_parse_deprecated(cb->nlh,
2596 GENL_HDRLEN + nl80211_fam.hdrsize,
2597 tb, nl80211_fam.maxattr,
2598 nl80211_policy, NULL);
86e8cf98 2599 /* ignore parse errors for backward compatibility */
50508d94
JB
2600 if (ret) {
2601 ret = 0;
2602 goto out;
2603 }
86e8cf98
JB
2604
2605 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
2606 if (tb[NL80211_ATTR_WIPHY])
2607 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2608 if (tb[NL80211_ATTR_WDEV])
2609 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
2610 if (tb[NL80211_ATTR_IFINDEX]) {
2611 struct net_device *netdev;
2612 struct cfg80211_registered_device *rdev;
2613 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2614
7f2b8562 2615 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
50508d94
JB
2616 if (!netdev) {
2617 ret = -ENODEV;
2618 goto out;
2619 }
86e8cf98 2620 if (netdev->ieee80211_ptr) {
f26cbf40 2621 rdev = wiphy_to_rdev(
86e8cf98
JB
2622 netdev->ieee80211_ptr->wiphy);
2623 state->filter_wiphy = rdev->wiphy_idx;
2624 }
86e8cf98
JB
2625 }
2626
50508d94
JB
2627 ret = 0;
2628out:
2629 kfree(tb);
2630 return ret;
86e8cf98
JB
2631}
2632
55682965
JB
2633static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
2634{
645e77de 2635 int idx = 0, ret;
86e8cf98 2636 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 2637 struct cfg80211_registered_device *rdev;
3a5a423b 2638
5fe231e8 2639 rtnl_lock();
86e8cf98
JB
2640 if (!state) {
2641 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
2642 if (!state) {
2643 rtnl_unlock();
86e8cf98 2644 return -ENOMEM;
3713b4e3 2645 }
86e8cf98
JB
2646 state->filter_wiphy = -1;
2647 ret = nl80211_dump_wiphy_parse(skb, cb, state);
2648 if (ret) {
2649 kfree(state);
2650 rtnl_unlock();
2651 return ret;
3713b4e3 2652 }
86e8cf98 2653 cb->args[0] = (long)state;
3713b4e3
JB
2654 }
2655
1b8ec87a
ZG
2656 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2657 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2658 continue;
86e8cf98 2659 if (++idx <= state->start)
55682965 2660 continue;
86e8cf98 2661 if (state->filter_wiphy != -1 &&
1b8ec87a 2662 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
2663 continue;
2664 /* attempt to fit multiple wiphy data chunks into the skb */
2665 do {
3bb20556
JB
2666 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
2667 skb,
3713b4e3
JB
2668 NETLINK_CB(cb->skb).portid,
2669 cb->nlh->nlmsg_seq,
86e8cf98 2670 NLM_F_MULTI, state);
3713b4e3
JB
2671 if (ret < 0) {
2672 /*
2673 * If sending the wiphy data didn't fit (ENOBUFS
2674 * or EMSGSIZE returned), this SKB is still
2675 * empty (so it's not too big because another
2676 * wiphy dataset is already in the skb) and
2677 * we've not tried to adjust the dump allocation
2678 * yet ... then adjust the alloc size to be
2679 * bigger, and return 1 but with the empty skb.
2680 * This results in an empty message being RX'ed
2681 * in userspace, but that is ignored.
2682 *
2683 * We can then retry with the larger buffer.
2684 */
2685 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 2686 !skb->len && !state->split &&
3713b4e3
JB
2687 cb->min_dump_alloc < 4096) {
2688 cb->min_dump_alloc = 4096;
f12cb289 2689 state->split_start = 0;
d98cae64 2690 rtnl_unlock();
3713b4e3
JB
2691 return 1;
2692 }
2693 idx--;
2694 break;
645e77de 2695 }
86e8cf98 2696 } while (state->split_start > 0);
3713b4e3 2697 break;
55682965 2698 }
5fe231e8 2699 rtnl_unlock();
55682965 2700
86e8cf98 2701 state->start = idx;
55682965
JB
2702
2703 return skb->len;
2704}
2705
86e8cf98
JB
2706static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
2707{
2708 kfree((void *)cb->args[0]);
2709 return 0;
2710}
2711
55682965
JB
2712static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
2713{
2714 struct sk_buff *msg;
1b8ec87a 2715 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2716 struct nl80211_dump_wiphy_state state = {};
55682965 2717
645e77de 2718 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2719 if (!msg)
4c476991 2720 return -ENOMEM;
55682965 2721
3bb20556
JB
2722 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2723 info->snd_portid, info->snd_seq, 0,
86e8cf98 2724 &state) < 0) {
4c476991
JB
2725 nlmsg_free(msg);
2726 return -ENOBUFS;
2727 }
55682965 2728
134e6375 2729 return genlmsg_reply(msg, info);
55682965
JB
2730}
2731
31888487
JM
2732static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2733 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2734 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2735 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2736 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2737 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2738};
2739
2740static int parse_txq_params(struct nlattr *tb[],
2741 struct ieee80211_txq_params *txq_params)
2742{
259d8c1e
DW
2743 u8 ac;
2744
a3304b0a 2745 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2746 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2747 !tb[NL80211_TXQ_ATTR_AIFS])
2748 return -EINVAL;
2749
259d8c1e 2750 ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2751 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2752 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2753 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2754 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2755
259d8c1e 2756 if (ac >= NL80211_NUM_ACS)
a3304b0a 2757 return -EINVAL;
259d8c1e 2758 txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
31888487
JM
2759 return 0;
2760}
2761
f444de05
JB
2762static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2763{
2764 /*
cc1d2806
JB
2765 * You can only set the channel explicitly for WDS interfaces,
2766 * all others have their channel managed via their respective
2767 * "establish a connection" command (connect, join, ...)
2768 *
2769 * For AP/GO and mesh mode, the channel can be set with the
2770 * channel userspace API, but is only stored and passed to the
2771 * low-level driver when the AP starts or the mesh is joined.
2772 * This is for backward compatibility, userspace can also give
2773 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2774 *
2775 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2776 * whatever else is going on, so they have their own special
2777 * operation to set the monitor channel if possible.
f444de05
JB
2778 */
2779 return !wdev ||
2780 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2781 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2782 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2783 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2784}
2785
9bb7e0f2
JB
2786int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2787 struct genl_info *info,
2788 struct cfg80211_chan_def *chandef)
683b6d3b 2789{
49f9cf0e
JB
2790 struct netlink_ext_ack *extack = info->extack;
2791 struct nlattr **attrs = info->attrs;
dbeca2ea 2792 u32 control_freq;
683b6d3b 2793
49f9cf0e 2794 if (!attrs[NL80211_ATTR_WIPHY_FREQ])
683b6d3b
JB
2795 return -EINVAL;
2796
49f9cf0e 2797 control_freq = nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]);
683b6d3b 2798
f43e5210
JB
2799 memset(chandef, 0, sizeof(*chandef));
2800
683b6d3b 2801 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
2802 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
2803 chandef->center_freq1 = control_freq;
2804 chandef->center_freq2 = 0;
683b6d3b
JB
2805
2806 /* Primary channel not allowed */
49f9cf0e
JB
2807 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) {
2808 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
2809 "Channel is disabled");
683b6d3b 2810 return -EINVAL;
49f9cf0e 2811 }
683b6d3b 2812
49f9cf0e 2813 if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
3d9d1d66
JB
2814 enum nl80211_channel_type chantype;
2815
49f9cf0e 2816 chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
3d9d1d66
JB
2817
2818 switch (chantype) {
2819 case NL80211_CHAN_NO_HT:
2820 case NL80211_CHAN_HT20:
2821 case NL80211_CHAN_HT40PLUS:
2822 case NL80211_CHAN_HT40MINUS:
2823 cfg80211_chandef_create(chandef, chandef->chan,
2824 chantype);
ffa4629e 2825 /* user input for center_freq is incorrect */
49f9cf0e
JB
2826 if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
2827 chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
2828 NL_SET_ERR_MSG_ATTR(extack,
2829 attrs[NL80211_ATTR_CENTER_FREQ1],
2830 "bad center frequency 1");
ffa4629e 2831 return -EINVAL;
49f9cf0e 2832 }
ffa4629e 2833 /* center_freq2 must be zero */
49f9cf0e
JB
2834 if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
2835 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
2836 NL_SET_ERR_MSG_ATTR(extack,
2837 attrs[NL80211_ATTR_CENTER_FREQ2],
2838 "center frequency 2 can't be used");
ffa4629e 2839 return -EINVAL;
49f9cf0e 2840 }
3d9d1d66
JB
2841 break;
2842 default:
49f9cf0e
JB
2843 NL_SET_ERR_MSG_ATTR(extack,
2844 attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
2845 "invalid channel type");
3d9d1d66
JB
2846 return -EINVAL;
2847 }
49f9cf0e 2848 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
3d9d1d66 2849 chandef->width =
49f9cf0e
JB
2850 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
2851 if (attrs[NL80211_ATTR_CENTER_FREQ1])
3d9d1d66 2852 chandef->center_freq1 =
49f9cf0e
JB
2853 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
2854 if (attrs[NL80211_ATTR_CENTER_FREQ2])
3d9d1d66 2855 chandef->center_freq2 =
49f9cf0e 2856 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
3d9d1d66
JB
2857 }
2858
2a38075c
AAL
2859 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
2860 chandef->edmg.channels =
2861 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
2862
2863 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
2864 chandef->edmg.bw_config =
2865 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
2866 } else {
2867 chandef->edmg.bw_config = 0;
2868 chandef->edmg.channels = 0;
2869 }
2870
49f9cf0e
JB
2871 if (!cfg80211_chandef_valid(chandef)) {
2872 NL_SET_ERR_MSG(extack, "invalid channel definition");
3d9d1d66 2873 return -EINVAL;
49f9cf0e 2874 }
3d9d1d66 2875
9f5e8f6e 2876 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
49f9cf0e
JB
2877 IEEE80211_CHAN_DISABLED)) {
2878 NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
3d9d1d66 2879 return -EINVAL;
49f9cf0e 2880 }
3d9d1d66 2881
2f301ab2
SW
2882 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
2883 chandef->width == NL80211_CHAN_WIDTH_10) &&
49f9cf0e
JB
2884 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
2885 NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
2f301ab2 2886 return -EINVAL;
49f9cf0e 2887 }
2f301ab2 2888
683b6d3b
JB
2889 return 0;
2890}
2891
f444de05 2892static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 2893 struct net_device *dev,
f444de05
JB
2894 struct genl_info *info)
2895{
683b6d3b 2896 struct cfg80211_chan_def chandef;
f444de05 2897 int result;
e8c9bd5b 2898 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 2899 struct wireless_dev *wdev = NULL;
e8c9bd5b 2900
e16821bc
JM
2901 if (dev)
2902 wdev = dev->ieee80211_ptr;
f444de05
JB
2903 if (!nl80211_can_set_dev_channel(wdev))
2904 return -EOPNOTSUPP;
e16821bc
JM
2905 if (wdev)
2906 iftype = wdev->iftype;
f444de05 2907
683b6d3b
JB
2908 result = nl80211_parse_chandef(rdev, info, &chandef);
2909 if (result)
2910 return result;
f444de05 2911
e8c9bd5b 2912 switch (iftype) {
aa430da4
JB
2913 case NL80211_IFTYPE_AP:
2914 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
2915 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
2916 iftype)) {
aa430da4
JB
2917 result = -EINVAL;
2918 break;
2919 }
e16821bc
JM
2920 if (wdev->beacon_interval) {
2921 if (!dev || !rdev->ops->set_ap_chanwidth ||
2922 !(rdev->wiphy.features &
2923 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
2924 result = -EBUSY;
2925 break;
2926 }
2927
2928 /* Only allow dynamic channel width changes */
2929 if (chandef.chan != wdev->preset_chandef.chan) {
2930 result = -EBUSY;
2931 break;
2932 }
2933 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
2934 if (result)
2935 break;
2936 }
683b6d3b 2937 wdev->preset_chandef = chandef;
aa430da4
JB
2938 result = 0;
2939 break;
cc1d2806 2940 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 2941 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 2942 break;
e8c9bd5b 2943 case NL80211_IFTYPE_MONITOR:
683b6d3b 2944 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 2945 break;
aa430da4 2946 default:
e8c9bd5b 2947 result = -EINVAL;
f444de05 2948 }
f444de05
JB
2949
2950 return result;
2951}
2952
2953static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
2954{
4c476991
JB
2955 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2956 struct net_device *netdev = info->user_ptr[1];
f444de05 2957
e16821bc 2958 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
2959}
2960
e8347eba
BJ
2961static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
2962{
43b19952
JB
2963 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2964 struct net_device *dev = info->user_ptr[1];
2965 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 2966 const u8 *bssid;
e8347eba
BJ
2967
2968 if (!info->attrs[NL80211_ATTR_MAC])
2969 return -EINVAL;
2970
43b19952
JB
2971 if (netif_running(dev))
2972 return -EBUSY;
e8347eba 2973
43b19952
JB
2974 if (!rdev->ops->set_wds_peer)
2975 return -EOPNOTSUPP;
e8347eba 2976
43b19952
JB
2977 if (wdev->iftype != NL80211_IFTYPE_WDS)
2978 return -EOPNOTSUPP;
e8347eba
BJ
2979
2980 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 2981 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
2982}
2983
55682965
JB
2984static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2985{
2986 struct cfg80211_registered_device *rdev;
f444de05
JB
2987 struct net_device *netdev = NULL;
2988 struct wireless_dev *wdev;
a1e567c8 2989 int result = 0, rem_txq_params = 0;
31888487 2990 struct nlattr *nl_txq_params;
b9a5f8ca
JM
2991 u32 changed;
2992 u8 retry_short = 0, retry_long = 0;
2993 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 2994 u8 coverage_class = 0;
52539ca8 2995 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
55682965 2996
5fe231e8
JB
2997 ASSERT_RTNL();
2998
f444de05
JB
2999 /*
3000 * Try to find the wiphy and netdev. Normally this
3001 * function shouldn't need the netdev, but this is
3002 * done for backward compatibility -- previously
3003 * setting the channel was done per wiphy, but now
3004 * it is per netdev. Previous userland like hostapd
3005 * also passed a netdev to set_wiphy, so that it is
3006 * possible to let that go to the right netdev!
3007 */
4bbf4d56 3008
f444de05
JB
3009 if (info->attrs[NL80211_ATTR_IFINDEX]) {
3010 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
3011
7f2b8562 3012 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 3013 if (netdev && netdev->ieee80211_ptr)
f26cbf40 3014 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 3015 else
f444de05 3016 netdev = NULL;
4bbf4d56
JB
3017 }
3018
f444de05 3019 if (!netdev) {
878d9ec7
JB
3020 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
3021 info->attrs);
5fe231e8 3022 if (IS_ERR(rdev))
4c476991 3023 return PTR_ERR(rdev);
f444de05
JB
3024 wdev = NULL;
3025 netdev = NULL;
3026 result = 0;
71fe96bf 3027 } else
f444de05 3028 wdev = netdev->ieee80211_ptr;
f444de05
JB
3029
3030 /*
3031 * end workaround code, by now the rdev is available
3032 * and locked, and wdev may or may not be NULL.
3033 */
4bbf4d56
JB
3034
3035 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
3036 result = cfg80211_dev_rename(
3037 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 3038
4bbf4d56 3039 if (result)
7f2b8562 3040 return result;
31888487
JM
3041
3042 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
3043 struct ieee80211_txq_params txq_params;
3044 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
3045
7f2b8562
YX
3046 if (!rdev->ops->set_txq_params)
3047 return -EOPNOTSUPP;
31888487 3048
7f2b8562
YX
3049 if (!netdev)
3050 return -EINVAL;
f70f01c2 3051
133a3ff2 3052 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
3053 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3054 return -EINVAL;
133a3ff2 3055
7f2b8562
YX
3056 if (!netif_running(netdev))
3057 return -ENETDOWN;
2b5f8b0b 3058
31888487
JM
3059 nla_for_each_nested(nl_txq_params,
3060 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
3061 rem_txq_params) {
8cb08174
JB
3062 result = nla_parse_nested_deprecated(tb,
3063 NL80211_TXQ_ATTR_MAX,
3064 nl_txq_params,
3065 txq_params_policy,
3066 info->extack);
ae811e21
JB
3067 if (result)
3068 return result;
31888487
JM
3069 result = parse_txq_params(tb, &txq_params);
3070 if (result)
7f2b8562 3071 return result;
31888487 3072
e35e4d28
HG
3073 result = rdev_set_txq_params(rdev, netdev,
3074 &txq_params);
31888487 3075 if (result)
7f2b8562 3076 return result;
31888487
JM
3077 }
3078 }
55682965 3079
72bdcf34 3080 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
3081 result = __nl80211_set_channel(
3082 rdev,
3083 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
3084 info);
72bdcf34 3085 if (result)
7f2b8562 3086 return result;
72bdcf34
JM
3087 }
3088
98d2ff8b 3089 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 3090 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
3091 enum nl80211_tx_power_setting type;
3092 int idx, mbm = 0;
3093
c8442118
JB
3094 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
3095 txp_wdev = NULL;
3096
7f2b8562
YX
3097 if (!rdev->ops->set_tx_power)
3098 return -EOPNOTSUPP;
98d2ff8b
JO
3099
3100 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
3101 type = nla_get_u32(info->attrs[idx]);
3102
3103 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
3104 (type != NL80211_TX_POWER_AUTOMATIC))
3105 return -EINVAL;
98d2ff8b
JO
3106
3107 if (type != NL80211_TX_POWER_AUTOMATIC) {
3108 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
3109 mbm = nla_get_u32(info->attrs[idx]);
3110 }
3111
c8442118 3112 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 3113 if (result)
7f2b8562 3114 return result;
98d2ff8b
JO
3115 }
3116
afe0cbf8
BR
3117 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
3118 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
3119 u32 tx_ant, rx_ant;
7a087e74 3120
7f531e03
BR
3121 if ((!rdev->wiphy.available_antennas_tx &&
3122 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
3123 !rdev->ops->set_antenna)
3124 return -EOPNOTSUPP;
afe0cbf8
BR
3125
3126 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
3127 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
3128
a7ffac95 3129 /* reject antenna configurations which don't match the
7f531e03
BR
3130 * available antenna masks, except for the "all" mask */
3131 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
3132 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
3133 return -EINVAL;
a7ffac95 3134
7f531e03
BR
3135 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
3136 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 3137
e35e4d28 3138 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 3139 if (result)
7f2b8562 3140 return result;
afe0cbf8
BR
3141 }
3142
b9a5f8ca
JM
3143 changed = 0;
3144
3145 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
3146 retry_short = nla_get_u8(
3147 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562 3148
b9a5f8ca
JM
3149 changed |= WIPHY_PARAM_RETRY_SHORT;
3150 }
3151
3152 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
3153 retry_long = nla_get_u8(
3154 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562 3155
b9a5f8ca
JM
3156 changed |= WIPHY_PARAM_RETRY_LONG;
3157 }
3158
3159 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
3160 frag_threshold = nla_get_u32(
3161 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
3162 if (frag_threshold < 256)
3163 return -EINVAL;
3164
b9a5f8ca
JM
3165 if (frag_threshold != (u32) -1) {
3166 /*
3167 * Fragments (apart from the last one) are required to
3168 * have even length. Make the fragmentation code
3169 * simpler by stripping LSB should someone try to use
3170 * odd threshold value.
3171 */
3172 frag_threshold &= ~0x1;
3173 }
3174 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
3175 }
3176
3177 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
3178 rts_threshold = nla_get_u32(
3179 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
3180 changed |= WIPHY_PARAM_RTS_THRESHOLD;
3181 }
3182
81077e82 3183 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3057dbfd
LB
3184 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
3185 return -EINVAL;
3186
81077e82
LT
3187 coverage_class = nla_get_u8(
3188 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
3189 changed |= WIPHY_PARAM_COVERAGE_CLASS;
3190 }
3191
3057dbfd
LB
3192 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
3193 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
3194 return -EOPNOTSUPP;
3195
3196 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
3197 }
3198
52539ca8
THJ
3199 if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
3200 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3201 NL80211_EXT_FEATURE_TXQS))
3202 return -EOPNOTSUPP;
3203 txq_limit = nla_get_u32(
3204 info->attrs[NL80211_ATTR_TXQ_LIMIT]);
3205 changed |= WIPHY_PARAM_TXQ_LIMIT;
3206 }
3207
3208 if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
3209 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3210 NL80211_EXT_FEATURE_TXQS))
3211 return -EOPNOTSUPP;
3212 txq_memory_limit = nla_get_u32(
3213 info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
3214 changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
3215 }
3216
3217 if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
3218 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3219 NL80211_EXT_FEATURE_TXQS))
3220 return -EOPNOTSUPP;
3221 txq_quantum = nla_get_u32(
3222 info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
3223 changed |= WIPHY_PARAM_TXQ_QUANTUM;
3224 }
3225
b9a5f8ca
JM
3226 if (changed) {
3227 u8 old_retry_short, old_retry_long;
3228 u32 old_frag_threshold, old_rts_threshold;
81077e82 3229 u8 old_coverage_class;
52539ca8 3230 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
b9a5f8ca 3231
7f2b8562
YX
3232 if (!rdev->ops->set_wiphy_params)
3233 return -EOPNOTSUPP;
b9a5f8ca
JM
3234
3235 old_retry_short = rdev->wiphy.retry_short;
3236 old_retry_long = rdev->wiphy.retry_long;
3237 old_frag_threshold = rdev->wiphy.frag_threshold;
3238 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 3239 old_coverage_class = rdev->wiphy.coverage_class;
52539ca8
THJ
3240 old_txq_limit = rdev->wiphy.txq_limit;
3241 old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
3242 old_txq_quantum = rdev->wiphy.txq_quantum;
b9a5f8ca
JM
3243
3244 if (changed & WIPHY_PARAM_RETRY_SHORT)
3245 rdev->wiphy.retry_short = retry_short;
3246 if (changed & WIPHY_PARAM_RETRY_LONG)
3247 rdev->wiphy.retry_long = retry_long;
3248 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
3249 rdev->wiphy.frag_threshold = frag_threshold;
3250 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
3251 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
3252 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
3253 rdev->wiphy.coverage_class = coverage_class;
52539ca8
THJ
3254 if (changed & WIPHY_PARAM_TXQ_LIMIT)
3255 rdev->wiphy.txq_limit = txq_limit;
3256 if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
3257 rdev->wiphy.txq_memory_limit = txq_memory_limit;
3258 if (changed & WIPHY_PARAM_TXQ_QUANTUM)
3259 rdev->wiphy.txq_quantum = txq_quantum;
b9a5f8ca 3260
e35e4d28 3261 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
3262 if (result) {
3263 rdev->wiphy.retry_short = old_retry_short;
3264 rdev->wiphy.retry_long = old_retry_long;
3265 rdev->wiphy.frag_threshold = old_frag_threshold;
3266 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 3267 rdev->wiphy.coverage_class = old_coverage_class;
52539ca8
THJ
3268 rdev->wiphy.txq_limit = old_txq_limit;
3269 rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
3270 rdev->wiphy.txq_quantum = old_txq_quantum;
9189ee31 3271 return result;
b9a5f8ca
JM
3272 }
3273 }
7f2b8562 3274 return 0;
55682965
JB
3275}
3276
683b6d3b 3277static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 3278 const struct cfg80211_chan_def *chandef)
683b6d3b 3279{
601555cd
JB
3280 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
3281 return -EINVAL;
3d9d1d66 3282
683b6d3b
JB
3283 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
3284 chandef->chan->center_freq))
3285 return -ENOBUFS;
3d9d1d66
JB
3286 switch (chandef->width) {
3287 case NL80211_CHAN_WIDTH_20_NOHT:
3288 case NL80211_CHAN_WIDTH_20:
3289 case NL80211_CHAN_WIDTH_40:
3290 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3291 cfg80211_get_chandef_type(chandef)))
3292 return -ENOBUFS;
3293 break;
3294 default:
3295 break;
3296 }
3297 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
3298 return -ENOBUFS;
3299 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
3300 return -ENOBUFS;
3301 if (chandef->center_freq2 &&
3302 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
3303 return -ENOBUFS;
3304 return 0;
3305}
3306
15e47304 3307static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 3308 struct cfg80211_registered_device *rdev,
3d1a5bbf
AZ
3309 struct wireless_dev *wdev,
3310 enum nl80211_commands cmd)
55682965 3311{
72fb2abc 3312 struct net_device *dev = wdev->netdev;
55682965
JB
3313 void *hdr;
3314
3d1a5bbf
AZ
3315 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
3316 cmd != NL80211_CMD_DEL_INTERFACE &&
3317 cmd != NL80211_CMD_SET_INTERFACE);
8f894be2
TB
3318
3319 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
3320 if (!hdr)
3321 return -1;
3322
72fb2abc
JB
3323 if (dev &&
3324 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 3325 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
3326 goto nla_put_failure;
3327
3328 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3329 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
3330 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
3331 NL80211_ATTR_PAD) ||
98104fde 3332 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
3333 nla_put_u32(msg, NL80211_ATTR_GENERATION,
3334 rdev->devlist_generation ^
446faa15
AQ
3335 (cfg80211_rdev_list_generation << 2)) ||
3336 nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
9360ffd1 3337 goto nla_put_failure;
f5ea9120 3338
5b7ccaf3 3339 if (rdev->ops->get_channel) {
683b6d3b 3340 int ret;
f43e5210 3341 struct cfg80211_chan_def chandef = {};
683b6d3b
JB
3342
3343 ret = rdev_get_channel(rdev, wdev, &chandef);
3344 if (ret == 0) {
3345 if (nl80211_send_chandef(msg, &chandef))
3346 goto nla_put_failure;
3347 }
d91df0e3
PF
3348 }
3349
d55d0d59
RM
3350 if (rdev->ops->get_tx_power) {
3351 int dbm, ret;
3352
3353 ret = rdev_get_tx_power(rdev, wdev, &dbm);
3354 if (ret == 0 &&
3355 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
3356 DBM_TO_MBM(dbm)))
3357 goto nla_put_failure;
3358 }
3359
44905265
JB
3360 wdev_lock(wdev);
3361 switch (wdev->iftype) {
3362 case NL80211_IFTYPE_AP:
3363 if (wdev->ssid_len &&
3364 nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
4564b187 3365 goto nla_put_failure_locked;
44905265
JB
3366 break;
3367 case NL80211_IFTYPE_STATION:
3368 case NL80211_IFTYPE_P2P_CLIENT:
3369 case NL80211_IFTYPE_ADHOC: {
3370 const u8 *ssid_ie;
3371 if (!wdev->current_bss)
3372 break;
7a94b8c2 3373 rcu_read_lock();
44905265
JB
3374 ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
3375 WLAN_EID_SSID);
7a94b8c2
DB
3376 if (ssid_ie &&
3377 nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2))
3378 goto nla_put_failure_rcu_locked;
3379 rcu_read_unlock();
44905265
JB
3380 break;
3381 }
3382 default:
3383 /* nothing */
3384 break;
b84e7a05 3385 }
44905265 3386 wdev_unlock(wdev);
b84e7a05 3387
52539ca8
THJ
3388 if (rdev->ops->get_txq_stats) {
3389 struct cfg80211_txq_stats txqstats = {};
3390 int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
3391
3392 if (ret == 0 &&
3393 !nl80211_put_txq_stats(msg, &txqstats,
3394 NL80211_ATTR_TXQ_STATS))
3395 goto nla_put_failure;
3396 }
3397
053c095a
JB
3398 genlmsg_end(msg, hdr);
3399 return 0;
55682965 3400
7a94b8c2
DB
3401 nla_put_failure_rcu_locked:
3402 rcu_read_unlock();
4564b187
JB
3403 nla_put_failure_locked:
3404 wdev_unlock(wdev);
55682965 3405 nla_put_failure:
bc3ed28c
TG
3406 genlmsg_cancel(msg, hdr);
3407 return -EMSGSIZE;
55682965
JB
3408}
3409
3410static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
3411{
3412 int wp_idx = 0;
3413 int if_idx = 0;
3414 int wp_start = cb->args[0];
3415 int if_start = cb->args[1];
b7fb44da 3416 int filter_wiphy = -1;
f5ea9120 3417 struct cfg80211_registered_device *rdev;
55682965 3418 struct wireless_dev *wdev;
ea90e0dc 3419 int ret;
55682965 3420
5fe231e8 3421 rtnl_lock();
b7fb44da
DK
3422 if (!cb->args[2]) {
3423 struct nl80211_dump_wiphy_state state = {
3424 .filter_wiphy = -1,
3425 };
b7fb44da
DK
3426
3427 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
3428 if (ret)
ea90e0dc 3429 goto out_unlock;
b7fb44da
DK
3430
3431 filter_wiphy = state.filter_wiphy;
3432
3433 /*
3434 * if filtering, set cb->args[2] to +1 since 0 is the default
3435 * value needed to determine that parsing is necessary.
3436 */
3437 if (filter_wiphy >= 0)
3438 cb->args[2] = filter_wiphy + 1;
3439 else
3440 cb->args[2] = -1;
3441 } else if (cb->args[2] > 0) {
3442 filter_wiphy = cb->args[2] - 1;
3443 }
3444
f5ea9120
JB
3445 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
3446 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 3447 continue;
bba95fef
JB
3448 if (wp_idx < wp_start) {
3449 wp_idx++;
55682965 3450 continue;
bba95fef 3451 }
b7fb44da
DK
3452
3453 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
3454 continue;
3455
55682965
JB
3456 if_idx = 0;
3457
53873f13 3458 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
3459 if (if_idx < if_start) {
3460 if_idx++;
55682965 3461 continue;
bba95fef 3462 }
15e47304 3463 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 3464 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3d1a5bbf
AZ
3465 rdev, wdev,
3466 NL80211_CMD_NEW_INTERFACE) < 0) {
bba95fef
JB
3467 goto out;
3468 }
3469 if_idx++;
55682965 3470 }
bba95fef
JB
3471
3472 wp_idx++;
55682965 3473 }
bba95fef 3474 out:
55682965
JB
3475 cb->args[0] = wp_idx;
3476 cb->args[1] = if_idx;
3477
ea90e0dc
JB
3478 ret = skb->len;
3479 out_unlock:
3480 rtnl_unlock();
3481
3482 return ret;
55682965
JB
3483}
3484
3485static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
3486{
3487 struct sk_buff *msg;
1b8ec87a 3488 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 3489 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3490
fd2120ca 3491 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 3492 if (!msg)
4c476991 3493 return -ENOMEM;
55682965 3494
15e47304 3495 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 3496 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
4c476991
JB
3497 nlmsg_free(msg);
3498 return -ENOBUFS;
3499 }
55682965 3500
134e6375 3501 return genlmsg_reply(msg, info);
55682965
JB
3502}
3503
66f7ac50
MW
3504static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
3505 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
3506 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
3507 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
3508 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
3509 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 3510 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
3511};
3512
3513static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
3514{
3515 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
3516 int flag;
3517
3518 *mntrflags = 0;
3519
3520 if (!nla)
3521 return -EINVAL;
3522
8cb08174 3523 if (nla_parse_nested_deprecated(flags, NL80211_MNTR_FLAG_MAX, nla, mntr_flags_policy, NULL))
66f7ac50
MW
3524 return -EINVAL;
3525
3526 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
3527 if (flags[flag])
3528 *mntrflags |= (1<<flag);
3529
818a986e
JB
3530 *mntrflags |= MONITOR_FLAG_CHANGED;
3531
66f7ac50
MW
3532 return 0;
3533}
3534
1db77596
JB
3535static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
3536 enum nl80211_iftype type,
3537 struct genl_info *info,
3538 struct vif_params *params)
3539{
3540 bool change = false;
3541 int err;
3542
3543 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
3544 if (type != NL80211_IFTYPE_MONITOR)
3545 return -EINVAL;
3546
3547 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
3548 &params->flags);
3549 if (err)
3550 return err;
3551
3552 change = true;
3553 }
3554
3555 if (params->flags & MONITOR_FLAG_ACTIVE &&
3556 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
3557 return -EOPNOTSUPP;
3558
3559 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
3560 const u8 *mumimo_groups;
3561 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3562
3563 if (type != NL80211_IFTYPE_MONITOR)
3564 return -EINVAL;
3565
3566 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3567 return -EOPNOTSUPP;
3568
3569 mumimo_groups =
3570 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
3571
3572 /* bits 0 and 63 are reserved and must be zero */
4954601f
JB
3573 if ((mumimo_groups[0] & BIT(0)) ||
3574 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
1db77596
JB
3575 return -EINVAL;
3576
3577 params->vht_mumimo_groups = mumimo_groups;
3578 change = true;
3579 }
3580
3581 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
3582 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3583
3584 if (type != NL80211_IFTYPE_MONITOR)
3585 return -EINVAL;
3586
3587 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3588 return -EOPNOTSUPP;
3589
3590 params->vht_mumimo_follow_addr =
3591 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
3592 change = true;
3593 }
3594
3595 return change ? 1 : 0;
3596}
3597
9bc383de 3598static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
3599 struct net_device *netdev, u8 use_4addr,
3600 enum nl80211_iftype iftype)
9bc383de 3601{
ad4bb6f8 3602 if (!use_4addr) {
f350a0a8 3603 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 3604 return -EBUSY;
9bc383de 3605 return 0;
ad4bb6f8 3606 }
9bc383de
JB
3607
3608 switch (iftype) {
3609 case NL80211_IFTYPE_AP_VLAN:
3610 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
3611 return 0;
3612 break;
3613 case NL80211_IFTYPE_STATION:
3614 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
3615 return 0;
3616 break;
3617 default:
3618 break;
3619 }
3620
3621 return -EOPNOTSUPP;
3622}
3623
55682965
JB
3624static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3625{
4c476991 3626 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3627 struct vif_params params;
e36d56b6 3628 int err;
04a773ad 3629 enum nl80211_iftype otype, ntype;
4c476991 3630 struct net_device *dev = info->user_ptr[1];
ac7f9cfa 3631 bool change = false;
55682965 3632
2ec600d6
LCC
3633 memset(&params, 0, sizeof(params));
3634
04a773ad 3635 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 3636
723b038d 3637 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 3638 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 3639 if (otype != ntype)
ac7f9cfa 3640 change = true;
723b038d
JB
3641 }
3642
92ffe055 3643 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
3644 struct wireless_dev *wdev = dev->ieee80211_ptr;
3645
4c476991
JB
3646 if (ntype != NL80211_IFTYPE_MESH_POINT)
3647 return -EINVAL;
29cbe68c
JB
3648 if (netif_running(dev))
3649 return -EBUSY;
3650
3651 wdev_lock(wdev);
3652 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3653 IEEE80211_MAX_MESH_ID_LEN);
3654 wdev->mesh_id_up_len =
3655 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3656 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3657 wdev->mesh_id_up_len);
3658 wdev_unlock(wdev);
2ec600d6
LCC
3659 }
3660
8b787643
FF
3661 if (info->attrs[NL80211_ATTR_4ADDR]) {
3662 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
3663 change = true;
ad4bb6f8 3664 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 3665 if (err)
4c476991 3666 return err;
8b787643
FF
3667 } else {
3668 params.use_4addr = -1;
3669 }
3670
1db77596
JB
3671 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
3672 if (err < 0)
3673 return err;
3674 if (err > 0)
c6e6a0c8 3675 change = true;
e057d3c3 3676
ac7f9cfa 3677 if (change)
818a986e 3678 err = cfg80211_change_iface(rdev, dev, ntype, &params);
ac7f9cfa
JB
3679 else
3680 err = 0;
60719ffd 3681
9bc383de
JB
3682 if (!err && params.use_4addr != -1)
3683 dev->ieee80211_ptr->use_4addr = params.use_4addr;
3684
3d1a5bbf
AZ
3685 if (change && !err) {
3686 struct wireless_dev *wdev = dev->ieee80211_ptr;
3687
3688 nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
3689 }
3690
55682965
JB
3691 return err;
3692}
3693
3694static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
3695{
4c476991 3696 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3697 struct vif_params params;
84efbb84 3698 struct wireless_dev *wdev;
896ff063 3699 struct sk_buff *msg;
55682965
JB
3700 int err;
3701 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
3702
78f22b6a
JB
3703 /* to avoid failing a new interface creation due to pending removal */
3704 cfg80211_destroy_ifaces(rdev);
3705
2ec600d6
LCC
3706 memset(&params, 0, sizeof(params));
3707
55682965
JB
3708 if (!info->attrs[NL80211_ATTR_IFNAME])
3709 return -EINVAL;
3710
ab0d76f6 3711 if (info->attrs[NL80211_ATTR_IFTYPE])
55682965 3712 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
55682965 3713
33d915d9 3714 if (!rdev->ops->add_virtual_intf)
4c476991 3715 return -EOPNOTSUPP;
55682965 3716
cb3b7d87 3717 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
3718 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
3719 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
3720 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
3721 ETH_ALEN);
3722 if (!is_valid_ether_addr(params.macaddr))
3723 return -EADDRNOTAVAIL;
3724 }
3725
9bc383de 3726 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 3727 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 3728 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 3729 if (err)
4c476991 3730 return err;
9bc383de 3731 }
8b787643 3732
e6f40511 3733 if (!cfg80211_iftype_allowed(&rdev->wiphy, type, params.use_4addr, 0))
33d915d9
MP
3734 return -EOPNOTSUPP;
3735
1db77596
JB
3736 err = nl80211_parse_mon_options(rdev, type, info, &params);
3737 if (err < 0)
3738 return err;
e057d3c3 3739
a18c7192
JB
3740 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3741 if (!msg)
3742 return -ENOMEM;
3743
e35e4d28
HG
3744 wdev = rdev_add_virtual_intf(rdev,
3745 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
818a986e 3746 NET_NAME_USER, type, &params);
d687cbb7
RM
3747 if (WARN_ON(!wdev)) {
3748 nlmsg_free(msg);
3749 return -EPROTO;
3750 } else if (IS_ERR(wdev)) {
1c90f9d4 3751 nlmsg_free(msg);
84efbb84 3752 return PTR_ERR(wdev);
1c90f9d4 3753 }
2ec600d6 3754
18e5ca65 3755 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
3756 wdev->owner_nlportid = info->snd_portid;
3757
98104fde
JB
3758 switch (type) {
3759 case NL80211_IFTYPE_MESH_POINT:
3760 if (!info->attrs[NL80211_ATTR_MESH_ID])
3761 break;
29cbe68c
JB
3762 wdev_lock(wdev);
3763 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3764 IEEE80211_MAX_MESH_ID_LEN);
3765 wdev->mesh_id_up_len =
3766 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3767 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3768 wdev->mesh_id_up_len);
3769 wdev_unlock(wdev);
98104fde 3770 break;
cb3b7d87 3771 case NL80211_IFTYPE_NAN:
98104fde
JB
3772 case NL80211_IFTYPE_P2P_DEVICE:
3773 /*
cb3b7d87 3774 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
3775 * through the netdev notifier and must be added here
3776 */
e4d4216e 3777 cfg80211_init_wdev(rdev, wdev);
98104fde
JB
3778 break;
3779 default:
3780 break;
29cbe68c
JB
3781 }
3782
15e47304 3783 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 3784 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
1c90f9d4
JB
3785 nlmsg_free(msg);
3786 return -ENOBUFS;
3787 }
3788
3789 return genlmsg_reply(msg, info);
55682965
JB
3790}
3791
3792static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
3793{
4c476991 3794 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 3795 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3796
4c476991
JB
3797 if (!rdev->ops->del_virtual_intf)
3798 return -EOPNOTSUPP;
55682965 3799
84efbb84
JB
3800 /*
3801 * If we remove a wireless device without a netdev then clear
3802 * user_ptr[1] so that nl80211_post_doit won't dereference it
3803 * to check if it needs to do dev_put(). Otherwise it crashes
3804 * since the wdev has been freed, unlike with a netdev where
3805 * we need the dev_put() for the netdev to really be freed.
3806 */
3807 if (!wdev->netdev)
3808 info->user_ptr[1] = NULL;
3809
7f8ed01e 3810 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
3811}
3812
1d9d9213
SW
3813static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
3814{
3815 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3816 struct net_device *dev = info->user_ptr[1];
3817 u16 noack_map;
3818
3819 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
3820 return -EINVAL;
3821
3822 if (!rdev->ops->set_noack_map)
3823 return -EOPNOTSUPP;
3824
3825 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
3826
e35e4d28 3827 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
3828}
3829
41ade00f
JB
3830struct get_key_cookie {
3831 struct sk_buff *msg;
3832 int error;
b9454e83 3833 int idx;
41ade00f
JB
3834};
3835
3836static void get_key_callback(void *c, struct key_params *params)
3837{
b9454e83 3838 struct nlattr *key;
41ade00f
JB
3839 struct get_key_cookie *cookie = c;
3840
9360ffd1
DM
3841 if ((params->key &&
3842 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
3843 params->key_len, params->key)) ||
3844 (params->seq &&
3845 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
3846 params->seq_len, params->seq)) ||
3847 (params->cipher &&
3848 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
3849 params->cipher)))
3850 goto nla_put_failure;
41ade00f 3851
ae0be8de 3852 key = nla_nest_start_noflag(cookie->msg, NL80211_ATTR_KEY);
b9454e83
JB
3853 if (!key)
3854 goto nla_put_failure;
3855
9360ffd1
DM
3856 if ((params->key &&
3857 nla_put(cookie->msg, NL80211_KEY_DATA,
3858 params->key_len, params->key)) ||
3859 (params->seq &&
3860 nla_put(cookie->msg, NL80211_KEY_SEQ,
3861 params->seq_len, params->seq)) ||
3862 (params->cipher &&
3863 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
3864 params->cipher)))
3865 goto nla_put_failure;
b9454e83 3866
efdfce72 3867 if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
9360ffd1 3868 goto nla_put_failure;
b9454e83
JB
3869
3870 nla_nest_end(cookie->msg, key);
3871
41ade00f
JB
3872 return;
3873 nla_put_failure:
3874 cookie->error = 1;
3875}
3876
3877static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3878{
4c476991 3879 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3880 int err;
4c476991 3881 struct net_device *dev = info->user_ptr[1];
41ade00f 3882 u8 key_idx = 0;
e31b8213
JB
3883 const u8 *mac_addr = NULL;
3884 bool pairwise;
41ade00f
JB
3885 struct get_key_cookie cookie = {
3886 .error = 0,
3887 };
3888 void *hdr;
3889 struct sk_buff *msg;
3890
56be393f 3891 if (info->attrs[NL80211_ATTR_KEY_IDX]) {
41ade00f 3892 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
56be393f
JM
3893 if (key_idx > 5 &&
3894 !wiphy_ext_feature_isset(
3895 &rdev->wiphy,
3896 NL80211_EXT_FEATURE_BEACON_PROTECTION))
3897 return -EINVAL;
3898 }
41ade00f 3899
41ade00f
JB
3900 if (info->attrs[NL80211_ATTR_MAC])
3901 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3902
e31b8213
JB
3903 pairwise = !!mac_addr;
3904 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3905 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 3906
e31b8213
JB
3907 if (kt != NL80211_KEYTYPE_GROUP &&
3908 kt != NL80211_KEYTYPE_PAIRWISE)
3909 return -EINVAL;
3910 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
3911 }
3912
4c476991
JB
3913 if (!rdev->ops->get_key)
3914 return -EOPNOTSUPP;
41ade00f 3915
0fa7b391
JB
3916 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3917 return -ENOENT;
3918
fd2120ca 3919 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3920 if (!msg)
3921 return -ENOMEM;
41ade00f 3922
15e47304 3923 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 3924 NL80211_CMD_NEW_KEY);
cb35fba3 3925 if (!hdr)
9fe271af 3926 goto nla_put_failure;
41ade00f
JB
3927
3928 cookie.msg = msg;
b9454e83 3929 cookie.idx = key_idx;
41ade00f 3930
9360ffd1
DM
3931 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3932 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
3933 goto nla_put_failure;
3934 if (mac_addr &&
3935 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
3936 goto nla_put_failure;
41ade00f 3937
e35e4d28
HG
3938 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
3939 get_key_callback);
41ade00f
JB
3940
3941 if (err)
6c95e2a2 3942 goto free_msg;
41ade00f
JB
3943
3944 if (cookie.error)
3945 goto nla_put_failure;
3946
3947 genlmsg_end(msg, hdr);
4c476991 3948 return genlmsg_reply(msg, info);
41ade00f
JB
3949
3950 nla_put_failure:
3951 err = -ENOBUFS;
6c95e2a2 3952 free_msg:
41ade00f 3953 nlmsg_free(msg);
41ade00f
JB
3954 return err;
3955}
3956
3957static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
3958{
4c476991 3959 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 3960 struct key_parse key;
41ade00f 3961 int err;
4c476991 3962 struct net_device *dev = info->user_ptr[1];
41ade00f 3963
b9454e83
JB
3964 err = nl80211_parse_key(info, &key);
3965 if (err)
3966 return err;
41ade00f 3967
b9454e83 3968 if (key.idx < 0)
41ade00f
JB
3969 return -EINVAL;
3970
6cdd3979
AW
3971 /* Only support setting default key and
3972 * Extended Key ID action NL80211_KEY_SET_TX.
3973 */
56be393f 3974 if (!key.def && !key.defmgmt && !key.defbeacon &&
6cdd3979 3975 !(key.p.mode == NL80211_KEY_SET_TX))
41ade00f
JB
3976 return -EINVAL;
3977
dbd2fd65 3978 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 3979
dbd2fd65
JB
3980 if (key.def) {
3981 if (!rdev->ops->set_default_key) {
3982 err = -EOPNOTSUPP;
3983 goto out;
3984 }
41ade00f 3985
dbd2fd65
JB
3986 err = nl80211_key_allowed(dev->ieee80211_ptr);
3987 if (err)
3988 goto out;
3989
e35e4d28 3990 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
3991 key.def_uni, key.def_multi);
3992
3993 if (err)
3994 goto out;
fffd0934 3995
3d23e349 3996#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
3997 dev->ieee80211_ptr->wext.default_key = key.idx;
3998#endif
6cdd3979 3999 } else if (key.defmgmt) {
dbd2fd65
JB
4000 if (key.def_uni || !key.def_multi) {
4001 err = -EINVAL;
4002 goto out;
4003 }
4004
4005 if (!rdev->ops->set_default_mgmt_key) {
4006 err = -EOPNOTSUPP;
4007 goto out;
4008 }
4009
4010 err = nl80211_key_allowed(dev->ieee80211_ptr);
4011 if (err)
4012 goto out;
4013
e35e4d28 4014 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
4015 if (err)
4016 goto out;
4017
4018#ifdef CONFIG_CFG80211_WEXT
4019 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 4020#endif
56be393f
JM
4021 } else if (key.defbeacon) {
4022 if (key.def_uni || !key.def_multi) {
4023 err = -EINVAL;
4024 goto out;
4025 }
4026
4027 if (!rdev->ops->set_default_beacon_key) {
4028 err = -EOPNOTSUPP;
4029 goto out;
4030 }
4031
4032 err = nl80211_key_allowed(dev->ieee80211_ptr);
4033 if (err)
4034 goto out;
4035
4036 err = rdev_set_default_beacon_key(rdev, dev, key.idx);
4037 if (err)
4038 goto out;
6cdd3979
AW
4039 } else if (key.p.mode == NL80211_KEY_SET_TX &&
4040 wiphy_ext_feature_isset(&rdev->wiphy,
4041 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
4042 u8 *mac_addr = NULL;
4043
4044 if (info->attrs[NL80211_ATTR_MAC])
4045 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4046
4047 if (!mac_addr || key.idx < 0 || key.idx > 1) {
4048 err = -EINVAL;
4049 goto out;
4050 }
dbd2fd65 4051
6cdd3979
AW
4052 err = rdev_add_key(rdev, dev, key.idx,
4053 NL80211_KEYTYPE_PAIRWISE,
4054 mac_addr, &key.p);
4055 } else {
4056 err = -EINVAL;
4057 }
dbd2fd65 4058 out:
fffd0934 4059 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4060
41ade00f
JB
4061 return err;
4062}
4063
4064static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
4065{
4c476991 4066 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 4067 int err;
4c476991 4068 struct net_device *dev = info->user_ptr[1];
b9454e83 4069 struct key_parse key;
e31b8213 4070 const u8 *mac_addr = NULL;
41ade00f 4071
b9454e83
JB
4072 err = nl80211_parse_key(info, &key);
4073 if (err)
4074 return err;
41ade00f 4075
f8af764b
JM
4076 if (!key.p.key) {
4077 GENL_SET_ERR_MSG(info, "no key");
41ade00f 4078 return -EINVAL;
f8af764b 4079 }
41ade00f 4080
41ade00f
JB
4081 if (info->attrs[NL80211_ATTR_MAC])
4082 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4083
e31b8213
JB
4084 if (key.type == -1) {
4085 if (mac_addr)
4086 key.type = NL80211_KEYTYPE_PAIRWISE;
4087 else
4088 key.type = NL80211_KEYTYPE_GROUP;
4089 }
4090
4091 /* for now */
4092 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
f8af764b
JM
4093 key.type != NL80211_KEYTYPE_GROUP) {
4094 GENL_SET_ERR_MSG(info, "key type not pairwise or group");
e31b8213 4095 return -EINVAL;
f8af764b 4096 }
e31b8213 4097
14f34e36
GG
4098 if (key.type == NL80211_KEYTYPE_GROUP &&
4099 info->attrs[NL80211_ATTR_VLAN_ID])
4100 key.p.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
4101
4c476991
JB
4102 if (!rdev->ops->add_key)
4103 return -EOPNOTSUPP;
25e47c18 4104
e31b8213
JB
4105 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
4106 key.type == NL80211_KEYTYPE_PAIRWISE,
f8af764b
JM
4107 mac_addr)) {
4108 GENL_SET_ERR_MSG(info, "key setting validation failed");
4c476991 4109 return -EINVAL;
f8af764b 4110 }
41ade00f 4111
fffd0934
JB
4112 wdev_lock(dev->ieee80211_ptr);
4113 err = nl80211_key_allowed(dev->ieee80211_ptr);
f8af764b
JM
4114 if (err)
4115 GENL_SET_ERR_MSG(info, "key not allowed");
4116 if (!err) {
e35e4d28
HG
4117 err = rdev_add_key(rdev, dev, key.idx,
4118 key.type == NL80211_KEYTYPE_PAIRWISE,
4119 mac_addr, &key.p);
f8af764b
JM
4120 if (err)
4121 GENL_SET_ERR_MSG(info, "key addition failed");
4122 }
fffd0934 4123 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4124
41ade00f
JB
4125 return err;
4126}
4127
4128static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
4129{
4c476991 4130 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 4131 int err;
4c476991 4132 struct net_device *dev = info->user_ptr[1];
41ade00f 4133 u8 *mac_addr = NULL;
b9454e83 4134 struct key_parse key;
41ade00f 4135
b9454e83
JB
4136 err = nl80211_parse_key(info, &key);
4137 if (err)
4138 return err;
41ade00f
JB
4139
4140 if (info->attrs[NL80211_ATTR_MAC])
4141 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4142
e31b8213
JB
4143 if (key.type == -1) {
4144 if (mac_addr)
4145 key.type = NL80211_KEYTYPE_PAIRWISE;
4146 else
4147 key.type = NL80211_KEYTYPE_GROUP;
4148 }
4149
4150 /* for now */
4151 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
4152 key.type != NL80211_KEYTYPE_GROUP)
4153 return -EINVAL;
4154
4c476991
JB
4155 if (!rdev->ops->del_key)
4156 return -EOPNOTSUPP;
41ade00f 4157
fffd0934
JB
4158 wdev_lock(dev->ieee80211_ptr);
4159 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 4160
0fa7b391 4161 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
4162 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4163 err = -ENOENT;
4164
fffd0934 4165 if (!err)
e35e4d28
HG
4166 err = rdev_del_key(rdev, dev, key.idx,
4167 key.type == NL80211_KEYTYPE_PAIRWISE,
4168 mac_addr);
41ade00f 4169
3d23e349 4170#ifdef CONFIG_CFG80211_WEXT
08645126 4171 if (!err) {
b9454e83 4172 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 4173 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 4174 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
4175 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
4176 }
4177#endif
fffd0934 4178 wdev_unlock(dev->ieee80211_ptr);
08645126 4179
41ade00f
JB
4180 return err;
4181}
4182
77765eaf
VT
4183/* This function returns an error or the number of nested attributes */
4184static int validate_acl_mac_addrs(struct nlattr *nl_attr)
4185{
4186 struct nlattr *attr;
4187 int n_entries = 0, tmp;
4188
4189 nla_for_each_nested(attr, nl_attr, tmp) {
4190 if (nla_len(attr) != ETH_ALEN)
4191 return -EINVAL;
4192
4193 n_entries++;
4194 }
4195
4196 return n_entries;
4197}
4198
4199/*
4200 * This function parses ACL information and allocates memory for ACL data.
4201 * On successful return, the calling function is responsible to free the
4202 * ACL buffer returned by this function.
4203 */
4204static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
4205 struct genl_info *info)
4206{
4207 enum nl80211_acl_policy acl_policy;
4208 struct nlattr *attr;
4209 struct cfg80211_acl_data *acl;
4210 int i = 0, n_entries, tmp;
4211
4212 if (!wiphy->max_acl_mac_addrs)
4213 return ERR_PTR(-EOPNOTSUPP);
4214
4215 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
4216 return ERR_PTR(-EINVAL);
4217
4218 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
4219 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
4220 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
4221 return ERR_PTR(-EINVAL);
4222
4223 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
4224 return ERR_PTR(-EINVAL);
4225
4226 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
4227 if (n_entries < 0)
4228 return ERR_PTR(n_entries);
4229
4230 if (n_entries > wiphy->max_acl_mac_addrs)
4231 return ERR_PTR(-ENOTSUPP);
4232
391d132c 4233 acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
77765eaf
VT
4234 if (!acl)
4235 return ERR_PTR(-ENOMEM);
4236
4237 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
4238 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
4239 i++;
4240 }
4241
4242 acl->n_acl_entries = n_entries;
4243 acl->acl_policy = acl_policy;
4244
4245 return acl;
4246}
4247
4248static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
4249{
4250 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4251 struct net_device *dev = info->user_ptr[1];
4252 struct cfg80211_acl_data *acl;
4253 int err;
4254
4255 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4256 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4257 return -EOPNOTSUPP;
4258
4259 if (!dev->ieee80211_ptr->beacon_interval)
4260 return -EINVAL;
4261
4262 acl = parse_acl_data(&rdev->wiphy, info);
4263 if (IS_ERR(acl))
4264 return PTR_ERR(acl);
4265
4266 err = rdev_set_mac_acl(rdev, dev, acl);
4267
4268 kfree(acl);
4269
4270 return err;
4271}
4272
a7c7fbff
PK
4273static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
4274 u8 *rates, u8 rates_len)
4275{
4276 u8 i;
4277 u32 mask = 0;
4278
4279 for (i = 0; i < rates_len; i++) {
4280 int rate = (rates[i] & 0x7f) * 5;
4281 int ridx;
4282
4283 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
4284 struct ieee80211_rate *srate =
4285 &sband->bitrates[ridx];
4286 if (rate == srate->bitrate) {
4287 mask |= 1 << ridx;
4288 break;
4289 }
4290 }
4291 if (ridx == sband->n_bitrates)
4292 return 0; /* rate not found */
4293 }
4294
4295 return mask;
4296}
4297
4298static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
4299 u8 *rates, u8 rates_len,
4300 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
4301{
4302 u8 i;
4303
4304 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
4305
4306 for (i = 0; i < rates_len; i++) {
4307 int ridx, rbit;
4308
4309 ridx = rates[i] / 8;
4310 rbit = BIT(rates[i] % 8);
4311
4312 /* check validity */
4313 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
4314 return false;
4315
4316 /* check availability */
30fe6d50 4317 ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
a7c7fbff
PK
4318 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
4319 mcs[ridx] |= rbit;
4320 else
4321 return false;
4322 }
4323
4324 return true;
4325}
4326
4327static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
4328{
4329 u16 mcs_mask = 0;
4330
4331 switch (vht_mcs_map) {
4332 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
4333 break;
4334 case IEEE80211_VHT_MCS_SUPPORT_0_7:
4335 mcs_mask = 0x00FF;
4336 break;
4337 case IEEE80211_VHT_MCS_SUPPORT_0_8:
4338 mcs_mask = 0x01FF;
4339 break;
4340 case IEEE80211_VHT_MCS_SUPPORT_0_9:
4341 mcs_mask = 0x03FF;
4342 break;
4343 default:
4344 break;
4345 }
4346
4347 return mcs_mask;
4348}
4349
4350static void vht_build_mcs_mask(u16 vht_mcs_map,
4351 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
4352{
4353 u8 nss;
4354
4355 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
4356 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
4357 vht_mcs_map >>= 2;
4358 }
4359}
4360
4361static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
4362 struct nl80211_txrate_vht *txrate,
4363 u16 mcs[NL80211_VHT_NSS_MAX])
4364{
4365 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4366 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
4367 u8 i;
4368
4369 if (!sband->vht_cap.vht_supported)
4370 return false;
4371
4372 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
4373
4374 /* Build vht_mcs_mask from VHT capabilities */
4375 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4376
4377 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
4378 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4379 mcs[i] = txrate->mcs[i];
4380 else
4381 return false;
4382 }
4383
4384 return true;
4385}
4386
4387static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
4388 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
4389 .len = NL80211_MAX_SUPP_RATES },
4390 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
4391 .len = NL80211_MAX_SUPP_HT_RATES },
180aa422
JB
4392 [NL80211_TXRATE_VHT] = {
4393 .type = NLA_EXACT_LEN_WARN,
4394 .len = sizeof(struct nl80211_txrate_vht),
4395 },
a7c7fbff
PK
4396 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
4397};
4398
4399static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
4400 struct cfg80211_bitrate_mask *mask)
4401{
4402 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4403 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4404 int rem, i;
4405 struct nlattr *tx_rates;
4406 struct ieee80211_supported_band *sband;
4407 u16 vht_tx_mcs_map;
4408
4409 memset(mask, 0, sizeof(*mask));
4410 /* Default to all rates enabled */
4411 for (i = 0; i < NUM_NL80211_BANDS; i++) {
4412 sband = rdev->wiphy.bands[i];
4413
4414 if (!sband)
4415 continue;
4416
4417 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
4418 memcpy(mask->control[i].ht_mcs,
4419 sband->ht_cap.mcs.rx_mask,
4420 sizeof(mask->control[i].ht_mcs));
4421
4422 if (!sband->vht_cap.vht_supported)
4423 continue;
4424
4425 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4426 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
4427 }
4428
4429 /* if no rates are given set it back to the defaults */
4430 if (!info->attrs[NL80211_ATTR_TX_RATES])
4431 goto out;
4432
4433 /* The nested attribute uses enum nl80211_band as the index. This maps
4434 * directly to the enum nl80211_band values used in cfg80211.
4435 */
4436 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
4437 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
4438 enum nl80211_band band = nla_type(tx_rates);
4439 int err;
4440
4441 if (band < 0 || band >= NUM_NL80211_BANDS)
4442 return -EINVAL;
4443 sband = rdev->wiphy.bands[band];
4444 if (sband == NULL)
4445 return -EINVAL;
8cb08174
JB
4446 err = nla_parse_nested_deprecated(tb, NL80211_TXRATE_MAX,
4447 tx_rates,
4448 nl80211_txattr_policy,
4449 info->extack);
a7c7fbff
PK
4450 if (err)
4451 return err;
4452 if (tb[NL80211_TXRATE_LEGACY]) {
4453 mask->control[band].legacy = rateset_to_mask(
4454 sband,
4455 nla_data(tb[NL80211_TXRATE_LEGACY]),
4456 nla_len(tb[NL80211_TXRATE_LEGACY]));
4457 if ((mask->control[band].legacy == 0) &&
4458 nla_len(tb[NL80211_TXRATE_LEGACY]))
4459 return -EINVAL;
4460 }
4461 if (tb[NL80211_TXRATE_HT]) {
4462 if (!ht_rateset_to_mask(
4463 sband,
4464 nla_data(tb[NL80211_TXRATE_HT]),
4465 nla_len(tb[NL80211_TXRATE_HT]),
4466 mask->control[band].ht_mcs))
4467 return -EINVAL;
4468 }
4469 if (tb[NL80211_TXRATE_VHT]) {
4470 if (!vht_set_mcs_mask(
4471 sband,
4472 nla_data(tb[NL80211_TXRATE_VHT]),
4473 mask->control[band].vht_mcs))
4474 return -EINVAL;
4475 }
4476 if (tb[NL80211_TXRATE_GI]) {
4477 mask->control[band].gi =
4478 nla_get_u8(tb[NL80211_TXRATE_GI]);
4479 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
4480 return -EINVAL;
4481 }
4482
4483 if (mask->control[band].legacy == 0) {
4484 /* don't allow empty legacy rates if HT or VHT
4485 * are not even supported.
4486 */
4487 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
4488 rdev->wiphy.bands[band]->vht_cap.vht_supported))
4489 return -EINVAL;
4490
4491 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
4492 if (mask->control[band].ht_mcs[i])
4493 goto out;
4494
4495 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
4496 if (mask->control[band].vht_mcs[i])
4497 goto out;
4498
4499 /* legacy and mcs rates may not be both empty */
4500 return -EINVAL;
4501 }
4502 }
4503
4504out:
4505 return 0;
4506}
4507
8564e382
JB
4508static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
4509 enum nl80211_band band,
4510 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 4511{
8564e382
JB
4512 u32 count_ht, count_vht, i;
4513 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
4514
4515 /* Allow only one rate */
4516 if (hweight32(rate) > 1)
4517 return -EINVAL;
4518
4519 count_ht = 0;
4520 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 4521 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 4522 return -EINVAL;
8564e382 4523 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
4524 count_ht++;
4525 if (count_ht > 1)
4526 return -EINVAL;
4527 }
4528 if (count_ht && rate)
4529 return -EINVAL;
4530 }
4531
4532 count_vht = 0;
4533 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 4534 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 4535 return -EINVAL;
8564e382 4536 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
4537 count_vht++;
4538 if (count_vht > 1)
4539 return -EINVAL;
4540 }
4541 if (count_vht && rate)
4542 return -EINVAL;
4543 }
4544
4545 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
4546 return -EINVAL;
4547
8564e382
JB
4548 if (rate &&
4549 !wiphy_ext_feature_isset(&rdev->wiphy,
4550 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
4551 return -EINVAL;
4552 if (count_ht &&
4553 !wiphy_ext_feature_isset(&rdev->wiphy,
4554 NL80211_EXT_FEATURE_BEACON_RATE_HT))
4555 return -EINVAL;
4556 if (count_vht &&
4557 !wiphy_ext_feature_isset(&rdev->wiphy,
4558 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
4559 return -EINVAL;
4560
a7c7fbff
PK
4561 return 0;
4562}
4563
81e54d08
PKC
4564static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
4565 struct nlattr *attrs[],
8860020e 4566 struct cfg80211_beacon_data *bcn)
ed1b6cc7 4567{
8860020e 4568 bool haveinfo = false;
81e54d08 4569 int err;
ed1b6cc7 4570
8860020e 4571 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 4572
a1193be8
SW
4573 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
4574 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
4575 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
4576 if (!bcn->head_len)
4577 return -EINVAL;
4578 haveinfo = true;
ed1b6cc7
JB
4579 }
4580
a1193be8
SW
4581 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
4582 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
4583 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 4584 haveinfo = true;
ed1b6cc7
JB
4585 }
4586
4c476991
JB
4587 if (!haveinfo)
4588 return -EINVAL;
3b85875a 4589
a1193be8
SW
4590 if (attrs[NL80211_ATTR_IE]) {
4591 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
4592 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
4593 }
4594
a1193be8 4595 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 4596 bcn->proberesp_ies =
a1193be8 4597 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 4598 bcn->proberesp_ies_len =
a1193be8 4599 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
4600 }
4601
a1193be8 4602 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 4603 bcn->assocresp_ies =
a1193be8 4604 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 4605 bcn->assocresp_ies_len =
a1193be8 4606 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
4607 }
4608
a1193be8
SW
4609 if (attrs[NL80211_ATTR_PROBE_RESP]) {
4610 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
4611 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
4612 }
4613
81e54d08
PKC
4614 if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
4615 struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
4616
8cb08174
JB
4617 err = nla_parse_nested_deprecated(tb,
4618 NL80211_FTM_RESP_ATTR_MAX,
4619 attrs[NL80211_ATTR_FTM_RESPONDER],
4620 NULL, NULL);
81e54d08
PKC
4621 if (err)
4622 return err;
4623
4624 if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
4625 wiphy_ext_feature_isset(&rdev->wiphy,
4626 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
4627 bcn->ftm_responder = 1;
4628 else
4629 return -EOPNOTSUPP;
4630
4631 if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
4632 bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
4633 bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
4634 }
4635
4636 if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
4637 bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
4638 bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
4639 }
4640 } else {
4641 bcn->ftm_responder = -1;
4642 }
4643
8860020e
JB
4644 return 0;
4645}
4646
796e90f4
JC
4647static int nl80211_parse_he_obss_pd(struct nlattr *attrs,
4648 struct ieee80211_he_obss_pd *he_obss_pd)
4649{
4650 struct nlattr *tb[NL80211_HE_OBSS_PD_ATTR_MAX + 1];
4651 int err;
4652
4653 err = nla_parse_nested(tb, NL80211_HE_OBSS_PD_ATTR_MAX, attrs,
4654 he_obss_pd_policy, NULL);
4655 if (err)
4656 return err;
4657
4658 if (!tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] ||
4659 !tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
4660 return -EINVAL;
4661
4662 he_obss_pd->min_offset =
4663 nla_get_u32(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
4664 he_obss_pd->max_offset =
4665 nla_get_u32(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
4666
4667 if (he_obss_pd->min_offset >= he_obss_pd->max_offset)
4668 return -EINVAL;
4669
4670 he_obss_pd->enable = true;
4671
4672 return 0;
4673}
4674
5c5e52d1
JC
4675static int nl80211_parse_he_bss_color(struct nlattr *attrs,
4676 struct cfg80211_he_bss_color *he_bss_color)
4677{
4678 struct nlattr *tb[NL80211_HE_BSS_COLOR_ATTR_MAX + 1];
4679 int err;
4680
4681 err = nla_parse_nested(tb, NL80211_HE_BSS_COLOR_ATTR_MAX, attrs,
4682 he_bss_color_policy, NULL);
4683 if (err)
4684 return err;
4685
4686 if (!tb[NL80211_HE_BSS_COLOR_ATTR_COLOR])
4687 return -EINVAL;
4688
4689 he_bss_color->color =
4690 nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
4691 he_bss_color->disabled =
4692 nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
4693 he_bss_color->partial =
4694 nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
4695
4696 return 0;
4697}
4698
66cd794e
JB
4699static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
4700 const u8 *rates)
4701{
4702 int i;
4703
4704 if (!rates)
4705 return;
4706
4707 for (i = 0; i < rates[1]; i++) {
4708 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
4709 params->ht_required = true;
4710 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
4711 params->vht_required = true;
4712 }
4713}
4714
4715/*
4716 * Since the nl80211 API didn't include, from the beginning, attributes about
4717 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
4718 * benefit of drivers that rebuild IEs in the firmware.
4719 */
4720static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
4721{
4722 const struct cfg80211_beacon_data *bcn = &params->beacon;
ba83bfb1
IM
4723 size_t ies_len = bcn->tail_len;
4724 const u8 *ies = bcn->tail;
66cd794e
JB
4725 const u8 *rates;
4726 const u8 *cap;
4727
4728 rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
4729 nl80211_check_ap_rate_selectors(params, rates);
4730
4731 rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
4732 nl80211_check_ap_rate_selectors(params, rates);
4733
4734 cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
4735 if (cap && cap[1] >= sizeof(*params->ht_cap))
4736 params->ht_cap = (void *)(cap + 2);
4737 cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
4738 if (cap && cap[1] >= sizeof(*params->vht_cap))
4739 params->vht_cap = (void *)(cap + 2);
244eb9ae
ST
4740 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
4741 if (cap && cap[1] >= sizeof(*params->he_cap) + 1)
4742 params->he_cap = (void *)(cap + 3);
66cd794e
JB
4743}
4744
46c1dd0c
FF
4745static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
4746 struct cfg80211_ap_settings *params)
4747{
4748 struct wireless_dev *wdev;
4749 bool ret = false;
4750
53873f13 4751 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
4752 if (wdev->iftype != NL80211_IFTYPE_AP &&
4753 wdev->iftype != NL80211_IFTYPE_P2P_GO)
4754 continue;
4755
683b6d3b 4756 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
4757 continue;
4758
683b6d3b 4759 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
4760 ret = true;
4761 break;
4762 }
4763
46c1dd0c
FF
4764 return ret;
4765}
4766
e39e5b5e
JM
4767static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
4768 enum nl80211_auth_type auth_type,
4769 enum nl80211_commands cmd)
4770{
4771 if (auth_type > NL80211_AUTHTYPE_MAX)
4772 return false;
4773
4774 switch (cmd) {
4775 case NL80211_CMD_AUTHENTICATE:
4776 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
4777 auth_type == NL80211_AUTHTYPE_SAE)
4778 return false;
63181060
JM
4779 if (!wiphy_ext_feature_isset(&rdev->wiphy,
4780 NL80211_EXT_FEATURE_FILS_STA) &&
4781 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
4782 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4783 auth_type == NL80211_AUTHTYPE_FILS_PK))
4784 return false;
e39e5b5e
JM
4785 return true;
4786 case NL80211_CMD_CONNECT:
10773a7c 4787 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
26f7044e
CHH
4788 !wiphy_ext_feature_isset(&rdev->wiphy,
4789 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
10773a7c 4790 auth_type == NL80211_AUTHTYPE_SAE)
a3caf744 4791 return false;
10773a7c 4792
a3caf744
VK
4793 /* FILS with SK PFS or PK not supported yet */
4794 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4795 auth_type == NL80211_AUTHTYPE_FILS_PK)
4796 return false;
4797 if (!wiphy_ext_feature_isset(
4798 &rdev->wiphy,
4799 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
4800 auth_type == NL80211_AUTHTYPE_FILS_SK)
4801 return false;
4802 return true;
e39e5b5e
JM
4803 case NL80211_CMD_START_AP:
4804 /* SAE not supported yet */
4805 if (auth_type == NL80211_AUTHTYPE_SAE)
4806 return false;
63181060
JM
4807 /* FILS not supported yet */
4808 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
4809 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4810 auth_type == NL80211_AUTHTYPE_FILS_PK)
4811 return false;
e39e5b5e
JM
4812 return true;
4813 default:
4814 return false;
4815 }
4816}
4817
8860020e
JB
4818static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
4819{
4820 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4821 struct net_device *dev = info->user_ptr[1];
4822 struct wireless_dev *wdev = dev->ieee80211_ptr;
4823 struct cfg80211_ap_settings params;
4824 int err;
4825
4826 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4827 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4828 return -EOPNOTSUPP;
4829
4830 if (!rdev->ops->start_ap)
4831 return -EOPNOTSUPP;
4832
4833 if (wdev->beacon_interval)
4834 return -EALREADY;
4835
4836 memset(&params, 0, sizeof(params));
4837
4838 /* these are required for START_AP */
4839 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
4840 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
4841 !info->attrs[NL80211_ATTR_BEACON_HEAD])
4842 return -EINVAL;
4843
81e54d08 4844 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon);
8860020e
JB
4845 if (err)
4846 return err;
4847
4848 params.beacon_interval =
4849 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
4850 params.dtim_period =
4851 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
4852
0c317a02
PK
4853 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
4854 params.beacon_interval);
8860020e
JB
4855 if (err)
4856 return err;
4857
4858 /*
4859 * In theory, some of these attributes should be required here
4860 * but since they were not used when the command was originally
4861 * added, keep them optional for old user space programs to let
4862 * them continue to work with drivers that do not need the
4863 * additional information -- drivers must check!
4864 */
4865 if (info->attrs[NL80211_ATTR_SSID]) {
4866 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4867 params.ssid_len =
4868 nla_len(info->attrs[NL80211_ATTR_SSID]);
4869 if (params.ssid_len == 0 ||
4870 params.ssid_len > IEEE80211_MAX_SSID_LEN)
4871 return -EINVAL;
4872 }
4873
ab0d76f6 4874 if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
8860020e
JB
4875 params.hidden_ssid = nla_get_u32(
4876 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
8860020e
JB
4877
4878 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
4879
4880 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
4881 params.auth_type = nla_get_u32(
4882 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
4883 if (!nl80211_valid_auth_type(rdev, params.auth_type,
4884 NL80211_CMD_START_AP))
8860020e
JB
4885 return -EINVAL;
4886 } else
4887 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
4888
4889 err = nl80211_crypto_settings(rdev, info, &params.crypto,
4890 NL80211_MAX_NR_CIPHER_SUITES);
4891 if (err)
4892 return err;
4893
1b658f11
VT
4894 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
4895 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
4896 return -EOPNOTSUPP;
4897 params.inactivity_timeout = nla_get_u16(
4898 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
4899 }
4900
53cabad7
JB
4901 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
4902 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4903 return -EINVAL;
4904 params.p2p_ctwindow =
4905 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
4906 if (params.p2p_ctwindow != 0 &&
4907 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
4908 return -EINVAL;
4909 }
4910
4911 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
4912 u8 tmp;
4913
4914 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4915 return -EINVAL;
4916 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
4917 params.p2p_opp_ps = tmp;
4918 if (params.p2p_opp_ps != 0 &&
4919 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
4920 return -EINVAL;
4921 }
4922
aa430da4 4923 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
4924 err = nl80211_parse_chandef(rdev, info, &params.chandef);
4925 if (err)
4926 return err;
4927 } else if (wdev->preset_chandef.chan) {
4928 params.chandef = wdev->preset_chandef;
46c1dd0c 4929 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
4930 return -EINVAL;
4931
923b352f
AN
4932 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
4933 wdev->iftype))
aa430da4
JB
4934 return -EINVAL;
4935
a7c7fbff
PK
4936 if (info->attrs[NL80211_ATTR_TX_RATES]) {
4937 err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate);
4938 if (err)
4939 return err;
4940
8564e382
JB
4941 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
4942 &params.beacon_rate);
a7c7fbff
PK
4943 if (err)
4944 return err;
4945 }
4946
18998c38
EP
4947 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
4948 params.smps_mode =
4949 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
4950 switch (params.smps_mode) {
4951 case NL80211_SMPS_OFF:
4952 break;
4953 case NL80211_SMPS_STATIC:
4954 if (!(rdev->wiphy.features &
4955 NL80211_FEATURE_STATIC_SMPS))
4956 return -EINVAL;
4957 break;
4958 case NL80211_SMPS_DYNAMIC:
4959 if (!(rdev->wiphy.features &
4960 NL80211_FEATURE_DYNAMIC_SMPS))
4961 return -EINVAL;
4962 break;
4963 default:
4964 return -EINVAL;
4965 }
4966 } else {
4967 params.smps_mode = NL80211_SMPS_OFF;
4968 }
4969
6e8ef842
PK
4970 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
4971 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
4972 return -EOPNOTSUPP;
4973
4baf6bea
OO
4974 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
4975 params.acl = parse_acl_data(&rdev->wiphy, info);
4976 if (IS_ERR(params.acl))
4977 return PTR_ERR(params.acl);
4978 }
4979
a0de1ca3
JC
4980 params.twt_responder =
4981 nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
4982
796e90f4
JC
4983 if (info->attrs[NL80211_ATTR_HE_OBSS_PD]) {
4984 err = nl80211_parse_he_obss_pd(
4985 info->attrs[NL80211_ATTR_HE_OBSS_PD],
4986 &params.he_obss_pd);
4987 if (err)
4988 return err;
4989 }
4990
5c5e52d1
JC
4991 if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
4992 err = nl80211_parse_he_bss_color(
4993 info->attrs[NL80211_ATTR_HE_BSS_COLOR],
4994 &params.he_bss_color);
4995 if (err)
4996 return err;
4997 }
4998
66cd794e
JB
4999 nl80211_calculate_ap_params(&params);
5000
fe494370
SD
5001 if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
5002 params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
5003
c56589ed 5004 wdev_lock(wdev);
e35e4d28 5005 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 5006 if (!err) {
683b6d3b 5007 wdev->preset_chandef = params.chandef;
8860020e 5008 wdev->beacon_interval = params.beacon_interval;
9e0e2961 5009 wdev->chandef = params.chandef;
06e191e2
AQ
5010 wdev->ssid_len = params.ssid_len;
5011 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
466a3061
DK
5012
5013 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
5014 wdev->conn_owner_nlportid = info->snd_portid;
46c1dd0c 5015 }
c56589ed 5016 wdev_unlock(wdev);
77765eaf
VT
5017
5018 kfree(params.acl);
5019
56d1893d 5020 return err;
ed1b6cc7
JB
5021}
5022
8860020e
JB
5023static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
5024{
5025 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5026 struct net_device *dev = info->user_ptr[1];
5027 struct wireless_dev *wdev = dev->ieee80211_ptr;
5028 struct cfg80211_beacon_data params;
5029 int err;
5030
5031 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5032 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5033 return -EOPNOTSUPP;
5034
5035 if (!rdev->ops->change_beacon)
5036 return -EOPNOTSUPP;
5037
5038 if (!wdev->beacon_interval)
5039 return -EINVAL;
5040
81e54d08 5041 err = nl80211_parse_beacon(rdev, info->attrs, &params);
8860020e
JB
5042 if (err)
5043 return err;
5044
c56589ed
SW
5045 wdev_lock(wdev);
5046 err = rdev_change_beacon(rdev, dev, &params);
5047 wdev_unlock(wdev);
5048
5049 return err;
8860020e
JB
5050}
5051
5052static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 5053{
4c476991
JB
5054 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5055 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 5056
7c8d5e03 5057 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
5058}
5059
5727ef1b
JB
5060static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
5061 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
5062 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
5063 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 5064 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 5065 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 5066 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
5067};
5068
eccb8e8f 5069static int parse_station_flags(struct genl_info *info,
bdd3ae3d 5070 enum nl80211_iftype iftype,
eccb8e8f 5071 struct station_parameters *params)
5727ef1b
JB
5072{
5073 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 5074 struct nlattr *nla;
5727ef1b
JB
5075 int flag;
5076
eccb8e8f
JB
5077 /*
5078 * Try parsing the new attribute first so userspace
5079 * can specify both for older kernels.
5080 */
5081 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
5082 if (nla) {
5083 struct nl80211_sta_flag_update *sta_flags;
5084
5085 sta_flags = nla_data(nla);
5086 params->sta_flags_mask = sta_flags->mask;
5087 params->sta_flags_set = sta_flags->set;
77ee7c89 5088 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
5089 if ((params->sta_flags_mask |
5090 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
5091 return -EINVAL;
5092 return 0;
5093 }
5094
5095 /* if present, parse the old attribute */
5727ef1b 5096
eccb8e8f 5097 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
5098 if (!nla)
5099 return 0;
5100
8cb08174 5101 if (nla_parse_nested_deprecated(flags, NL80211_STA_FLAG_MAX, nla, sta_flags_policy, info->extack))
5727ef1b
JB
5102 return -EINVAL;
5103
bdd3ae3d
JB
5104 /*
5105 * Only allow certain flags for interface types so that
5106 * other attributes are silently ignored. Remember that
5107 * this is backward compatibility code with old userspace
5108 * and shouldn't be hit in other cases anyway.
5109 */
5110 switch (iftype) {
5111 case NL80211_IFTYPE_AP:
5112 case NL80211_IFTYPE_AP_VLAN:
5113 case NL80211_IFTYPE_P2P_GO:
5114 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5115 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
5116 BIT(NL80211_STA_FLAG_WME) |
5117 BIT(NL80211_STA_FLAG_MFP);
5118 break;
5119 case NL80211_IFTYPE_P2P_CLIENT:
5120 case NL80211_IFTYPE_STATION:
5121 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5122 BIT(NL80211_STA_FLAG_TDLS_PEER);
5123 break;
5124 case NL80211_IFTYPE_MESH_POINT:
5125 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5126 BIT(NL80211_STA_FLAG_MFP) |
5127 BIT(NL80211_STA_FLAG_AUTHORIZED);
5cf3006c 5128 break;
bdd3ae3d
JB
5129 default:
5130 return -EINVAL;
5131 }
5727ef1b 5132
3383b5a6
JB
5133 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
5134 if (flags[flag]) {
eccb8e8f 5135 params->sta_flags_set |= (1<<flag);
5727ef1b 5136
3383b5a6
JB
5137 /* no longer support new API additions in old API */
5138 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
5139 return -EINVAL;
5140 }
5141 }
5142
5727ef1b
JB
5143 return 0;
5144}
5145
9bb7e0f2 5146bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
c8dcfd8a
FF
5147{
5148 struct nlattr *rate;
8eb41c8d
VK
5149 u32 bitrate;
5150 u16 bitrate_compat;
bbf67e45 5151 enum nl80211_rate_info rate_flg;
c8dcfd8a 5152
ae0be8de 5153 rate = nla_nest_start_noflag(msg, attr);
c8dcfd8a 5154 if (!rate)
db9c64cf 5155 return false;
c8dcfd8a
FF
5156
5157 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
5158 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
5159 /* report 16-bit bitrate only if we can */
5160 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
5161 if (bitrate > 0 &&
5162 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
5163 return false;
5164 if (bitrate_compat > 0 &&
5165 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
5166 return false;
5167
b51f3bee
JB
5168 switch (info->bw) {
5169 case RATE_INFO_BW_5:
5170 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
5171 break;
5172 case RATE_INFO_BW_10:
5173 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
5174 break;
5175 default:
5176 WARN_ON(1);
5177 /* fall through */
5178 case RATE_INFO_BW_20:
5179 rate_flg = 0;
5180 break;
5181 case RATE_INFO_BW_40:
5182 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
5183 break;
5184 case RATE_INFO_BW_80:
5185 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
5186 break;
5187 case RATE_INFO_BW_160:
5188 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
5189 break;
c4cbaf79
LC
5190 case RATE_INFO_BW_HE_RU:
5191 rate_flg = 0;
5192 WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
b51f3bee
JB
5193 }
5194
5195 if (rate_flg && nla_put_flag(msg, rate_flg))
5196 return false;
5197
db9c64cf
JB
5198 if (info->flags & RATE_INFO_FLAGS_MCS) {
5199 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
5200 return false;
db9c64cf
JB
5201 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5202 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5203 return false;
5204 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
5205 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
5206 return false;
5207 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
5208 return false;
db9c64cf
JB
5209 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5210 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5211 return false;
c4cbaf79
LC
5212 } else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
5213 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
5214 return false;
5215 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
5216 return false;
5217 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
5218 return false;
5219 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
5220 return false;
5221 if (info->bw == RATE_INFO_BW_HE_RU &&
5222 nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
5223 info->he_ru_alloc))
5224 return false;
db9c64cf 5225 }
c8dcfd8a
FF
5226
5227 nla_nest_end(msg, rate);
5228 return true;
c8dcfd8a
FF
5229}
5230
119363c7
FF
5231static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
5232 int id)
5233{
5234 void *attr;
5235 int i = 0;
5236
5237 if (!mask)
5238 return true;
5239
ae0be8de 5240 attr = nla_nest_start_noflag(msg, id);
119363c7
FF
5241 if (!attr)
5242 return false;
5243
5244 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
5245 if (!(mask & BIT(i)))
5246 continue;
5247
5248 if (nla_put_u8(msg, i, signal[i]))
5249 return false;
5250 }
5251
5252 nla_nest_end(msg, attr);
5253
5254 return true;
5255}
5256
cf5ead82
JB
5257static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
5258 u32 seq, int flags,
66266b3a
JL
5259 struct cfg80211_registered_device *rdev,
5260 struct net_device *dev,
98b62183 5261 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
5262{
5263 void *hdr;
f4263c98 5264 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 5265
cf5ead82 5266 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
f77bf486
AS
5267 if (!hdr) {
5268 cfg80211_sinfo_release_content(sinfo);
fd5b74dc 5269 return -1;
f77bf486 5270 }
fd5b74dc 5271
9360ffd1
DM
5272 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5273 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
5274 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
5275 goto nla_put_failure;
f5ea9120 5276
ae0be8de 5277 sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
2ec600d6 5278 if (!sinfoattr)
fd5b74dc 5279 goto nla_put_failure;
319090bf
JB
5280
5281#define PUT_SINFO(attr, memb, type) do { \
d686b920 5282 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
397c657a 5283 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
319090bf
JB
5284 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
5285 sinfo->memb)) \
5286 goto nla_put_failure; \
5287 } while (0)
d686b920 5288#define PUT_SINFO_U64(attr, memb) do { \
397c657a 5289 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
d686b920
JB
5290 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
5291 sinfo->memb, NL80211_STA_INFO_PAD)) \
5292 goto nla_put_failure; \
5293 } while (0)
319090bf
JB
5294
5295 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
5296 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
6c7a0033 5297 PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at);
319090bf 5298
397c657a
OE
5299 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
5300 BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 5301 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 5302 (u32)sinfo->rx_bytes))
9360ffd1 5303 goto nla_put_failure;
319090bf 5304
397c657a
OE
5305 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
5306 BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 5307 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
5308 (u32)sinfo->tx_bytes))
5309 goto nla_put_failure;
319090bf 5310
d686b920
JB
5311 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
5312 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
5313 PUT_SINFO(LLID, llid, u16);
5314 PUT_SINFO(PLID, plid, u16);
5315 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 5316 PUT_SINFO_U64(RX_DURATION, rx_duration);
36647055
THJ
5317 PUT_SINFO_U64(TX_DURATION, tx_duration);
5318
5319 if (wiphy_ext_feature_isset(&rdev->wiphy,
5320 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
5321 PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
319090bf 5322
66266b3a
JL
5323 switch (rdev->wiphy.signal_type) {
5324 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
5325 PUT_SINFO(SIGNAL, signal, u8);
5326 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
5327 break;
5328 default:
5329 break;
5330 }
397c657a 5331 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
5332 if (!nl80211_put_signal(msg, sinfo->chains,
5333 sinfo->chain_signal,
5334 NL80211_STA_INFO_CHAIN_SIGNAL))
5335 goto nla_put_failure;
5336 }
397c657a 5337 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
5338 if (!nl80211_put_signal(msg, sinfo->chains,
5339 sinfo->chain_signal_avg,
5340 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
5341 goto nla_put_failure;
5342 }
397c657a 5343 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
5344 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
5345 NL80211_STA_INFO_TX_BITRATE))
5346 goto nla_put_failure;
5347 }
397c657a 5348 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
5349 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
5350 NL80211_STA_INFO_RX_BITRATE))
420e7fab 5351 goto nla_put_failure;
420e7fab 5352 }
319090bf
JB
5353
5354 PUT_SINFO(RX_PACKETS, rx_packets, u32);
5355 PUT_SINFO(TX_PACKETS, tx_packets, u32);
5356 PUT_SINFO(TX_RETRIES, tx_retries, u32);
5357 PUT_SINFO(TX_FAILED, tx_failed, u32);
5358 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
ab60633c 5359 PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
319090bf
JB
5360 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
5361 PUT_SINFO(LOCAL_PM, local_pm, u32);
5362 PUT_SINFO(PEER_PM, peer_pm, u32);
5363 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
dbdaee7a 5364 PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
319090bf 5365
397c657a 5366 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
ae0be8de
MK
5367 bss_param = nla_nest_start_noflag(msg,
5368 NL80211_STA_INFO_BSS_PARAM);
f4263c98
PS
5369 if (!bss_param)
5370 goto nla_put_failure;
5371
9360ffd1
DM
5372 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
5373 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
5374 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
5375 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
5376 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
5377 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
5378 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
5379 sinfo->bss_param.dtim_period) ||
5380 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
5381 sinfo->bss_param.beacon_interval))
5382 goto nla_put_failure;
f4263c98
PS
5383
5384 nla_nest_end(msg, bss_param);
5385 }
397c657a 5386 if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
5387 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
5388 sizeof(struct nl80211_sta_flag_update),
5389 &sinfo->sta_flags))
5390 goto nla_put_failure;
319090bf 5391
d686b920
JB
5392 PUT_SINFO_U64(T_OFFSET, t_offset);
5393 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
5394 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 5395 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
0d4e14a3
AB
5396 PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
5397 PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
81d5439d 5398 if (wiphy_ext_feature_isset(&rdev->wiphy,
9c06602b
BP
5399 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
5400 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
5401 PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
5402 }
319090bf
JB
5403
5404#undef PUT_SINFO
d686b920 5405#undef PUT_SINFO_U64
6de39808 5406
8689c051 5407 if (sinfo->pertid) {
6de39808
JB
5408 struct nlattr *tidsattr;
5409 int tid;
5410
ae0be8de
MK
5411 tidsattr = nla_nest_start_noflag(msg,
5412 NL80211_STA_INFO_TID_STATS);
6de39808
JB
5413 if (!tidsattr)
5414 goto nla_put_failure;
5415
5416 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
5417 struct cfg80211_tid_stats *tidstats;
5418 struct nlattr *tidattr;
5419
5420 tidstats = &sinfo->pertid[tid];
5421
5422 if (!tidstats->filled)
5423 continue;
5424
ae0be8de 5425 tidattr = nla_nest_start_noflag(msg, tid + 1);
6de39808
JB
5426 if (!tidattr)
5427 goto nla_put_failure;
5428
d686b920 5429#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 5430 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
5431 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
5432 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
5433 goto nla_put_failure; \
5434 } while (0)
5435
d686b920
JB
5436 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
5437 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
5438 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
5439 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 5440
d686b920 5441#undef PUT_TIDVAL_U64
52539ca8
THJ
5442 if ((tidstats->filled &
5443 BIT(NL80211_TID_STATS_TXQ_STATS)) &&
5444 !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
5445 NL80211_TID_STATS_TXQ_STATS))
5446 goto nla_put_failure;
5447
6de39808
JB
5448 nla_nest_end(msg, tidattr);
5449 }
5450
5451 nla_nest_end(msg, tidsattr);
5452 }
5453
2ec600d6 5454 nla_nest_end(msg, sinfoattr);
fd5b74dc 5455
319090bf 5456 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
5457 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
5458 sinfo->assoc_req_ies))
5459 goto nla_put_failure;
50d3dfb7 5460
7ea3e110 5461 cfg80211_sinfo_release_content(sinfo);
053c095a
JB
5462 genlmsg_end(msg, hdr);
5463 return 0;
fd5b74dc
JB
5464
5465 nla_put_failure:
7ea3e110 5466 cfg80211_sinfo_release_content(sinfo);
bc3ed28c
TG
5467 genlmsg_cancel(msg, hdr);
5468 return -EMSGSIZE;
fd5b74dc
JB
5469}
5470
2ec600d6 5471static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 5472 struct netlink_callback *cb)
2ec600d6 5473{
73887fd9 5474 struct station_info sinfo;
1b8ec87a 5475 struct cfg80211_registered_device *rdev;
97990a06 5476 struct wireless_dev *wdev;
2ec600d6 5477 u8 mac_addr[ETH_ALEN];
97990a06 5478 int sta_idx = cb->args[2];
2ec600d6 5479 int err;
2ec600d6 5480
ea90e0dc 5481 rtnl_lock();
5297c65c 5482 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 5483 if (err)
ea90e0dc 5484 goto out_err;
bba95fef 5485
97990a06
JB
5486 if (!wdev->netdev) {
5487 err = -EINVAL;
5488 goto out_err;
5489 }
5490
1b8ec87a 5491 if (!rdev->ops->dump_station) {
eec60b03 5492 err = -EOPNOTSUPP;
bba95fef
JB
5493 goto out_err;
5494 }
5495
bba95fef 5496 while (1) {
73887fd9 5497 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 5498 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
73887fd9 5499 mac_addr, &sinfo);
bba95fef
JB
5500 if (err == -ENOENT)
5501 break;
5502 if (err)
3b85875a 5503 goto out_err;
bba95fef 5504
cf5ead82 5505 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 5506 NETLINK_CB(cb->skb).portid,
bba95fef 5507 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 5508 rdev, wdev->netdev, mac_addr,
73887fd9 5509 &sinfo) < 0)
bba95fef
JB
5510 goto out;
5511
5512 sta_idx++;
5513 }
5514
bba95fef 5515 out:
97990a06 5516 cb->args[2] = sta_idx;
bba95fef 5517 err = skb->len;
bba95fef 5518 out_err:
ea90e0dc 5519 rtnl_unlock();
bba95fef
JB
5520
5521 return err;
2ec600d6 5522}
fd5b74dc 5523
5727ef1b
JB
5524static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
5525{
4c476991
JB
5526 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5527 struct net_device *dev = info->user_ptr[1];
73887fd9 5528 struct station_info sinfo;
fd5b74dc
JB
5529 struct sk_buff *msg;
5530 u8 *mac_addr = NULL;
4c476991 5531 int err;
fd5b74dc 5532
73887fd9 5533 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc 5534
73887fd9
JB
5535 if (!info->attrs[NL80211_ATTR_MAC])
5536 return -EINVAL;
fd5b74dc
JB
5537
5538 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5539
73887fd9
JB
5540 if (!rdev->ops->get_station)
5541 return -EOPNOTSUPP;
3b85875a 5542
73887fd9 5543 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 5544 if (err)
73887fd9 5545 return err;
2ec600d6 5546
fd2120ca 5547 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7ea3e110 5548 if (!msg) {
ba8f566a 5549 cfg80211_sinfo_release_content(&sinfo);
73887fd9 5550 return -ENOMEM;
7ea3e110 5551 }
fd5b74dc 5552
cf5ead82
JB
5553 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
5554 info->snd_portid, info->snd_seq, 0,
73887fd9 5555 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991 5556 nlmsg_free(msg);
73887fd9 5557 return -ENOBUFS;
4c476991 5558 }
3b85875a 5559
73887fd9 5560 return genlmsg_reply(msg, info);
5727ef1b
JB
5561}
5562
77ee7c89
JB
5563int cfg80211_check_station_change(struct wiphy *wiphy,
5564 struct station_parameters *params,
5565 enum cfg80211_station_type statype)
5566{
e4208427
AB
5567 if (params->listen_interval != -1 &&
5568 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 5569 return -EINVAL;
e4208427 5570
17b94247
AB
5571 if (params->support_p2p_ps != -1 &&
5572 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
5573 return -EINVAL;
5574
c72e1140 5575 if (params->aid &&
e4208427
AB
5576 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
5577 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
5578 return -EINVAL;
5579
5580 /* When you run into this, adjust the code below for the new flag */
5581 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
5582
5583 switch (statype) {
eef941e6
TP
5584 case CFG80211_STA_MESH_PEER_KERNEL:
5585 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
5586 /*
5587 * No ignoring the TDLS flag here -- the userspace mesh
5588 * code doesn't have the bug of including TDLS in the
5589 * mask everywhere.
5590 */
5591 if (params->sta_flags_mask &
5592 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5593 BIT(NL80211_STA_FLAG_MFP) |
5594 BIT(NL80211_STA_FLAG_AUTHORIZED)))
5595 return -EINVAL;
5596 break;
5597 case CFG80211_STA_TDLS_PEER_SETUP:
5598 case CFG80211_STA_TDLS_PEER_ACTIVE:
5599 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5600 return -EINVAL;
5601 /* ignore since it can't change */
5602 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
5603 break;
5604 default:
5605 /* disallow mesh-specific things */
5606 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
5607 return -EINVAL;
5608 if (params->local_pm)
5609 return -EINVAL;
5610 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5611 return -EINVAL;
5612 }
5613
5614 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
5615 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
5616 /* TDLS can't be set, ... */
5617 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
5618 return -EINVAL;
5619 /*
5620 * ... but don't bother the driver with it. This works around
5621 * a hostapd/wpa_supplicant issue -- it always includes the
5622 * TLDS_PEER flag in the mask even for AP mode.
5623 */
5624 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
5625 }
5626
47edb11b
AB
5627 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
5628 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
5629 /* reject other things that can't change */
5630 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
5631 return -EINVAL;
5632 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
5633 return -EINVAL;
5634 if (params->supported_rates)
5635 return -EINVAL;
c4cbaf79
LC
5636 if (params->ext_capab || params->ht_capa || params->vht_capa ||
5637 params->he_capa)
77ee7c89
JB
5638 return -EINVAL;
5639 }
5640
47edb11b
AB
5641 if (statype != CFG80211_STA_AP_CLIENT &&
5642 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
5643 if (params->vlan)
5644 return -EINVAL;
5645 }
5646
5647 switch (statype) {
5648 case CFG80211_STA_AP_MLME_CLIENT:
5649 /* Use this only for authorizing/unauthorizing a station */
5650 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
5651 return -EOPNOTSUPP;
5652 break;
5653 case CFG80211_STA_AP_CLIENT:
47edb11b 5654 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
5655 /* accept only the listed bits */
5656 if (params->sta_flags_mask &
5657 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
5658 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5659 BIT(NL80211_STA_FLAG_ASSOCIATED) |
5660 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
5661 BIT(NL80211_STA_FLAG_WME) |
5662 BIT(NL80211_STA_FLAG_MFP)))
5663 return -EINVAL;
5664
5665 /* but authenticated/associated only if driver handles it */
5666 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
5667 params->sta_flags_mask &
5668 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5669 BIT(NL80211_STA_FLAG_ASSOCIATED)))
5670 return -EINVAL;
5671 break;
5672 case CFG80211_STA_IBSS:
5673 case CFG80211_STA_AP_STA:
5674 /* reject any changes other than AUTHORIZED */
5675 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
5676 return -EINVAL;
5677 break;
5678 case CFG80211_STA_TDLS_PEER_SETUP:
5679 /* reject any changes other than AUTHORIZED or WME */
5680 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
5681 BIT(NL80211_STA_FLAG_WME)))
5682 return -EINVAL;
5683 /* force (at least) rates when authorizing */
5684 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
5685 !params->supported_rates)
5686 return -EINVAL;
5687 break;
5688 case CFG80211_STA_TDLS_PEER_ACTIVE:
5689 /* reject any changes */
5690 return -EINVAL;
eef941e6 5691 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
5692 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5693 return -EINVAL;
5694 break;
eef941e6 5695 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
5696 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
5697 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
5698 return -EINVAL;
5699 break;
5700 }
5701
06f7c88c
BL
5702 /*
5703 * Older kernel versions ignored this attribute entirely, so don't
5704 * reject attempts to update it but mark it as unused instead so the
5705 * driver won't look at the data.
5706 */
5707 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
5708 statype != CFG80211_STA_TDLS_PEER_SETUP)
5709 params->opmode_notif_used = false;
5710
77ee7c89
JB
5711 return 0;
5712}
5713EXPORT_SYMBOL(cfg80211_check_station_change);
5714
5727ef1b 5715/*
c258d2de 5716 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 5717 */
80b99899
JB
5718static struct net_device *get_vlan(struct genl_info *info,
5719 struct cfg80211_registered_device *rdev)
5727ef1b 5720{
463d0183 5721 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
5722 struct net_device *v;
5723 int ret;
5724
5725 if (!vlanattr)
5726 return NULL;
5727
5728 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
5729 if (!v)
5730 return ERR_PTR(-ENODEV);
5731
5732 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
5733 ret = -EINVAL;
5734 goto error;
5727ef1b 5735 }
80b99899 5736
77ee7c89
JB
5737 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
5738 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5739 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
5740 ret = -EINVAL;
5741 goto error;
5742 }
5743
80b99899
JB
5744 if (!netif_running(v)) {
5745 ret = -ENETDOWN;
5746 goto error;
5747 }
5748
5749 return v;
5750 error:
5751 dev_put(v);
5752 return ERR_PTR(ret);
5727ef1b
JB
5753}
5754
94e860f1
JB
5755static const struct nla_policy
5756nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
5757 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
5758 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
5759};
5760
ff276691
JB
5761static int nl80211_parse_sta_wme(struct genl_info *info,
5762 struct station_parameters *params)
df881293 5763{
df881293
JM
5764 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
5765 struct nlattr *nla;
5766 int err;
5767
df881293
JM
5768 /* parse WME attributes if present */
5769 if (!info->attrs[NL80211_ATTR_STA_WME])
5770 return 0;
5771
5772 nla = info->attrs[NL80211_ATTR_STA_WME];
8cb08174
JB
5773 err = nla_parse_nested_deprecated(tb, NL80211_STA_WME_MAX, nla,
5774 nl80211_sta_wme_policy,
5775 info->extack);
df881293
JM
5776 if (err)
5777 return err;
5778
5779 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
5780 params->uapsd_queues = nla_get_u8(
5781 tb[NL80211_STA_WME_UAPSD_QUEUES]);
5782 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
5783 return -EINVAL;
5784
5785 if (tb[NL80211_STA_WME_MAX_SP])
5786 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
5787
5788 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
5789 return -EINVAL;
5790
5791 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
5792
5793 return 0;
5794}
5795
c01fc9ad
SD
5796static int nl80211_parse_sta_channel_info(struct genl_info *info,
5797 struct station_parameters *params)
5798{
5799 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
5800 params->supported_channels =
5801 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
5802 params->supported_channels_len =
5803 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
5804 /*
5805 * Need to include at least one (first channel, number of
5806 * channels) tuple for each subband, and must have proper
5807 * tuples for the rest of the data as well.
5808 */
5809 if (params->supported_channels_len < 2)
5810 return -EINVAL;
5811 if (params->supported_channels_len % 2)
5812 return -EINVAL;
5813 }
5814
5815 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
5816 params->supported_oper_classes =
5817 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
5818 params->supported_oper_classes_len =
5819 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
5820 /*
5821 * The value of the Length field of the Supported Operating
5822 * Classes element is between 2 and 253.
5823 */
5824 if (params->supported_oper_classes_len < 2 ||
5825 params->supported_oper_classes_len > 253)
5826 return -EINVAL;
5827 }
5828 return 0;
5829}
5830
ff276691
JB
5831static int nl80211_set_station_tdls(struct genl_info *info,
5832 struct station_parameters *params)
5833{
c01fc9ad 5834 int err;
ff276691 5835 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
5836 if (info->attrs[NL80211_ATTR_PEER_AID])
5837 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
5838 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
5839 params->ht_capa =
5840 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5841 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
5842 params->vht_capa =
5843 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
c4cbaf79
LC
5844 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
5845 params->he_capa =
5846 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5847 params->he_capa_len =
5848 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5849
5850 if (params->he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
5851 return -EINVAL;
5852 }
ff276691 5853
c01fc9ad
SD
5854 err = nl80211_parse_sta_channel_info(info, params);
5855 if (err)
5856 return err;
5857
ff276691
JB
5858 return nl80211_parse_sta_wme(info, params);
5859}
5860
e96d1cd2
ARN
5861static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
5862 struct station_parameters *params)
5863{
5864 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5865 int idx;
5866
5867 if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
5868 if (!rdev->ops->set_tx_power ||
5869 !wiphy_ext_feature_isset(&rdev->wiphy,
5870 NL80211_EXT_FEATURE_STA_TX_PWR))
5871 return -EOPNOTSUPP;
5872
5873 idx = NL80211_ATTR_STA_TX_POWER_SETTING;
5874 params->txpwr.type = nla_get_u8(info->attrs[idx]);
5875
5876 if (params->txpwr.type == NL80211_TX_POWER_LIMITED) {
5877 idx = NL80211_ATTR_STA_TX_POWER;
5878
5879 if (info->attrs[idx])
5880 params->txpwr.power =
5881 nla_get_s16(info->attrs[idx]);
5882 else
5883 return -EINVAL;
5884 }
5885 params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER;
5886 }
5887
5888 return 0;
5889}
5890
5727ef1b
JB
5891static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
5892{
4c476991 5893 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 5894 struct net_device *dev = info->user_ptr[1];
5727ef1b 5895 struct station_parameters params;
77ee7c89
JB
5896 u8 *mac_addr;
5897 int err;
5727ef1b
JB
5898
5899 memset(&params, 0, sizeof(params));
5900
77ee7c89
JB
5901 if (!rdev->ops->change_station)
5902 return -EOPNOTSUPP;
5903
e4208427
AB
5904 /*
5905 * AID and listen_interval properties can be set only for unassociated
5906 * station. Include these parameters here and will check them in
5907 * cfg80211_check_station_change().
5908 */
a9bc31e4
AB
5909 if (info->attrs[NL80211_ATTR_STA_AID])
5910 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427 5911
14f34e36
GG
5912 if (info->attrs[NL80211_ATTR_VLAN_ID])
5913 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
5914
e4208427
AB
5915 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
5916 params.listen_interval =
5917 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
5918 else
5919 params.listen_interval = -1;
5727ef1b 5920
ab0d76f6
JB
5921 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
5922 params.support_p2p_ps =
5923 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5924 else
17b94247 5925 params.support_p2p_ps = -1;
17b94247 5926
5727ef1b
JB
5927 if (!info->attrs[NL80211_ATTR_MAC])
5928 return -EINVAL;
5929
5930 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5931
5932 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
5933 params.supported_rates =
5934 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5935 params.supported_rates_len =
5936 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5937 }
5938
9d62a986
JM
5939 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
5940 params.capability =
5941 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
5942 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
5943 }
5944
5945 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
5946 params.ext_capab =
5947 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5948 params.ext_capab_len =
5949 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5950 }
5951
bdd3ae3d 5952 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
5953 return -EINVAL;
5954
ab0d76f6 5955 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2ec600d6 5956 params.plink_action =
f8bacc21 5957 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2ec600d6 5958
f8bacc21 5959 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 5960 params.plink_state =
f8bacc21 5961 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
ab0d76f6 5962 if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
7d27a0ba
MH
5963 params.peer_aid = nla_get_u16(
5964 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
f8bacc21
JB
5965 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
5966 }
9c3990aa 5967
ab0d76f6
JB
5968 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
5969 params.local_pm = nla_get_u32(
3b1c5a53
MP
5970 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
5971
06f7c88c
BL
5972 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
5973 params.opmode_notif_used = true;
5974 params.opmode_notif =
5975 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
5976 }
5977
36647055
THJ
5978 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
5979 params.airtime_weight =
5980 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
5981
5982 if (params.airtime_weight &&
5983 !wiphy_ext_feature_isset(&rdev->wiphy,
5984 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
5985 return -EOPNOTSUPP;
5986
e96d1cd2
ARN
5987 err = nl80211_parse_sta_txpower_setting(info, &params);
5988 if (err)
5989 return err;
5990
77ee7c89
JB
5991 /* Include parameters for TDLS peer (will check later) */
5992 err = nl80211_set_station_tdls(info, &params);
5993 if (err)
5994 return err;
5995
5996 params.vlan = get_vlan(info, rdev);
5997 if (IS_ERR(params.vlan))
5998 return PTR_ERR(params.vlan);
5999
a97f4424
JB
6000 switch (dev->ieee80211_ptr->iftype) {
6001 case NL80211_IFTYPE_AP:
6002 case NL80211_IFTYPE_AP_VLAN:
074ac8df 6003 case NL80211_IFTYPE_P2P_GO:
074ac8df 6004 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 6005 case NL80211_IFTYPE_STATION:
267335d6 6006 case NL80211_IFTYPE_ADHOC:
a97f4424 6007 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
6008 break;
6009 default:
77ee7c89
JB
6010 err = -EOPNOTSUPP;
6011 goto out_put_vlan;
034d655e
JB
6012 }
6013
77ee7c89 6014 /* driver will call cfg80211_check_station_change() */
e35e4d28 6015 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 6016
77ee7c89 6017 out_put_vlan:
5727ef1b
JB
6018 if (params.vlan)
6019 dev_put(params.vlan);
3b85875a 6020
5727ef1b
JB
6021 return err;
6022}
6023
6024static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
6025{
4c476991 6026 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 6027 int err;
4c476991 6028 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
6029 struct station_parameters params;
6030 u8 *mac_addr = NULL;
bda95eb1
JB
6031 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6032 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
6033
6034 memset(&params, 0, sizeof(params));
6035
984c311b
JB
6036 if (!rdev->ops->add_station)
6037 return -EOPNOTSUPP;
6038
5727ef1b
JB
6039 if (!info->attrs[NL80211_ATTR_MAC])
6040 return -EINVAL;
6041
5727ef1b
JB
6042 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
6043 return -EINVAL;
6044
6045 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
6046 return -EINVAL;
6047
5e4b6f56
JM
6048 if (!info->attrs[NL80211_ATTR_STA_AID] &&
6049 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
6050 return -EINVAL;
6051
5727ef1b
JB
6052 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6053 params.supported_rates =
6054 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6055 params.supported_rates_len =
6056 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6057 params.listen_interval =
6058 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 6059
14f34e36
GG
6060 if (info->attrs[NL80211_ATTR_VLAN_ID])
6061 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
6062
17b94247 6063 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
ab0d76f6
JB
6064 params.support_p2p_ps =
6065 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
17b94247
AB
6066 } else {
6067 /*
6068 * if not specified, assume it's supported for P2P GO interface,
6069 * and is NOT supported for AP interface
6070 */
6071 params.support_p2p_ps =
6072 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
6073 }
6074
3d124ea2 6075 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 6076 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
6077 else
6078 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
51b50fbe 6079
9d62a986
JM
6080 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
6081 params.capability =
6082 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
6083 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
6084 }
6085
6086 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
6087 params.ext_capab =
6088 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6089 params.ext_capab_len =
6090 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6091 }
6092
36aedc90
JM
6093 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
6094 params.ht_capa =
6095 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 6096
f461be3e
MP
6097 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
6098 params.vht_capa =
6099 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
6100
c4cbaf79
LC
6101 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
6102 params.he_capa =
6103 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6104 params.he_capa_len =
6105 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6106
6107 /* max len is validated in nla policy */
6108 if (params.he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
6109 return -EINVAL;
6110 }
6111
60f4a7b1
MK
6112 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
6113 params.opmode_notif_used = true;
6114 params.opmode_notif =
6115 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
6116 }
6117
ab0d76f6 6118 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
96b78dff 6119 params.plink_action =
f8bacc21 6120 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
96b78dff 6121
36647055
THJ
6122 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
6123 params.airtime_weight =
6124 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
6125
6126 if (params.airtime_weight &&
6127 !wiphy_ext_feature_isset(&rdev->wiphy,
6128 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6129 return -EOPNOTSUPP;
6130
e96d1cd2
ARN
6131 err = nl80211_parse_sta_txpower_setting(info, &params);
6132 if (err)
6133 return err;
6134
c01fc9ad
SD
6135 err = nl80211_parse_sta_channel_info(info, &params);
6136 if (err)
6137 return err;
6138
ff276691
JB
6139 err = nl80211_parse_sta_wme(info, &params);
6140 if (err)
6141 return err;
bdd90d5e 6142
bdd3ae3d 6143 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
6144 return -EINVAL;
6145
496fcc29
JB
6146 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
6147 * as userspace might just pass through the capabilities from the IEs
6148 * directly, rather than enforcing this restriction and returning an
6149 * error in this case.
6150 */
6151 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
6152 params.ht_capa = NULL;
6153 params.vht_capa = NULL;
c4cbaf79
LC
6154
6155 /* HE requires WME */
6156 if (params.he_capa_len)
6157 return -EINVAL;
496fcc29
JB
6158 }
6159
77ee7c89
JB
6160 /* When you run into this, adjust the code below for the new flag */
6161 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
6162
bdd90d5e
JB
6163 switch (dev->ieee80211_ptr->iftype) {
6164 case NL80211_IFTYPE_AP:
6165 case NL80211_IFTYPE_AP_VLAN:
6166 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
6167 /* ignore WME attributes if iface/sta is not capable */
6168 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
6169 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
6170 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 6171
bdd90d5e 6172 /* TDLS peers cannot be added */
3d124ea2
JM
6173 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
6174 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 6175 return -EINVAL;
bdd90d5e
JB
6176 /* but don't bother the driver with it */
6177 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 6178
d582cffb
JB
6179 /* allow authenticated/associated only if driver handles it */
6180 if (!(rdev->wiphy.features &
6181 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 6182 params.sta_flags_mask & auth_assoc)
d582cffb
JB
6183 return -EINVAL;
6184
bda95eb1
JB
6185 /* Older userspace, or userspace wanting to be compatible with
6186 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
6187 * and assoc flags in the mask, but assumes the station will be
6188 * added as associated anyway since this was the required driver
6189 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
6190 * introduced.
6191 * In order to not bother drivers with this quirk in the API
6192 * set the flags in both the mask and set for new stations in
6193 * this case.
6194 */
6195 if (!(params.sta_flags_mask & auth_assoc)) {
6196 params.sta_flags_mask |= auth_assoc;
6197 params.sta_flags_set |= auth_assoc;
6198 }
6199
bdd90d5e
JB
6200 /* must be last in here for error handling */
6201 params.vlan = get_vlan(info, rdev);
6202 if (IS_ERR(params.vlan))
6203 return PTR_ERR(params.vlan);
6204 break;
6205 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
6206 /* ignore uAPSD data */
6207 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
6208
d582cffb
JB
6209 /* associated is disallowed */
6210 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
6211 return -EINVAL;
bdd90d5e 6212 /* TDLS peers cannot be added */
3d124ea2
JM
6213 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
6214 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
6215 return -EINVAL;
6216 break;
6217 case NL80211_IFTYPE_STATION:
93d08f0b 6218 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
6219 /* ignore uAPSD data */
6220 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
6221
77ee7c89
JB
6222 /* these are disallowed */
6223 if (params.sta_flags_mask &
6224 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
6225 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 6226 return -EINVAL;
bdd90d5e
JB
6227 /* Only TDLS peers can be added */
6228 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
6229 return -EINVAL;
6230 /* Can only add if TDLS ... */
6231 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
6232 return -EOPNOTSUPP;
6233 /* ... with external setup is supported */
6234 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
6235 return -EOPNOTSUPP;
77ee7c89
JB
6236 /*
6237 * Older wpa_supplicant versions always mark the TDLS peer
6238 * as authorized, but it shouldn't yet be.
6239 */
6240 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
6241 break;
6242 default:
6243 return -EOPNOTSUPP;
c75786c9
EP
6244 }
6245
bdd90d5e 6246 /* be aware of params.vlan when changing code here */
5727ef1b 6247
e35e4d28 6248 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 6249
5727ef1b
JB
6250 if (params.vlan)
6251 dev_put(params.vlan);
5727ef1b
JB
6252 return err;
6253}
6254
6255static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
6256{
4c476991
JB
6257 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6258 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
6259 struct station_del_parameters params;
6260
6261 memset(&params, 0, sizeof(params));
5727ef1b
JB
6262
6263 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 6264 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 6265
e80cf853 6266 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 6267 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 6268 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
6269 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6270 return -EINVAL;
5727ef1b 6271
4c476991
JB
6272 if (!rdev->ops->del_station)
6273 return -EOPNOTSUPP;
3b85875a 6274
98856866
JM
6275 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
6276 params.subtype =
6277 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
6278 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
6279 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
6280 return -EINVAL;
6281 } else {
6282 /* Default to Deauthentication frame */
6283 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
6284 }
6285
6286 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
6287 params.reason_code =
6288 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
6289 if (params.reason_code == 0)
6290 return -EINVAL; /* 0 is reserved */
6291 } else {
6292 /* Default to reason code 2 */
6293 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
6294 }
6295
89c771e5 6296 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
6297}
6298
15e47304 6299static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
6300 int flags, struct net_device *dev,
6301 u8 *dst, u8 *next_hop,
6302 struct mpath_info *pinfo)
6303{
6304 void *hdr;
6305 struct nlattr *pinfoattr;
6306
1ef4c850 6307 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
6308 if (!hdr)
6309 return -1;
6310
9360ffd1
DM
6311 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6312 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
6313 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
6314 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
6315 goto nla_put_failure;
f5ea9120 6316
ae0be8de 6317 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MPATH_INFO);
2ec600d6
LCC
6318 if (!pinfoattr)
6319 goto nla_put_failure;
9360ffd1
DM
6320 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
6321 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
6322 pinfo->frame_qlen))
6323 goto nla_put_failure;
6324 if (((pinfo->filled & MPATH_INFO_SN) &&
6325 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
6326 ((pinfo->filled & MPATH_INFO_METRIC) &&
6327 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
6328 pinfo->metric)) ||
6329 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
6330 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
6331 pinfo->exptime)) ||
6332 ((pinfo->filled & MPATH_INFO_FLAGS) &&
6333 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
6334 pinfo->flags)) ||
6335 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
6336 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
6337 pinfo->discovery_timeout)) ||
6338 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
6339 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
cc241636
JH
6340 pinfo->discovery_retries)) ||
6341 ((pinfo->filled & MPATH_INFO_HOP_COUNT) &&
6342 nla_put_u8(msg, NL80211_MPATH_INFO_HOP_COUNT,
540bbcb9
JH
6343 pinfo->hop_count)) ||
6344 ((pinfo->filled & MPATH_INFO_PATH_CHANGE) &&
6345 nla_put_u32(msg, NL80211_MPATH_INFO_PATH_CHANGE,
6346 pinfo->path_change_count)))
9360ffd1 6347 goto nla_put_failure;
2ec600d6
LCC
6348
6349 nla_nest_end(msg, pinfoattr);
6350
053c095a
JB
6351 genlmsg_end(msg, hdr);
6352 return 0;
2ec600d6
LCC
6353
6354 nla_put_failure:
bc3ed28c
TG
6355 genlmsg_cancel(msg, hdr);
6356 return -EMSGSIZE;
2ec600d6
LCC
6357}
6358
6359static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 6360 struct netlink_callback *cb)
2ec600d6 6361{
2ec600d6 6362 struct mpath_info pinfo;
1b8ec87a 6363 struct cfg80211_registered_device *rdev;
97990a06 6364 struct wireless_dev *wdev;
2ec600d6
LCC
6365 u8 dst[ETH_ALEN];
6366 u8 next_hop[ETH_ALEN];
97990a06 6367 int path_idx = cb->args[2];
2ec600d6 6368 int err;
2ec600d6 6369
ea90e0dc 6370 rtnl_lock();
5297c65c 6371 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 6372 if (err)
ea90e0dc 6373 goto out_err;
bba95fef 6374
1b8ec87a 6375 if (!rdev->ops->dump_mpath) {
eec60b03 6376 err = -EOPNOTSUPP;
bba95fef
JB
6377 goto out_err;
6378 }
6379
97990a06 6380 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 6381 err = -EOPNOTSUPP;
0448b5fc 6382 goto out_err;
eec60b03
JM
6383 }
6384
bba95fef 6385 while (1) {
1b8ec87a 6386 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 6387 next_hop, &pinfo);
bba95fef 6388 if (err == -ENOENT)
2ec600d6 6389 break;
bba95fef 6390 if (err)
3b85875a 6391 goto out_err;
2ec600d6 6392
15e47304 6393 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 6394 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 6395 wdev->netdev, dst, next_hop,
bba95fef
JB
6396 &pinfo) < 0)
6397 goto out;
2ec600d6 6398
bba95fef 6399 path_idx++;
2ec600d6 6400 }
2ec600d6 6401
bba95fef 6402 out:
97990a06 6403 cb->args[2] = path_idx;
bba95fef 6404 err = skb->len;
bba95fef 6405 out_err:
ea90e0dc 6406 rtnl_unlock();
bba95fef 6407 return err;
2ec600d6
LCC
6408}
6409
6410static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
6411{
4c476991 6412 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 6413 int err;
4c476991 6414 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6415 struct mpath_info pinfo;
6416 struct sk_buff *msg;
6417 u8 *dst = NULL;
6418 u8 next_hop[ETH_ALEN];
6419
6420 memset(&pinfo, 0, sizeof(pinfo));
6421
6422 if (!info->attrs[NL80211_ATTR_MAC])
6423 return -EINVAL;
6424
6425 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6426
4c476991
JB
6427 if (!rdev->ops->get_mpath)
6428 return -EOPNOTSUPP;
2ec600d6 6429
4c476991
JB
6430 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6431 return -EOPNOTSUPP;
eec60b03 6432
e35e4d28 6433 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 6434 if (err)
4c476991 6435 return err;
2ec600d6 6436
fd2120ca 6437 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 6438 if (!msg)
4c476991 6439 return -ENOMEM;
2ec600d6 6440
15e47304 6441 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
6442 dev, dst, next_hop, &pinfo) < 0) {
6443 nlmsg_free(msg);
6444 return -ENOBUFS;
6445 }
3b85875a 6446
4c476991 6447 return genlmsg_reply(msg, info);
2ec600d6
LCC
6448}
6449
6450static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
6451{
4c476991
JB
6452 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6453 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6454 u8 *dst = NULL;
6455 u8 *next_hop = NULL;
6456
6457 if (!info->attrs[NL80211_ATTR_MAC])
6458 return -EINVAL;
6459
6460 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
6461 return -EINVAL;
6462
6463 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6464 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
6465
4c476991
JB
6466 if (!rdev->ops->change_mpath)
6467 return -EOPNOTSUPP;
35a8efe1 6468
4c476991
JB
6469 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6470 return -EOPNOTSUPP;
2ec600d6 6471
e35e4d28 6472 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 6473}
4c476991 6474
2ec600d6
LCC
6475static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
6476{
4c476991
JB
6477 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6478 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6479 u8 *dst = NULL;
6480 u8 *next_hop = NULL;
6481
6482 if (!info->attrs[NL80211_ATTR_MAC])
6483 return -EINVAL;
6484
6485 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
6486 return -EINVAL;
6487
6488 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6489 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
6490
4c476991
JB
6491 if (!rdev->ops->add_mpath)
6492 return -EOPNOTSUPP;
35a8efe1 6493
4c476991
JB
6494 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6495 return -EOPNOTSUPP;
2ec600d6 6496
e35e4d28 6497 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
6498}
6499
6500static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
6501{
4c476991
JB
6502 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6503 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6504 u8 *dst = NULL;
6505
6506 if (info->attrs[NL80211_ATTR_MAC])
6507 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6508
4c476991
JB
6509 if (!rdev->ops->del_mpath)
6510 return -EOPNOTSUPP;
3b85875a 6511
b501426c
MP
6512 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6513 return -EOPNOTSUPP;
6514
e35e4d28 6515 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
6516}
6517
66be7d2b
HR
6518static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
6519{
6520 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6521 int err;
6522 struct net_device *dev = info->user_ptr[1];
6523 struct mpath_info pinfo;
6524 struct sk_buff *msg;
6525 u8 *dst = NULL;
6526 u8 mpp[ETH_ALEN];
6527
6528 memset(&pinfo, 0, sizeof(pinfo));
6529
6530 if (!info->attrs[NL80211_ATTR_MAC])
6531 return -EINVAL;
6532
6533 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6534
6535 if (!rdev->ops->get_mpp)
6536 return -EOPNOTSUPP;
6537
6538 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6539 return -EOPNOTSUPP;
6540
6541 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
6542 if (err)
6543 return err;
6544
6545 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6546 if (!msg)
6547 return -ENOMEM;
6548
6549 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
6550 dev, dst, mpp, &pinfo) < 0) {
6551 nlmsg_free(msg);
6552 return -ENOBUFS;
6553 }
6554
6555 return genlmsg_reply(msg, info);
6556}
6557
6558static int nl80211_dump_mpp(struct sk_buff *skb,
6559 struct netlink_callback *cb)
6560{
6561 struct mpath_info pinfo;
6562 struct cfg80211_registered_device *rdev;
6563 struct wireless_dev *wdev;
6564 u8 dst[ETH_ALEN];
6565 u8 mpp[ETH_ALEN];
6566 int path_idx = cb->args[2];
6567 int err;
6568
ea90e0dc 6569 rtnl_lock();
5297c65c 6570 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
66be7d2b 6571 if (err)
ea90e0dc 6572 goto out_err;
66be7d2b
HR
6573
6574 if (!rdev->ops->dump_mpp) {
6575 err = -EOPNOTSUPP;
6576 goto out_err;
6577 }
6578
6579 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
6580 err = -EOPNOTSUPP;
6581 goto out_err;
6582 }
6583
6584 while (1) {
6585 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
6586 mpp, &pinfo);
6587 if (err == -ENOENT)
6588 break;
6589 if (err)
6590 goto out_err;
6591
6592 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
6593 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6594 wdev->netdev, dst, mpp,
6595 &pinfo) < 0)
6596 goto out;
6597
6598 path_idx++;
6599 }
6600
6601 out:
6602 cb->args[2] = path_idx;
6603 err = skb->len;
6604 out_err:
ea90e0dc 6605 rtnl_unlock();
66be7d2b
HR
6606 return err;
6607}
6608
9f1ba906
JM
6609static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
6610{
4c476991
JB
6611 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6612 struct net_device *dev = info->user_ptr[1];
c56589ed 6613 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 6614 struct bss_parameters params;
c56589ed 6615 int err;
9f1ba906
JM
6616
6617 memset(&params, 0, sizeof(params));
6618 /* default to not changing parameters */
6619 params.use_cts_prot = -1;
6620 params.use_short_preamble = -1;
6621 params.use_short_slot_time = -1;
fd8aaaf3 6622 params.ap_isolate = -1;
50b12f59 6623 params.ht_opmode = -1;
53cabad7
JB
6624 params.p2p_ctwindow = -1;
6625 params.p2p_opp_ps = -1;
9f1ba906
JM
6626
6627 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
6628 params.use_cts_prot =
6629 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
6630 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
6631 params.use_short_preamble =
6632 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
6633 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
6634 params.use_short_slot_time =
6635 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
6636 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
6637 params.basic_rates =
6638 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
6639 params.basic_rates_len =
6640 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
6641 }
fd8aaaf3
FF
6642 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
6643 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
6644 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
6645 params.ht_opmode =
6646 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 6647
53cabad7
JB
6648 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
6649 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6650 return -EINVAL;
6651 params.p2p_ctwindow =
ab0d76f6 6652 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
6653 if (params.p2p_ctwindow != 0 &&
6654 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
6655 return -EINVAL;
6656 }
6657
6658 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
6659 u8 tmp;
6660
6661 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6662 return -EINVAL;
6663 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
6664 params.p2p_opp_ps = tmp;
6665 if (params.p2p_opp_ps &&
6666 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
6667 return -EINVAL;
6668 }
6669
4c476991
JB
6670 if (!rdev->ops->change_bss)
6671 return -EOPNOTSUPP;
9f1ba906 6672
074ac8df 6673 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
6674 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6675 return -EOPNOTSUPP;
3b85875a 6676
c56589ed
SW
6677 wdev_lock(wdev);
6678 err = rdev_change_bss(rdev, dev, &params);
6679 wdev_unlock(wdev);
6680
6681 return err;
9f1ba906
JM
6682}
6683
b2e1b302
LR
6684static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
6685{
b2e1b302 6686 char *data = NULL;
05050753 6687 bool is_indoor;
57b5ce07 6688 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
6689 u32 owner_nlportid;
6690
80778f18
LR
6691 /*
6692 * You should only get this when cfg80211 hasn't yet initialized
6693 * completely when built-in to the kernel right between the time
6694 * window between nl80211_init() and regulatory_init(), if that is
6695 * even possible.
6696 */
458f4f9e 6697 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 6698 return -EINPROGRESS;
80778f18 6699
57b5ce07
LR
6700 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
6701 user_reg_hint_type =
6702 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
6703 else
6704 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
6705
6706 switch (user_reg_hint_type) {
6707 case NL80211_USER_REG_HINT_USER:
6708 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
6709 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6710 return -EINVAL;
6711
6712 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6713 return regulatory_hint_user(data, user_reg_hint_type);
6714 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
6715 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
6716 owner_nlportid = info->snd_portid;
6717 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
6718 } else {
6719 owner_nlportid = 0;
6720 is_indoor = true;
6721 }
6722
6723 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
6724 default:
6725 return -EINVAL;
6726 }
b2e1b302
LR
6727}
6728
1ea4ff3e
JB
6729static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
6730{
6731 return reg_reload_regdb();
6732}
6733
24bdd9f4 6734static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 6735 struct genl_info *info)
93da9cc1 6736{
4c476991 6737 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 6738 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
6739 struct wireless_dev *wdev = dev->ieee80211_ptr;
6740 struct mesh_config cur_params;
6741 int err = 0;
93da9cc1 6742 void *hdr;
6743 struct nlattr *pinfoattr;
6744 struct sk_buff *msg;
6745
29cbe68c
JB
6746 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
6747 return -EOPNOTSUPP;
6748
24bdd9f4 6749 if (!rdev->ops->get_mesh_config)
4c476991 6750 return -EOPNOTSUPP;
f3f92586 6751
29cbe68c
JB
6752 wdev_lock(wdev);
6753 /* If not connected, get default parameters */
6754 if (!wdev->mesh_id_len)
6755 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
6756 else
e35e4d28 6757 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
6758 wdev_unlock(wdev);
6759
93da9cc1 6760 if (err)
4c476991 6761 return err;
93da9cc1 6762
6763 /* Draw up a netlink message to send back */
fd2120ca 6764 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
6765 if (!msg)
6766 return -ENOMEM;
15e47304 6767 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 6768 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 6769 if (!hdr)
efe1cf0c 6770 goto out;
ae0be8de 6771 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 6772 if (!pinfoattr)
6773 goto nla_put_failure;
9360ffd1
DM
6774 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6775 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
6776 cur_params.dot11MeshRetryTimeout) ||
6777 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
6778 cur_params.dot11MeshConfirmTimeout) ||
6779 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
6780 cur_params.dot11MeshHoldingTimeout) ||
6781 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
6782 cur_params.dot11MeshMaxPeerLinks) ||
6783 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
6784 cur_params.dot11MeshMaxRetries) ||
6785 nla_put_u8(msg, NL80211_MESHCONF_TTL,
6786 cur_params.dot11MeshTTL) ||
6787 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
6788 cur_params.element_ttl) ||
6789 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
6790 cur_params.auto_open_plinks) ||
7eab0f64
JL
6791 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
6792 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
6793 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
6794 cur_params.dot11MeshHWMPmaxPREQretries) ||
6795 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
6796 cur_params.path_refresh_time) ||
6797 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
6798 cur_params.min_discovery_timeout) ||
6799 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
6800 cur_params.dot11MeshHWMPactivePathTimeout) ||
6801 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
6802 cur_params.dot11MeshHWMPpreqMinInterval) ||
6803 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
6804 cur_params.dot11MeshHWMPperrMinInterval) ||
6805 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
6806 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
6807 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
6808 cur_params.dot11MeshHWMPRootMode) ||
6809 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
6810 cur_params.dot11MeshHWMPRannInterval) ||
6811 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
6812 cur_params.dot11MeshGateAnnouncementProtocol) ||
6813 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
6814 cur_params.dot11MeshForwarding) ||
335d5349 6815 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
6816 cur_params.rssi_threshold) ||
6817 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
6818 cur_params.ht_opmode) ||
6819 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
6820 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
6821 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
6822 cur_params.dot11MeshHWMProotInterval) ||
6823 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
6824 cur_params.dot11MeshHWMPconfirmationInterval) ||
6825 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
6826 cur_params.power_mode) ||
6827 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
6828 cur_params.dot11MeshAwakeWindowDuration) ||
6829 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
01d66fbd
BC
6830 cur_params.plink_timeout) ||
6831 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
6832 cur_params.dot11MeshConnectedToMeshGate))
9360ffd1 6833 goto nla_put_failure;
93da9cc1 6834 nla_nest_end(msg, pinfoattr);
6835 genlmsg_end(msg, hdr);
4c476991 6836 return genlmsg_reply(msg, info);
93da9cc1 6837
3b85875a 6838 nla_put_failure:
efe1cf0c 6839 out:
d080e275 6840 nlmsg_free(msg);
4c476991 6841 return -ENOBUFS;
93da9cc1 6842}
6843
ab0d76f6
JB
6844static const struct nla_policy
6845nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
6846 [NL80211_MESHCONF_RETRY_TIMEOUT] =
6847 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6848 [NL80211_MESHCONF_CONFIRM_TIMEOUT] =
6849 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6850 [NL80211_MESHCONF_HOLDING_TIMEOUT] =
6851 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6852 [NL80211_MESHCONF_MAX_PEER_LINKS] =
6853 NLA_POLICY_RANGE(NLA_U16, 0, 255),
6854 [NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
6855 [NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
6856 [NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
6857 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
6858 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
6859 NLA_POLICY_RANGE(NLA_U32, 1, 255),
93da9cc1 6860 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
6861 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
ab0d76f6 6862 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
93da9cc1 6863 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
6864 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
6865 NLA_POLICY_MIN(NLA_U16, 1),
6866 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
6867 NLA_POLICY_MIN(NLA_U16, 1),
6868 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
6869 NLA_POLICY_MIN(NLA_U16, 1),
6870 [NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
6871 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
6872 NLA_POLICY_MIN(NLA_U16, 1),
6873 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
6874 [NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
6875 [NL80211_MESHCONF_RSSI_THRESHOLD] =
6876 NLA_POLICY_RANGE(NLA_S32, -255, 0),
a4f606ea 6877 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6 6878 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
6879 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
6880 NLA_POLICY_MIN(NLA_U16, 1),
6881 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
6882 NLA_POLICY_MIN(NLA_U16, 1),
6883 [NL80211_MESHCONF_POWER_MODE] =
6884 NLA_POLICY_RANGE(NLA_U32,
6885 NL80211_MESH_POWER_ACTIVE,
6886 NL80211_MESH_POWER_MAX),
3b1c5a53 6887 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 6888 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
01d66fbd 6889 [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
93da9cc1 6890};
6891
c80d545d
JC
6892static const struct nla_policy
6893 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 6894 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
6895 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
6896 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 6897 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 6898 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 6899 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
3d7af878
JB
6900 [NL80211_MESH_SETUP_IE] =
6901 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
6902 IEEE80211_MAX_DATA_LEN),
b130e5ce 6903 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
6904};
6905
24bdd9f4 6906static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
6907 struct mesh_config *cfg,
6908 u32 *mask_out)
93da9cc1 6909{
93da9cc1 6910 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 6911 u32 mask = 0;
9757235f 6912 u16 ht_opmode;
93da9cc1 6913
ab0d76f6
JB
6914#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
6915do { \
6916 if (tb[attr]) { \
6917 cfg->param = fn(tb[attr]); \
6918 mask |= BIT((attr) - 1); \
6919 } \
ea54fba2 6920} while (0)
bd90fdcc 6921
24bdd9f4 6922 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 6923 return -EINVAL;
8cb08174 6924 if (nla_parse_nested_deprecated(tb, NL80211_MESHCONF_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy, info->extack))
93da9cc1 6925 return -EINVAL;
6926
93da9cc1 6927 /* This makes sure that there aren't more than 32 mesh config
6928 * parameters (otherwise our bitfield scheme would not work.) */
6929 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
6930
6931 /* Fill in the params struct */
ab0d76f6
JB
6932 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
6933 NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
6934 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
6935 NL80211_MESHCONF_CONFIRM_TIMEOUT,
6936 nla_get_u16);
6937 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
6938 NL80211_MESHCONF_HOLDING_TIMEOUT,
6939 nla_get_u16);
6940 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
6941 NL80211_MESHCONF_MAX_PEER_LINKS,
6942 nla_get_u16);
6943 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
6944 NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
6945 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
6946 NL80211_MESHCONF_TTL, nla_get_u8);
6947 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
6948 NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
6949 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
6950 NL80211_MESHCONF_AUTO_OPEN_PLINKS,
6951 nla_get_u8);
ea54fba2 6952 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
ab0d76f6 6953 mask,
a4f606ea 6954 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
ab0d76f6
JB
6955 nla_get_u32);
6956 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
6957 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
6958 nla_get_u8);
6959 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
6960 NL80211_MESHCONF_PATH_REFRESH_TIME,
6961 nla_get_u32);
6962 if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
6963 (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
6964 return -EINVAL;
6965 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
6966 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
6967 nla_get_u16);
ea54fba2 6968 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
ab0d76f6 6969 mask,
a4f606ea 6970 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
ab0d76f6
JB
6971 nla_get_u32);
6972 if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
6973 (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
6974 cfg->dot11MeshHWMPactivePathTimeout > 65535))
6975 return -EINVAL;
6976 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
ea54fba2 6977 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
ab0d76f6
JB
6978 nla_get_u16);
6979 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
ea54fba2 6980 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
ab0d76f6 6981 nla_get_u16);
93da9cc1 6982 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6 6983 dot11MeshHWMPnetDiameterTraversalTime, mask,
a4f606ea 6984 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
ab0d76f6
JB
6985 nla_get_u16);
6986 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
6987 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
6988 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
6989 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
6990 nla_get_u16);
6991 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
ea54fba2 6992 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
ab0d76f6
JB
6993 nla_get_u8);
6994 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
6995 NL80211_MESHCONF_FORWARDING, nla_get_u8);
6996 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
6997 NL80211_MESHCONF_RSSI_THRESHOLD,
6998 nla_get_s32);
01d66fbd
BC
6999 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
7000 NL80211_MESHCONF_CONNECTED_TO_GATE,
7001 nla_get_u8);
9757235f
MH
7002 /*
7003 * Check HT operation mode based on
188f60ab 7004 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
9757235f
MH
7005 */
7006 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
7007 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
7008
7009 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
7010 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
7011 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
7012 return -EINVAL;
7013
188f60ab
BC
7014 /* NON_HT_STA bit is reserved, but some programs set it */
7015 ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
9757235f 7016
9757235f 7017 cfg->ht_opmode = ht_opmode;
fd551bac 7018 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
9757235f 7019 }
728b19e5 7020 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6
JB
7021 dot11MeshHWMPactivePathToRootTimeout, mask,
7022 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
7023 nla_get_u32);
7024 if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
7025 (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
7026 cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
7027 return -EINVAL;
7028 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
7029 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
7030 nla_get_u16);
7031 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
7032 mask,
728b19e5 7033 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
ab0d76f6
JB
7034 nla_get_u16);
7035 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
7036 NL80211_MESHCONF_POWER_MODE, nla_get_u32);
7037 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
7038 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
7039 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
7040 NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
bd90fdcc
JB
7041 if (mask_out)
7042 *mask_out = mask;
c80d545d 7043
bd90fdcc
JB
7044 return 0;
7045
7046#undef FILL_IN_MESH_PARAM_IF_SET
7047}
7048
c80d545d
JC
7049static int nl80211_parse_mesh_setup(struct genl_info *info,
7050 struct mesh_setup *setup)
7051{
bb2798d4 7052 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
7053 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
7054
7055 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
7056 return -EINVAL;
8cb08174 7057 if (nla_parse_nested_deprecated(tb, NL80211_MESH_SETUP_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_SETUP], nl80211_mesh_setup_params_policy, info->extack))
c80d545d
JC
7058 return -EINVAL;
7059
d299a1f2
JC
7060 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
7061 setup->sync_method =
7062 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
7063 IEEE80211_SYNC_METHOD_VENDOR :
7064 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
7065
c80d545d
JC
7066 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
7067 setup->path_sel_proto =
7068 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
7069 IEEE80211_PATH_PROTOCOL_VENDOR :
7070 IEEE80211_PATH_PROTOCOL_HWMP;
7071
7072 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
7073 setup->path_metric =
7074 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
7075 IEEE80211_PATH_METRIC_VENDOR :
7076 IEEE80211_PATH_METRIC_AIRTIME;
7077
581a8b0f 7078 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 7079 struct nlattr *ieattr =
581a8b0f 7080 tb[NL80211_MESH_SETUP_IE];
581a8b0f
JC
7081 setup->ie = nla_data(ieattr);
7082 setup->ie_len = nla_len(ieattr);
c80d545d 7083 }
bb2798d4
TP
7084 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
7085 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
7086 return -EINVAL;
7087 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
7088 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
7089 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
7090 if (setup->is_secure)
7091 setup->user_mpm = true;
c80d545d 7092
6e16d90b
CT
7093 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
7094 if (!setup->user_mpm)
7095 return -EINVAL;
7096 setup->auth_id =
7097 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
7098 }
7099
c80d545d
JC
7100 return 0;
7101}
7102
24bdd9f4 7103static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 7104 struct genl_info *info)
bd90fdcc
JB
7105{
7106 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7107 struct net_device *dev = info->user_ptr[1];
29cbe68c 7108 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
7109 struct mesh_config cfg;
7110 u32 mask;
7111 int err;
7112
29cbe68c
JB
7113 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
7114 return -EOPNOTSUPP;
7115
24bdd9f4 7116 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
7117 return -EOPNOTSUPP;
7118
24bdd9f4 7119 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
7120 if (err)
7121 return err;
7122
29cbe68c
JB
7123 wdev_lock(wdev);
7124 if (!wdev->mesh_id_len)
7125 err = -ENOLINK;
7126
7127 if (!err)
e35e4d28 7128 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
7129
7130 wdev_unlock(wdev);
7131
7132 return err;
93da9cc1 7133}
7134
ad30ca2c
AN
7135static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
7136 struct sk_buff *msg)
f130347c 7137{
f130347c
LR
7138 struct nlattr *nl_reg_rules;
7139 unsigned int i;
f130347c 7140
458f4f9e
JB
7141 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
7142 (regdom->dfs_region &&
7143 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 7144 goto nla_put_failure;
458f4f9e 7145
ae0be8de 7146 nl_reg_rules = nla_nest_start_noflag(msg, NL80211_ATTR_REG_RULES);
f130347c 7147 if (!nl_reg_rules)
ad30ca2c 7148 goto nla_put_failure;
f130347c 7149
458f4f9e 7150 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
7151 struct nlattr *nl_reg_rule;
7152 const struct ieee80211_reg_rule *reg_rule;
7153 const struct ieee80211_freq_range *freq_range;
7154 const struct ieee80211_power_rule *power_rule;
97524820 7155 unsigned int max_bandwidth_khz;
f130347c 7156
458f4f9e 7157 reg_rule = &regdom->reg_rules[i];
f130347c
LR
7158 freq_range = &reg_rule->freq_range;
7159 power_rule = &reg_rule->power_rule;
7160
ae0be8de 7161 nl_reg_rule = nla_nest_start_noflag(msg, i);
f130347c 7162 if (!nl_reg_rule)
ad30ca2c 7163 goto nla_put_failure;
f130347c 7164
97524820
JD
7165 max_bandwidth_khz = freq_range->max_bandwidth_khz;
7166 if (!max_bandwidth_khz)
7167 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
7168 reg_rule);
7169
9360ffd1
DM
7170 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
7171 reg_rule->flags) ||
7172 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
7173 freq_range->start_freq_khz) ||
7174 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
7175 freq_range->end_freq_khz) ||
7176 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 7177 max_bandwidth_khz) ||
9360ffd1
DM
7178 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
7179 power_rule->max_antenna_gain) ||
7180 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
7181 power_rule->max_eirp) ||
7182 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
7183 reg_rule->dfs_cac_ms))
ad30ca2c 7184 goto nla_put_failure;
f130347c
LR
7185
7186 nla_nest_end(msg, nl_reg_rule);
7187 }
7188
7189 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
7190 return 0;
7191
7192nla_put_failure:
7193 return -EMSGSIZE;
7194}
7195
7196static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
7197{
7198 const struct ieee80211_regdomain *regdom = NULL;
7199 struct cfg80211_registered_device *rdev;
7200 struct wiphy *wiphy = NULL;
7201 struct sk_buff *msg;
7202 void *hdr;
7203
7204 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7205 if (!msg)
7206 return -ENOBUFS;
7207
7208 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7209 NL80211_CMD_GET_REG);
7210 if (!hdr)
7211 goto put_failure;
7212
7213 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
7214 bool self_managed;
7215
ad30ca2c
AN
7216 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
7217 if (IS_ERR(rdev)) {
7218 nlmsg_free(msg);
7219 return PTR_ERR(rdev);
7220 }
7221
7222 wiphy = &rdev->wiphy;
1bdd716c
AN
7223 self_managed = wiphy->regulatory_flags &
7224 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
7225 regdom = get_wiphy_regdom(wiphy);
7226
1bdd716c
AN
7227 /* a self-managed-reg device must have a private regdom */
7228 if (WARN_ON(!regdom && self_managed)) {
7229 nlmsg_free(msg);
7230 return -EINVAL;
7231 }
7232
ad30ca2c
AN
7233 if (regdom &&
7234 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
7235 goto nla_put_failure;
7236 }
7237
7238 if (!wiphy && reg_last_request_cell_base() &&
7239 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
7240 NL80211_USER_REG_HINT_CELL_BASE))
7241 goto nla_put_failure;
7242
7243 rcu_read_lock();
7244
7245 if (!regdom)
7246 regdom = rcu_dereference(cfg80211_regdomain);
7247
7248 if (nl80211_put_regdom(regdom, msg))
7249 goto nla_put_failure_rcu;
7250
7251 rcu_read_unlock();
f130347c
LR
7252
7253 genlmsg_end(msg, hdr);
5fe231e8 7254 return genlmsg_reply(msg, info);
f130347c 7255
458f4f9e
JB
7256nla_put_failure_rcu:
7257 rcu_read_unlock();
f130347c 7258nla_put_failure:
efe1cf0c 7259put_failure:
d080e275 7260 nlmsg_free(msg);
5fe231e8 7261 return -EMSGSIZE;
f130347c
LR
7262}
7263
ad30ca2c
AN
7264static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
7265 u32 seq, int flags, struct wiphy *wiphy,
7266 const struct ieee80211_regdomain *regdom)
7267{
7268 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
7269 NL80211_CMD_GET_REG);
7270
7271 if (!hdr)
7272 return -1;
7273
0a833c29 7274 genl_dump_check_consistent(cb, hdr);
ad30ca2c
AN
7275
7276 if (nl80211_put_regdom(regdom, msg))
7277 goto nla_put_failure;
7278
7279 if (!wiphy && reg_last_request_cell_base() &&
7280 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
7281 NL80211_USER_REG_HINT_CELL_BASE))
7282 goto nla_put_failure;
7283
7284 if (wiphy &&
7285 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
7286 goto nla_put_failure;
7287
1bdd716c
AN
7288 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
7289 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
7290 goto nla_put_failure;
7291
053c095a
JB
7292 genlmsg_end(msg, hdr);
7293 return 0;
ad30ca2c
AN
7294
7295nla_put_failure:
7296 genlmsg_cancel(msg, hdr);
7297 return -EMSGSIZE;
7298}
7299
7300static int nl80211_get_reg_dump(struct sk_buff *skb,
7301 struct netlink_callback *cb)
7302{
7303 const struct ieee80211_regdomain *regdom = NULL;
7304 struct cfg80211_registered_device *rdev;
7305 int err, reg_idx, start = cb->args[2];
7306
7307 rtnl_lock();
7308
7309 if (cfg80211_regdomain && start == 0) {
7310 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
7311 NLM_F_MULTI, NULL,
7312 rtnl_dereference(cfg80211_regdomain));
7313 if (err < 0)
7314 goto out_err;
7315 }
7316
7317 /* the global regdom is idx 0 */
7318 reg_idx = 1;
7319 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
7320 regdom = get_wiphy_regdom(&rdev->wiphy);
7321 if (!regdom)
7322 continue;
7323
7324 if (++reg_idx <= start)
7325 continue;
7326
7327 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
7328 NLM_F_MULTI, &rdev->wiphy, regdom);
7329 if (err < 0) {
7330 reg_idx--;
7331 break;
7332 }
7333 }
7334
7335 cb->args[2] = reg_idx;
7336 err = skb->len;
7337out_err:
7338 rtnl_unlock();
7339 return err;
7340}
7341
b6863036
JB
7342#ifdef CONFIG_CFG80211_CRDA_SUPPORT
7343static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
7344 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
7345 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
7346 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
7347 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
7348 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
7349 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
7350 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
7351};
7352
7353static int parse_reg_rule(struct nlattr *tb[],
7354 struct ieee80211_reg_rule *reg_rule)
7355{
7356 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
7357 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
7358
7359 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
7360 return -EINVAL;
7361 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
7362 return -EINVAL;
7363 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
7364 return -EINVAL;
7365 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
7366 return -EINVAL;
7367 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
7368 return -EINVAL;
7369
7370 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
7371
7372 freq_range->start_freq_khz =
7373 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
7374 freq_range->end_freq_khz =
7375 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
7376 freq_range->max_bandwidth_khz =
7377 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
7378
7379 power_rule->max_eirp =
7380 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
7381
7382 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
7383 power_rule->max_antenna_gain =
7384 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
7385
7386 if (tb[NL80211_ATTR_DFS_CAC_TIME])
7387 reg_rule->dfs_cac_ms =
7388 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
7389
7390 return 0;
7391}
7392
b2e1b302
LR
7393static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
7394{
7395 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
7396 struct nlattr *nl_reg_rule;
ea372c54
JB
7397 char *alpha2;
7398 int rem_reg_rules, r;
391d132c 7399 u32 num_rules = 0, rule_idx = 0;
4c7d3982 7400 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 7401 struct ieee80211_regdomain *rd;
b2e1b302
LR
7402
7403 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
7404 return -EINVAL;
7405
7406 if (!info->attrs[NL80211_ATTR_REG_RULES])
7407 return -EINVAL;
7408
7409 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
7410
8b60b078
LR
7411 if (info->attrs[NL80211_ATTR_DFS_REGION])
7412 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
7413
b2e1b302 7414 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7415 rem_reg_rules) {
b2e1b302
LR
7416 num_rules++;
7417 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 7418 return -EINVAL;
b2e1b302
LR
7419 }
7420
e438768f
LR
7421 if (!reg_is_valid_request(alpha2))
7422 return -EINVAL;
7423
391d132c 7424 rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
6913b49a
JB
7425 if (!rd)
7426 return -ENOMEM;
b2e1b302
LR
7427
7428 rd->n_reg_rules = num_rules;
7429 rd->alpha2[0] = alpha2[0];
7430 rd->alpha2[1] = alpha2[1];
7431
8b60b078
LR
7432 /*
7433 * Disable DFS master mode if the DFS region was
7434 * not supported or known on this kernel.
7435 */
7436 if (reg_supported_dfs_region(dfs_region))
7437 rd->dfs_region = dfs_region;
7438
b2e1b302 7439 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7440 rem_reg_rules) {
8cb08174
JB
7441 r = nla_parse_nested_deprecated(tb, NL80211_REG_RULE_ATTR_MAX,
7442 nl_reg_rule, reg_rule_policy,
7443 info->extack);
ae811e21
JB
7444 if (r)
7445 goto bad_reg;
b2e1b302
LR
7446 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
7447 if (r)
7448 goto bad_reg;
7449
7450 rule_idx++;
7451
d0e18f83
LR
7452 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
7453 r = -EINVAL;
b2e1b302 7454 goto bad_reg;
d0e18f83 7455 }
b2e1b302
LR
7456 }
7457
06627990
JB
7458 /* set_regdom takes ownership of rd */
7459 return set_regdom(rd, REGD_SOURCE_CRDA);
d2372b31 7460 bad_reg:
b2e1b302 7461 kfree(rd);
d0e18f83 7462 return r;
b2e1b302 7463}
b6863036 7464#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 7465
83f5e2cf
JB
7466static int validate_scan_freqs(struct nlattr *freqs)
7467{
7468 struct nlattr *attr1, *attr2;
7469 int n_channels = 0, tmp1, tmp2;
7470
d7f13f74
SD
7471 nla_for_each_nested(attr1, freqs, tmp1)
7472 if (nla_len(attr1) != sizeof(u32))
7473 return 0;
7474
83f5e2cf
JB
7475 nla_for_each_nested(attr1, freqs, tmp1) {
7476 n_channels++;
7477 /*
7478 * Some hardware has a limited channel list for
7479 * scanning, and it is pretty much nonsensical
7480 * to scan for a channel twice, so disallow that
7481 * and don't require drivers to check that the
7482 * channel list they get isn't longer than what
7483 * they can scan, as long as they can scan all
7484 * the channels they registered at once.
7485 */
7486 nla_for_each_nested(attr2, freqs, tmp2)
7487 if (attr1 != attr2 &&
7488 nla_get_u32(attr1) == nla_get_u32(attr2))
7489 return 0;
7490 }
7491
7492 return n_channels;
7493}
7494
57fbcce3 7495static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 7496{
57fbcce3 7497 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
7498}
7499
7500static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
7501 struct cfg80211_bss_selection *bss_select)
7502{
7503 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
7504 struct nlattr *nest;
7505 int err;
7506 bool found = false;
7507 int i;
7508
7509 /* only process one nested attribute */
7510 nest = nla_data(nla);
7511 if (!nla_ok(nest, nla_len(nest)))
7512 return -EINVAL;
7513
8cb08174
JB
7514 err = nla_parse_nested_deprecated(attr, NL80211_BSS_SELECT_ATTR_MAX,
7515 nest, nl80211_bss_select_policy,
7516 NULL);
38de03d2
AS
7517 if (err)
7518 return err;
7519
7520 /* only one attribute may be given */
7521 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
7522 if (attr[i]) {
7523 if (found)
7524 return -EINVAL;
7525 found = true;
7526 }
7527 }
7528
7529 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
7530
7531 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
7532 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
7533
7534 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
7535 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
7536 bss_select->param.band_pref =
7537 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
7538 if (!is_band_valid(wiphy, bss_select->param.band_pref))
7539 return -EINVAL;
7540 }
7541
7542 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
7543 struct nl80211_bss_select_rssi_adjust *adj_param;
7544
7545 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
7546 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
7547 bss_select->param.adjust.band = adj_param->band;
7548 bss_select->param.adjust.delta = adj_param->delta;
7549 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
7550 return -EINVAL;
7551 }
7552
7553 /* user-space did not provide behaviour attribute */
7554 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
7555 return -EINVAL;
7556
7557 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
7558 return -EINVAL;
7559
7560 return 0;
7561}
7562
9bb7e0f2
JB
7563int nl80211_parse_random_mac(struct nlattr **attrs,
7564 u8 *mac_addr, u8 *mac_addr_mask)
ad2b26ab
JB
7565{
7566 int i;
7567
7568 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
7569 eth_zero_addr(mac_addr);
7570 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
7571 mac_addr[0] = 0x2;
7572 mac_addr_mask[0] = 0x3;
7573
7574 return 0;
7575 }
7576
7577 /* need both or none */
7578 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
7579 return -EINVAL;
7580
7581 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
7582 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
7583
7584 /* don't allow or configure an mcast address */
7585 if (!is_multicast_ether_addr(mac_addr_mask) ||
7586 is_multicast_ether_addr(mac_addr))
7587 return -EINVAL;
7588
7589 /*
7590 * allow users to pass a MAC address that has bits set outside
7591 * of the mask, but don't bother drivers with having to deal
7592 * with such bits
7593 */
7594 for (i = 0; i < ETH_ALEN; i++)
7595 mac_addr[i] &= mac_addr_mask[i];
7596
7597 return 0;
7598}
7599
34373d12
VT
7600static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
7601{
7602 ASSERT_WDEV_LOCK(wdev);
7603
7604 if (!cfg80211_beaconing_iface_active(wdev))
7605 return true;
7606
7607 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
7608 return true;
7609
7610 return regulatory_pre_cac_allowed(wdev->wiphy);
7611}
7612
db0a4ad8
JB
7613static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
7614 enum nl80211_ext_feature_index feat)
7615{
7616 if (!(flags & flag))
7617 return true;
7618 if (wiphy_ext_feature_isset(wiphy, feat))
7619 return true;
7620 return false;
7621}
7622
2d23d073
RZ
7623static int
7624nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
7625 void *request, struct nlattr **attrs,
7626 bool is_sched_scan)
7627{
7628 u8 *mac_addr, *mac_addr_mask;
7629 u32 *flags;
7630 enum nl80211_feature_flags randomness_flag;
7631
7632 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
7633 return 0;
7634
7635 if (is_sched_scan) {
7636 struct cfg80211_sched_scan_request *req = request;
7637
7638 randomness_flag = wdev ?
7639 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
7640 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7641 flags = &req->flags;
7642 mac_addr = req->mac_addr;
7643 mac_addr_mask = req->mac_addr_mask;
7644 } else {
7645 struct cfg80211_scan_request *req = request;
7646
7647 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
7648 flags = &req->flags;
7649 mac_addr = req->mac_addr;
7650 mac_addr_mask = req->mac_addr_mask;
7651 }
7652
7653 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
7654
5037a009
SD
7655 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7656 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
db0a4ad8
JB
7657 !nl80211_check_scan_feat(wiphy, *flags,
7658 NL80211_SCAN_FLAG_LOW_SPAN,
7659 NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
7660 !nl80211_check_scan_feat(wiphy, *flags,
7661 NL80211_SCAN_FLAG_LOW_POWER,
7662 NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
7663 !nl80211_check_scan_feat(wiphy, *flags,
7664 NL80211_SCAN_FLAG_HIGH_ACCURACY,
7665 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
7666 !nl80211_check_scan_feat(wiphy, *flags,
7667 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
7668 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
7669 !nl80211_check_scan_feat(wiphy, *flags,
7670 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
7671 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
7672 !nl80211_check_scan_feat(wiphy, *flags,
7673 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
7674 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
7675 !nl80211_check_scan_feat(wiphy, *flags,
7676 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
2e076f19
JB
7677 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
7678 !nl80211_check_scan_feat(wiphy, *flags,
7679 NL80211_SCAN_FLAG_RANDOM_SN,
7680 NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
7681 !nl80211_check_scan_feat(wiphy, *flags,
7682 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
7683 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
2d23d073
RZ
7684 return -EOPNOTSUPP;
7685
7686 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7687 int err;
7688
7689 if (!(wiphy->features & randomness_flag) ||
7690 (wdev && wdev->current_bss))
7691 return -EOPNOTSUPP;
7692
7693 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
7694 if (err)
7695 return err;
7696 }
7697
2d23d073
RZ
7698 return 0;
7699}
7700
2a519311
JB
7701static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
7702{
4c476991 7703 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 7704 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 7705 struct cfg80211_scan_request *request;
2a519311
JB
7706 struct nlattr *attr;
7707 struct wiphy *wiphy;
83f5e2cf 7708 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 7709 size_t ie_len;
2a519311 7710
79c97e97 7711 wiphy = &rdev->wiphy;
2a519311 7712
cb3b7d87
AB
7713 if (wdev->iftype == NL80211_IFTYPE_NAN)
7714 return -EOPNOTSUPP;
7715
4c476991
JB
7716 if (!rdev->ops->scan)
7717 return -EOPNOTSUPP;
2a519311 7718
f9d15d16 7719 if (rdev->scan_req || rdev->scan_msg) {
f9f47529
JB
7720 err = -EBUSY;
7721 goto unlock;
7722 }
2a519311
JB
7723
7724 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
7725 n_channels = validate_scan_freqs(
7726 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
7727 if (!n_channels) {
7728 err = -EINVAL;
7729 goto unlock;
7730 }
2a519311 7731 } else {
bdfbec2d 7732 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
7733 }
7734
7735 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
7736 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
7737 n_ssids++;
7738
f9f47529
JB
7739 if (n_ssids > wiphy->max_scan_ssids) {
7740 err = -EINVAL;
7741 goto unlock;
7742 }
2a519311 7743
70692ad2
JM
7744 if (info->attrs[NL80211_ATTR_IE])
7745 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
7746 else
7747 ie_len = 0;
7748
f9f47529
JB
7749 if (ie_len > wiphy->max_scan_ie_len) {
7750 err = -EINVAL;
7751 goto unlock;
7752 }
18a83659 7753
2a519311 7754 request = kzalloc(sizeof(*request)
a2cd43c5
LC
7755 + sizeof(*request->ssids) * n_ssids
7756 + sizeof(*request->channels) * n_channels
70692ad2 7757 + ie_len, GFP_KERNEL);
f9f47529
JB
7758 if (!request) {
7759 err = -ENOMEM;
7760 goto unlock;
7761 }
2a519311 7762
2a519311 7763 if (n_ssids)
5ba63533 7764 request->ssids = (void *)&request->channels[n_channels];
2a519311 7765 request->n_ssids = n_ssids;
70692ad2 7766 if (ie_len) {
13874e4b 7767 if (n_ssids)
70692ad2
JM
7768 request->ie = (void *)(request->ssids + n_ssids);
7769 else
7770 request->ie = (void *)(request->channels + n_channels);
7771 }
2a519311 7772
584991dc 7773 i = 0;
2a519311
JB
7774 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
7775 /* user specified, bail out if channel not found */
2a519311 7776 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
7777 struct ieee80211_channel *chan;
7778
7779 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
7780
7781 if (!chan) {
2a519311
JB
7782 err = -EINVAL;
7783 goto out_free;
7784 }
584991dc
JB
7785
7786 /* ignore disabled channels */
7787 if (chan->flags & IEEE80211_CHAN_DISABLED)
7788 continue;
7789
7790 request->channels[i] = chan;
2a519311
JB
7791 i++;
7792 }
7793 } else {
57fbcce3 7794 enum nl80211_band band;
34850ab2 7795
2a519311 7796 /* all channels */
57fbcce3 7797 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 7798 int j;
7a087e74 7799
2a519311
JB
7800 if (!wiphy->bands[band])
7801 continue;
7802 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
7803 struct ieee80211_channel *chan;
7804
7805 chan = &wiphy->bands[band]->channels[j];
7806
7807 if (chan->flags & IEEE80211_CHAN_DISABLED)
7808 continue;
7809
7810 request->channels[i] = chan;
2a519311
JB
7811 i++;
7812 }
7813 }
7814 }
7815
584991dc
JB
7816 if (!i) {
7817 err = -EINVAL;
7818 goto out_free;
7819 }
7820
7821 request->n_channels = i;
7822
34373d12
VT
7823 wdev_lock(wdev);
7824 if (!cfg80211_off_channel_oper_allowed(wdev)) {
7825 struct ieee80211_channel *chan;
7826
7827 if (request->n_channels != 1) {
7828 wdev_unlock(wdev);
7829 err = -EBUSY;
7830 goto out_free;
7831 }
7832
7833 chan = request->channels[0];
7834 if (chan->center_freq != wdev->chandef.chan->center_freq) {
7835 wdev_unlock(wdev);
7836 err = -EBUSY;
7837 goto out_free;
7838 }
7839 }
7840 wdev_unlock(wdev);
7841
2a519311 7842 i = 0;
13874e4b 7843 if (n_ssids) {
2a519311 7844 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 7845 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
7846 err = -EINVAL;
7847 goto out_free;
7848 }
57a27e1d 7849 request->ssids[i].ssid_len = nla_len(attr);
2a519311 7850 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
7851 i++;
7852 }
7853 }
7854
70692ad2
JM
7855 if (info->attrs[NL80211_ATTR_IE]) {
7856 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
7857 memcpy((void *)request->ie,
7858 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
7859 request->ie_len);
7860 }
7861
57fbcce3 7862 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
7863 if (wiphy->bands[i])
7864 request->rates[i] =
7865 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
7866
7867 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
7868 nla_for_each_nested(attr,
7869 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
7870 tmp) {
57fbcce3 7871 enum nl80211_band band = nla_type(attr);
34850ab2 7872
57fbcce3 7873 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
7874 err = -EINVAL;
7875 goto out_free;
7876 }
1b09cd82
FF
7877
7878 if (!wiphy->bands[band])
7879 continue;
7880
34850ab2
JB
7881 err = ieee80211_get_ratemask(wiphy->bands[band],
7882 nla_data(attr),
7883 nla_len(attr),
7884 &request->rates[band]);
7885 if (err)
7886 goto out_free;
7887 }
7888 }
7889
1d76250b
AS
7890 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
7891 if (!wiphy_ext_feature_isset(wiphy,
7892 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
7893 err = -EOPNOTSUPP;
7894 goto out_free;
7895 }
7896
7897 request->duration =
7898 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
7899 request->duration_mandatory =
7900 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
7901 }
7902
2d23d073
RZ
7903 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
7904 false);
7905 if (err)
7906 goto out_free;
ed473771 7907
e9f935e3
RM
7908 request->no_cck =
7909 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
7910
2fa436b3
VK
7911 /* Initial implementation used NL80211_ATTR_MAC to set the specific
7912 * BSSID to scan for. This was problematic because that same attribute
7913 * was already used for another purpose (local random MAC address). The
7914 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
7915 * compatibility with older userspace components, also use the
7916 * NL80211_ATTR_MAC value here if it can be determined to be used for
7917 * the specific BSSID use case instead of the random MAC address
7918 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
7919 */
7920 if (info->attrs[NL80211_ATTR_BSSID])
7921 memcpy(request->bssid,
7922 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
7923 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
7924 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
7925 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
7926 ETH_ALEN);
7927 else
7928 eth_broadcast_addr(request->bssid);
7929
fd014284 7930 request->wdev = wdev;
79c97e97 7931 request->wiphy = &rdev->wiphy;
15d6030b 7932 request->scan_start = jiffies;
2a519311 7933
79c97e97 7934 rdev->scan_req = request;
e35e4d28 7935 err = rdev_scan(rdev, request);
2a519311 7936
463d0183 7937 if (!err) {
fd014284
JB
7938 nl80211_send_scan_start(rdev, wdev);
7939 if (wdev->netdev)
7940 dev_hold(wdev->netdev);
4c476991 7941 } else {
2a519311 7942 out_free:
79c97e97 7943 rdev->scan_req = NULL;
2a519311
JB
7944 kfree(request);
7945 }
3b85875a 7946
f9f47529 7947 unlock:
2a519311
JB
7948 return err;
7949}
7950
91d3ab46
VK
7951static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
7952{
7953 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7954 struct wireless_dev *wdev = info->user_ptr[1];
7955
7956 if (!rdev->ops->abort_scan)
7957 return -EOPNOTSUPP;
7958
7959 if (rdev->scan_msg)
7960 return 0;
7961
7962 if (!rdev->scan_req)
7963 return -ENOENT;
7964
7965 rdev_abort_scan(rdev, wdev);
7966 return 0;
7967}
7968
3b06d277
AS
7969static int
7970nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
7971 struct cfg80211_sched_scan_request *request,
7972 struct nlattr **attrs)
7973{
7974 int tmp, err, i = 0;
7975 struct nlattr *attr;
7976
7977 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
7978 u32 interval;
7979
7980 /*
7981 * If scan plans are not specified,
5a88de53 7982 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
7983 * case one scan plan will be set with the specified scan
7984 * interval and infinite number of iterations.
7985 */
3b06d277
AS
7986 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
7987 if (!interval)
7988 return -EINVAL;
7989
7990 request->scan_plans[0].interval =
7991 DIV_ROUND_UP(interval, MSEC_PER_SEC);
7992 if (!request->scan_plans[0].interval)
7993 return -EINVAL;
7994
7995 if (request->scan_plans[0].interval >
7996 wiphy->max_sched_scan_plan_interval)
7997 request->scan_plans[0].interval =
7998 wiphy->max_sched_scan_plan_interval;
7999
8000 return 0;
8001 }
8002
8003 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
8004 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
8005
8006 if (WARN_ON(i >= n_plans))
8007 return -EINVAL;
8008
8cb08174
JB
8009 err = nla_parse_nested_deprecated(plan,
8010 NL80211_SCHED_SCAN_PLAN_MAX,
8011 attr, nl80211_plan_policy,
8012 NULL);
3b06d277
AS
8013 if (err)
8014 return err;
8015
8016 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
8017 return -EINVAL;
8018
8019 request->scan_plans[i].interval =
8020 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
8021 if (!request->scan_plans[i].interval ||
8022 request->scan_plans[i].interval >
8023 wiphy->max_sched_scan_plan_interval)
8024 return -EINVAL;
8025
8026 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
8027 request->scan_plans[i].iterations =
8028 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
8029 if (!request->scan_plans[i].iterations ||
8030 (request->scan_plans[i].iterations >
8031 wiphy->max_sched_scan_plan_iterations))
8032 return -EINVAL;
8033 } else if (i < n_plans - 1) {
8034 /*
8035 * All scan plans but the last one must specify
8036 * a finite number of iterations
8037 */
8038 return -EINVAL;
8039 }
8040
8041 i++;
8042 }
8043
8044 /*
8045 * The last scan plan must not specify the number of
8046 * iterations, it is supposed to run infinitely
8047 */
8048 if (request->scan_plans[n_plans - 1].iterations)
8049 return -EINVAL;
8050
8051 return 0;
8052}
8053
1e1b11b6 8054static int
8055nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
8056 struct cfg80211_match_set *match_sets,
8057 struct nlattr *tb_band_rssi,
8058 s32 rssi_thold)
8059{
8060 struct nlattr *attr;
8061 int i, tmp, ret = 0;
8062
8063 if (!wiphy_ext_feature_isset(wiphy,
8064 NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
8065 if (tb_band_rssi)
8066 ret = -EOPNOTSUPP;
8067 else
8068 for (i = 0; i < NUM_NL80211_BANDS; i++)
8069 match_sets->per_band_rssi_thold[i] =
8070 NL80211_SCAN_RSSI_THOLD_OFF;
8071 return ret;
8072 }
8073
8074 for (i = 0; i < NUM_NL80211_BANDS; i++)
8075 match_sets->per_band_rssi_thold[i] = rssi_thold;
8076
8077 nla_for_each_nested(attr, tb_band_rssi, tmp) {
8078 enum nl80211_band band = nla_type(attr);
8079
8080 if (band < 0 || band >= NUM_NL80211_BANDS)
8081 return -EINVAL;
8082
8083 match_sets->per_band_rssi_thold[band] = nla_get_s32(attr);
8084 }
8085
8086 return 0;
8087}
8088
256da02d 8089static struct cfg80211_sched_scan_request *
ad2b26ab 8090nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
aad1e812 8091 struct nlattr **attrs, int max_match_sets)
807f8a8c
LC
8092{
8093 struct cfg80211_sched_scan_request *request;
807f8a8c 8094 struct nlattr *attr;
3b06d277 8095 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 8096 enum nl80211_band band;
807f8a8c 8097 size_t ie_len;
a1f1c21c 8098 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 8099 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 8100
256da02d 8101 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 8102 n_channels = validate_scan_freqs(
256da02d 8103 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 8104 if (!n_channels)
256da02d 8105 return ERR_PTR(-EINVAL);
807f8a8c 8106 } else {
bdfbec2d 8107 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
8108 }
8109
256da02d
LC
8110 if (attrs[NL80211_ATTR_SCAN_SSIDS])
8111 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
8112 tmp)
8113 n_ssids++;
8114
93b6aa69 8115 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 8116 return ERR_PTR(-EINVAL);
807f8a8c 8117
ea73cbce
JB
8118 /*
8119 * First, count the number of 'real' matchsets. Due to an issue with
8120 * the old implementation, matchsets containing only the RSSI attribute
8121 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
8122 * RSSI for all matchsets, rather than their own matchset for reporting
8123 * all APs with a strong RSSI. This is needed to be compatible with
8124 * older userspace that treated a matchset with only the RSSI as the
8125 * global RSSI for all other matchsets - if there are other matchsets.
8126 */
256da02d 8127 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 8128 nla_for_each_nested(attr,
256da02d 8129 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
8130 tmp) {
8131 struct nlattr *rssi;
8132
8cb08174
JB
8133 err = nla_parse_nested_deprecated(tb,
8134 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
8135 attr,
8136 nl80211_match_policy,
8137 NULL);
ea73cbce 8138 if (err)
256da02d 8139 return ERR_PTR(err);
3007e352
AVS
8140
8141 /* SSID and BSSID are mutually exclusive */
8142 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
8143 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
8144 return ERR_PTR(-EINVAL);
8145
ea73cbce 8146 /* add other standalone attributes here */
3007e352
AVS
8147 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
8148 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
ea73cbce
JB
8149 n_match_sets++;
8150 continue;
8151 }
8152 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
8153 if (rssi)
8154 default_match_rssi = nla_get_s32(rssi);
8155 }
8156 }
8157
8158 /* However, if there's no other matchset, add the RSSI one */
8159 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
8160 n_match_sets = 1;
a1f1c21c 8161
aad1e812 8162 if (n_match_sets > max_match_sets)
256da02d 8163 return ERR_PTR(-EINVAL);
a1f1c21c 8164
256da02d
LC
8165 if (attrs[NL80211_ATTR_IE])
8166 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
8167 else
8168 ie_len = 0;
8169
5a865bad 8170 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 8171 return ERR_PTR(-EINVAL);
c10841ca 8172
3b06d277
AS
8173 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
8174 /*
8175 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
8176 * each scan plan already specifies its own interval
8177 */
8178 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
8179 return ERR_PTR(-EINVAL);
8180
8181 nla_for_each_nested(attr,
8182 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
8183 n_plans++;
8184 } else {
8185 /*
8186 * The scan interval attribute is kept for backward
8187 * compatibility. If no scan plans are specified and sched scan
8188 * interval is specified, one scan plan will be set with this
8189 * scan interval and infinite number of iterations.
8190 */
8191 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
8192 return ERR_PTR(-EINVAL);
8193
8194 n_plans = 1;
8195 }
8196
8197 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
8198 return ERR_PTR(-EINVAL);
8199
bf95ecdb 8200 if (!wiphy_ext_feature_isset(
8201 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
8202 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
8203 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
8204 return ERR_PTR(-EINVAL);
8205
807f8a8c 8206 request = kzalloc(sizeof(*request)
a2cd43c5 8207 + sizeof(*request->ssids) * n_ssids
a1f1c21c 8208 + sizeof(*request->match_sets) * n_match_sets
3b06d277 8209 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 8210 + sizeof(*request->channels) * n_channels
807f8a8c 8211 + ie_len, GFP_KERNEL);
256da02d
LC
8212 if (!request)
8213 return ERR_PTR(-ENOMEM);
807f8a8c
LC
8214
8215 if (n_ssids)
8216 request->ssids = (void *)&request->channels[n_channels];
8217 request->n_ssids = n_ssids;
8218 if (ie_len) {
13874e4b 8219 if (n_ssids)
807f8a8c
LC
8220 request->ie = (void *)(request->ssids + n_ssids);
8221 else
8222 request->ie = (void *)(request->channels + n_channels);
8223 }
8224
a1f1c21c
LC
8225 if (n_match_sets) {
8226 if (request->ie)
8227 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 8228 else if (n_ssids)
a1f1c21c
LC
8229 request->match_sets =
8230 (void *)(request->ssids + n_ssids);
8231 else
8232 request->match_sets =
8233 (void *)(request->channels + n_channels);
8234 }
8235 request->n_match_sets = n_match_sets;
8236
3b06d277
AS
8237 if (n_match_sets)
8238 request->scan_plans = (void *)(request->match_sets +
8239 n_match_sets);
8240 else if (request->ie)
8241 request->scan_plans = (void *)(request->ie + ie_len);
8242 else if (n_ssids)
8243 request->scan_plans = (void *)(request->ssids + n_ssids);
8244 else
8245 request->scan_plans = (void *)(request->channels + n_channels);
8246
8247 request->n_scan_plans = n_plans;
8248
807f8a8c 8249 i = 0;
256da02d 8250 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
8251 /* user specified, bail out if channel not found */
8252 nla_for_each_nested(attr,
256da02d 8253 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
8254 tmp) {
8255 struct ieee80211_channel *chan;
8256
8257 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
8258
8259 if (!chan) {
8260 err = -EINVAL;
8261 goto out_free;
8262 }
8263
8264 /* ignore disabled channels */
8265 if (chan->flags & IEEE80211_CHAN_DISABLED)
8266 continue;
8267
8268 request->channels[i] = chan;
8269 i++;
8270 }
8271 } else {
8272 /* all channels */
57fbcce3 8273 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 8274 int j;
7a087e74 8275
807f8a8c
LC
8276 if (!wiphy->bands[band])
8277 continue;
8278 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
8279 struct ieee80211_channel *chan;
8280
8281 chan = &wiphy->bands[band]->channels[j];
8282
8283 if (chan->flags & IEEE80211_CHAN_DISABLED)
8284 continue;
8285
8286 request->channels[i] = chan;
8287 i++;
8288 }
8289 }
8290 }
8291
8292 if (!i) {
8293 err = -EINVAL;
8294 goto out_free;
8295 }
8296
8297 request->n_channels = i;
8298
8299 i = 0;
13874e4b 8300 if (n_ssids) {
256da02d 8301 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 8302 tmp) {
57a27e1d 8303 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
8304 err = -EINVAL;
8305 goto out_free;
8306 }
57a27e1d 8307 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
8308 memcpy(request->ssids[i].ssid, nla_data(attr),
8309 nla_len(attr));
807f8a8c
LC
8310 i++;
8311 }
8312 }
8313
a1f1c21c 8314 i = 0;
256da02d 8315 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 8316 nla_for_each_nested(attr,
256da02d 8317 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 8318 tmp) {
3007e352 8319 struct nlattr *ssid, *bssid, *rssi;
a1f1c21c 8320
8cb08174
JB
8321 err = nla_parse_nested_deprecated(tb,
8322 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
8323 attr,
8324 nl80211_match_policy,
8325 NULL);
ae811e21
JB
8326 if (err)
8327 goto out_free;
4a4ab0d7 8328 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
3007e352 8329 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
d39f3b4f
JB
8330
8331 if (!ssid && !bssid) {
8332 i++;
8333 continue;
8334 }
8335
8336 if (WARN_ON(i >= n_match_sets)) {
8337 /* this indicates a programming error,
8338 * the loop above should have verified
8339 * things properly
8340 */
8341 err = -EINVAL;
8342 goto out_free;
8343 }
8344
8345 if (ssid) {
8346 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
ea73cbce
JB
8347 err = -EINVAL;
8348 goto out_free;
8349 }
d39f3b4f
JB
8350 memcpy(request->match_sets[i].ssid.ssid,
8351 nla_data(ssid), nla_len(ssid));
8352 request->match_sets[i].ssid.ssid_len =
8353 nla_len(ssid);
8354 }
8355 if (bssid) {
8356 if (nla_len(bssid) != ETH_ALEN) {
8357 err = -EINVAL;
8358 goto out_free;
a1f1c21c 8359 }
d39f3b4f
JB
8360 memcpy(request->match_sets[i].bssid,
8361 nla_data(bssid), ETH_ALEN);
8362 }
3007e352 8363
d39f3b4f
JB
8364 /* special attribute - old implementation w/a */
8365 request->match_sets[i].rssi_thold = default_match_rssi;
8366 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
8367 if (rssi)
ea73cbce 8368 request->match_sets[i].rssi_thold =
d39f3b4f 8369 nla_get_s32(rssi);
1e1b11b6 8370
8371 /* Parse per band RSSI attribute */
8372 err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
8373 &request->match_sets[i],
8374 tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
8375 request->match_sets[i].rssi_thold);
8376 if (err)
8377 goto out_free;
8378
a1f1c21c
LC
8379 i++;
8380 }
ea73cbce
JB
8381
8382 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 8383 if (i == 0 && n_match_sets)
ea73cbce
JB
8384 request->match_sets[0].rssi_thold = default_match_rssi;
8385
8386 request->min_rssi_thold = INT_MAX;
8387 for (i = 0; i < n_match_sets; i++)
8388 request->min_rssi_thold =
8389 min(request->match_sets[i].rssi_thold,
8390 request->min_rssi_thold);
8391 } else {
8392 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
8393 }
8394
9900e484
JB
8395 if (ie_len) {
8396 request->ie_len = ie_len;
807f8a8c 8397 memcpy((void *)request->ie,
256da02d 8398 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
8399 request->ie_len);
8400 }
8401
2d23d073
RZ
8402 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
8403 if (err)
8404 goto out_free;
ed473771 8405
9c748934
LC
8406 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
8407 request->delay =
8408 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
8409
bf95ecdb 8410 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
8411 request->relative_rssi = nla_get_s8(
8412 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
8413 request->relative_rssi_set = true;
8414 }
8415
8416 if (request->relative_rssi_set &&
8417 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
8418 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
8419
8420 rssi_adjust = nla_data(
8421 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
8422 request->rssi_adjust.band = rssi_adjust->band;
8423 request->rssi_adjust.delta = rssi_adjust->delta;
8424 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
8425 err = -EINVAL;
8426 goto out_free;
8427 }
8428 }
8429
3b06d277
AS
8430 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
8431 if (err)
8432 goto out_free;
8433
15d6030b 8434 request->scan_start = jiffies;
807f8a8c 8435
256da02d 8436 return request;
807f8a8c
LC
8437
8438out_free:
8439 kfree(request);
256da02d
LC
8440 return ERR_PTR(err);
8441}
8442
8443static int nl80211_start_sched_scan(struct sk_buff *skb,
8444 struct genl_info *info)
8445{
8446 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8447 struct net_device *dev = info->user_ptr[1];
ad2b26ab 8448 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 8449 struct cfg80211_sched_scan_request *sched_scan_req;
ca986ad9 8450 bool want_multi;
256da02d
LC
8451 int err;
8452
ca986ad9 8453 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
256da02d
LC
8454 return -EOPNOTSUPP;
8455
ca986ad9
AVS
8456 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
8457 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
8458 if (err)
8459 return err;
256da02d 8460
31a60ed1 8461 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
aad1e812
AVS
8462 info->attrs,
8463 rdev->wiphy.max_match_sets);
31a60ed1
JR
8464
8465 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
8466 if (err)
8467 goto out_err;
8468
ca986ad9
AVS
8469 /* leave request id zero for legacy request
8470 * or if driver does not support multi-scheduled scan
8471 */
2fd351a8
DK
8472 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1)
8473 sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
ca986ad9 8474
31a60ed1 8475 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
8476 if (err)
8477 goto out_free;
8478
31a60ed1
JR
8479 sched_scan_req->dev = dev;
8480 sched_scan_req->wiphy = &rdev->wiphy;
8481
93a1e86c
JR
8482 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
8483 sched_scan_req->owner_nlportid = info->snd_portid;
8484
ca986ad9 8485 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
256da02d 8486
96b08fd6 8487 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
256da02d
LC
8488 return 0;
8489
8490out_free:
31a60ed1 8491 kfree(sched_scan_req);
256da02d 8492out_err:
807f8a8c
LC
8493 return err;
8494}
8495
8496static int nl80211_stop_sched_scan(struct sk_buff *skb,
8497 struct genl_info *info)
8498{
ca986ad9 8499 struct cfg80211_sched_scan_request *req;
807f8a8c 8500 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ca986ad9 8501 u64 cookie;
807f8a8c 8502
ca986ad9 8503 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
807f8a8c
LC
8504 return -EOPNOTSUPP;
8505
ca986ad9
AVS
8506 if (info->attrs[NL80211_ATTR_COOKIE]) {
8507 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
8508 return __cfg80211_stop_sched_scan(rdev, cookie, false);
8509 }
8510
8511 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
8512 struct cfg80211_sched_scan_request,
8513 list);
8514 if (!req || req->reqid ||
8515 (req->owner_nlportid &&
8516 req->owner_nlportid != info->snd_portid))
8517 return -ENOENT;
8518
8519 return cfg80211_stop_sched_scan_req(rdev, req, false);
807f8a8c
LC
8520}
8521
04f39047
SW
8522static int nl80211_start_radar_detection(struct sk_buff *skb,
8523 struct genl_info *info)
8524{
8525 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8526 struct net_device *dev = info->user_ptr[1];
8527 struct wireless_dev *wdev = dev->ieee80211_ptr;
13cf6dec 8528 struct wiphy *wiphy = wdev->wiphy;
04f39047 8529 struct cfg80211_chan_def chandef;
55f7435c 8530 enum nl80211_dfs_regions dfs_region;
31559f35 8531 unsigned int cac_time_ms;
04f39047
SW
8532 int err;
8533
13cf6dec 8534 dfs_region = reg_get_dfs_region(wiphy);
55f7435c
LR
8535 if (dfs_region == NL80211_DFS_UNSET)
8536 return -EINVAL;
8537
04f39047
SW
8538 err = nl80211_parse_chandef(rdev, info, &chandef);
8539 if (err)
8540 return err;
8541
ff311bc1
SW
8542 if (netif_carrier_ok(dev))
8543 return -EBUSY;
8544
04f39047
SW
8545 if (wdev->cac_started)
8546 return -EBUSY;
8547
13cf6dec 8548 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
04f39047
SW
8549 if (err < 0)
8550 return err;
8551
8552 if (err == 0)
8553 return -EINVAL;
8554
13cf6dec 8555 if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
04f39047
SW
8556 return -EINVAL;
8557
13cf6dec
DL
8558 /* CAC start is offloaded to HW and can't be started manually */
8559 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
8560 return -EOPNOTSUPP;
8561
04f39047
SW
8562 if (!rdev->ops->start_radar_detection)
8563 return -EOPNOTSUPP;
8564
31559f35
JD
8565 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
8566 if (WARN_ON(!cac_time_ms))
8567 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
8568
a1056b1b 8569 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 8570 if (!err) {
9e0e2961 8571 wdev->chandef = chandef;
04f39047
SW
8572 wdev->cac_started = true;
8573 wdev->cac_start_time = jiffies;
31559f35 8574 wdev->cac_time_ms = cac_time_ms;
04f39047 8575 }
04f39047
SW
8576 return err;
8577}
8578
30c63115
S
8579static int nl80211_notify_radar_detection(struct sk_buff *skb,
8580 struct genl_info *info)
8581{
8582 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8583 struct net_device *dev = info->user_ptr[1];
8584 struct wireless_dev *wdev = dev->ieee80211_ptr;
8585 struct wiphy *wiphy = wdev->wiphy;
8586 struct cfg80211_chan_def chandef;
8587 enum nl80211_dfs_regions dfs_region;
8588 int err;
8589
8590 dfs_region = reg_get_dfs_region(wiphy);
8591 if (dfs_region == NL80211_DFS_UNSET) {
8592 GENL_SET_ERR_MSG(info,
8593 "DFS Region is not set. Unexpected Radar indication");
8594 return -EINVAL;
8595 }
8596
8597 err = nl80211_parse_chandef(rdev, info, &chandef);
8598 if (err) {
8599 GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
8600 return err;
8601 }
8602
8603 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
8604 if (err < 0) {
8605 GENL_SET_ERR_MSG(info, "chandef is invalid");
8606 return err;
8607 }
8608
8609 if (err == 0) {
8610 GENL_SET_ERR_MSG(info,
8611 "Unexpected Radar indication for chandef/iftype");
8612 return -EINVAL;
8613 }
8614
8615 /* Do not process this notification if radar is already detected
8616 * by kernel on this channel, and return success.
8617 */
8618 if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
8619 return 0;
8620
8621 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
8622
8623 cfg80211_sched_dfs_chan_update(rdev);
8624
a680fe46 8625 rdev->radar_chandef = chandef;
30c63115
S
8626
8627 /* Propagate this notification to other radios as well */
8628 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
8629
8630 return 0;
8631}
8632
16ef1fe2
SW
8633static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
8634{
8635 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8636 struct net_device *dev = info->user_ptr[1];
8637 struct wireless_dev *wdev = dev->ieee80211_ptr;
8638 struct cfg80211_csa_settings params;
8639 /* csa_attrs is defined static to avoid waste of stack size - this
8640 * function is called under RTNL lock, so this should not be a problem.
8641 */
8642 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
16ef1fe2 8643 int err;
ee4bc9e7 8644 bool need_new_beacon = false;
8d9de16f 8645 bool need_handle_dfs_flag = true;
9a774c78 8646 int len, i;
252e07ca 8647 u32 cs_count;
16ef1fe2
SW
8648
8649 if (!rdev->ops->channel_switch ||
8650 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
8651 return -EOPNOTSUPP;
8652
ee4bc9e7
SW
8653 switch (dev->ieee80211_ptr->iftype) {
8654 case NL80211_IFTYPE_AP:
8655 case NL80211_IFTYPE_P2P_GO:
8656 need_new_beacon = true;
8d9de16f
BB
8657 /* For all modes except AP the handle_dfs flag needs to be
8658 * supplied to tell the kernel that userspace will handle radar
8659 * events when they happen. Otherwise a switch to a channel
8660 * requiring DFS will be rejected.
8661 */
8662 need_handle_dfs_flag = false;
ee4bc9e7
SW
8663
8664 /* useless if AP is not running */
8665 if (!wdev->beacon_interval)
1ff79dfa 8666 return -ENOTCONN;
ee4bc9e7
SW
8667 break;
8668 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
8669 if (!wdev->ssid_len)
8670 return -ENOTCONN;
8671 break;
c6da674a 8672 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
8673 if (!wdev->mesh_id_len)
8674 return -ENOTCONN;
ee4bc9e7
SW
8675 break;
8676 default:
16ef1fe2 8677 return -EOPNOTSUPP;
ee4bc9e7 8678 }
16ef1fe2
SW
8679
8680 memset(&params, 0, sizeof(params));
c177db2d 8681 params.beacon_csa.ftm_responder = -1;
16ef1fe2
SW
8682
8683 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
8684 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
8685 return -EINVAL;
8686
8687 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 8688 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
8689 return -EINVAL;
8690
252e07ca
LC
8691 /* Even though the attribute is u32, the specification says
8692 * u8, so let's make sure we don't overflow.
8693 */
8694 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
8695 if (cs_count > 255)
8696 return -EINVAL;
8697
8698 params.count = cs_count;
16ef1fe2 8699
ee4bc9e7
SW
8700 if (!need_new_beacon)
8701 goto skip_beacons;
8702
81e54d08 8703 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
16ef1fe2
SW
8704 if (err)
8705 return err;
8706
8cb08174
JB
8707 err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
8708 info->attrs[NL80211_ATTR_CSA_IES],
8709 nl80211_policy, info->extack);
16ef1fe2
SW
8710 if (err)
8711 return err;
8712
81e54d08 8713 err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
16ef1fe2
SW
8714 if (err)
8715 return err;
8716
8717 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
8718 return -EINVAL;
8719
9a774c78
AO
8720 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
8721 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
8722 return -EINVAL;
8723
9a774c78
AO
8724 params.n_counter_offsets_beacon = len / sizeof(u16);
8725 if (rdev->wiphy.max_num_csa_counters &&
8726 (params.n_counter_offsets_beacon >
8727 rdev->wiphy.max_num_csa_counters))
16ef1fe2
SW
8728 return -EINVAL;
8729
9a774c78
AO
8730 params.counter_offsets_beacon =
8731 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
8732
8733 /* sanity checks - counters should fit and be the same */
8734 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
8735 u16 offset = params.counter_offsets_beacon[i];
8736
8737 if (offset >= params.beacon_csa.tail_len)
8738 return -EINVAL;
8739
8740 if (params.beacon_csa.tail[offset] != params.count)
8741 return -EINVAL;
8742 }
8743
16ef1fe2 8744 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
9a774c78
AO
8745 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
8746 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
8747 return -EINVAL;
8748
9a774c78
AO
8749 params.n_counter_offsets_presp = len / sizeof(u16);
8750 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 8751 (params.n_counter_offsets_presp >
9a774c78 8752 rdev->wiphy.max_num_csa_counters))
16ef1fe2 8753 return -EINVAL;
9a774c78
AO
8754
8755 params.counter_offsets_presp =
8756 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
8757
8758 /* sanity checks - counters should fit and be the same */
8759 for (i = 0; i < params.n_counter_offsets_presp; i++) {
8760 u16 offset = params.counter_offsets_presp[i];
8761
8762 if (offset >= params.beacon_csa.probe_resp_len)
8763 return -EINVAL;
8764
8765 if (params.beacon_csa.probe_resp[offset] !=
8766 params.count)
8767 return -EINVAL;
8768 }
16ef1fe2
SW
8769 }
8770
ee4bc9e7 8771skip_beacons:
16ef1fe2
SW
8772 err = nl80211_parse_chandef(rdev, info, &params.chandef);
8773 if (err)
8774 return err;
8775
923b352f
AN
8776 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
8777 wdev->iftype))
16ef1fe2
SW
8778 return -EINVAL;
8779
2beb6dab
LC
8780 err = cfg80211_chandef_dfs_required(wdev->wiphy,
8781 &params.chandef,
8782 wdev->iftype);
8783 if (err < 0)
8784 return err;
8785
8d9de16f 8786 if (err > 0) {
2beb6dab 8787 params.radar_required = true;
8d9de16f
BB
8788 if (need_handle_dfs_flag &&
8789 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
8790 return -EINVAL;
8791 }
8792 }
16ef1fe2 8793
16ef1fe2
SW
8794 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
8795 params.block_tx = true;
8796
c56589ed
SW
8797 wdev_lock(wdev);
8798 err = rdev_channel_switch(rdev, dev, &params);
8799 wdev_unlock(wdev);
8800
8801 return err;
16ef1fe2
SW
8802}
8803
9720bb3a
JB
8804static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
8805 u32 seq, int flags,
2a519311 8806 struct cfg80211_registered_device *rdev,
48ab905d
JB
8807 struct wireless_dev *wdev,
8808 struct cfg80211_internal_bss *intbss)
2a519311 8809{
48ab905d 8810 struct cfg80211_bss *res = &intbss->pub;
9caf0364 8811 const struct cfg80211_bss_ies *ies;
2a519311
JB
8812 void *hdr;
8813 struct nlattr *bss;
48ab905d
JB
8814
8815 ASSERT_WDEV_LOCK(wdev);
2a519311 8816
15e47304 8817 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
8818 NL80211_CMD_NEW_SCAN_RESULTS);
8819 if (!hdr)
8820 return -1;
8821
0a833c29 8822 genl_dump_check_consistent(cb, hdr);
9720bb3a 8823
97990a06
JB
8824 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
8825 goto nla_put_failure;
8826 if (wdev->netdev &&
9360ffd1
DM
8827 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
8828 goto nla_put_failure;
2dad624e
ND
8829 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
8830 NL80211_ATTR_PAD))
97990a06 8831 goto nla_put_failure;
2a519311 8832
ae0be8de 8833 bss = nla_nest_start_noflag(msg, NL80211_ATTR_BSS);
2a519311
JB
8834 if (!bss)
8835 goto nla_put_failure;
9360ffd1 8836 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 8837 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 8838 goto nla_put_failure;
9caf0364
JB
8839
8840 rcu_read_lock();
0e227084
JB
8841 /* indicate whether we have probe response data or not */
8842 if (rcu_access_pointer(res->proberesp_ies) &&
8843 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
8844 goto fail_unlock_rcu;
8845
8846 /* this pointer prefers to be pointed to probe response data
8847 * but is always valid
8848 */
9caf0364 8849 ies = rcu_dereference(res->ies);
8cef2c9d 8850 if (ies) {
2dad624e
ND
8851 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
8852 NL80211_BSS_PAD))
8cef2c9d 8853 goto fail_unlock_rcu;
8cef2c9d
JB
8854 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
8855 ies->len, ies->data))
8856 goto fail_unlock_rcu;
9caf0364 8857 }
0e227084
JB
8858
8859 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 8860 ies = rcu_dereference(res->beacon_ies);
0e227084 8861 if (ies && ies->from_beacon) {
2dad624e
ND
8862 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
8863 NL80211_BSS_PAD))
8cef2c9d
JB
8864 goto fail_unlock_rcu;
8865 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
8866 ies->len, ies->data))
8867 goto fail_unlock_rcu;
9caf0364
JB
8868 }
8869 rcu_read_unlock();
8870
9360ffd1
DM
8871 if (res->beacon_interval &&
8872 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
8873 goto nla_put_failure;
8874 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
8875 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 8876 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
8877 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
8878 jiffies_to_msecs(jiffies - intbss->ts)))
8879 goto nla_put_failure;
2a519311 8880
1d76250b
AS
8881 if (intbss->parent_tsf &&
8882 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
8883 intbss->parent_tsf, NL80211_BSS_PAD) ||
8884 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
8885 intbss->parent_bssid)))
8886 goto nla_put_failure;
8887
6e19bc4b 8888 if (intbss->ts_boottime &&
2dad624e
ND
8889 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
8890 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
8891 goto nla_put_failure;
8892
983dafaa
SD
8893 if (!nl80211_put_signal(msg, intbss->pub.chains,
8894 intbss->pub.chain_signal,
8895 NL80211_BSS_CHAIN_SIGNAL))
8896 goto nla_put_failure;
8897
77965c97 8898 switch (rdev->wiphy.signal_type) {
2a519311 8899 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
8900 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
8901 goto nla_put_failure;
2a519311
JB
8902 break;
8903 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
8904 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
8905 goto nla_put_failure;
2a519311
JB
8906 break;
8907 default:
8908 break;
8909 }
8910
48ab905d 8911 switch (wdev->iftype) {
074ac8df 8912 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 8913 case NL80211_IFTYPE_STATION:
9360ffd1
DM
8914 if (intbss == wdev->current_bss &&
8915 nla_put_u32(msg, NL80211_BSS_STATUS,
8916 NL80211_BSS_STATUS_ASSOCIATED))
8917 goto nla_put_failure;
48ab905d
JB
8918 break;
8919 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
8920 if (intbss == wdev->current_bss &&
8921 nla_put_u32(msg, NL80211_BSS_STATUS,
8922 NL80211_BSS_STATUS_IBSS_JOINED))
8923 goto nla_put_failure;
48ab905d
JB
8924 break;
8925 default:
8926 break;
8927 }
8928
2a519311
JB
8929 nla_nest_end(msg, bss);
8930
053c095a
JB
8931 genlmsg_end(msg, hdr);
8932 return 0;
2a519311 8933
8cef2c9d
JB
8934 fail_unlock_rcu:
8935 rcu_read_unlock();
2a519311
JB
8936 nla_put_failure:
8937 genlmsg_cancel(msg, hdr);
8938 return -EMSGSIZE;
8939}
8940
97990a06 8941static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 8942{
48ab905d 8943 struct cfg80211_registered_device *rdev;
2a519311 8944 struct cfg80211_internal_bss *scan;
48ab905d 8945 struct wireless_dev *wdev;
97990a06 8946 int start = cb->args[2], idx = 0;
2a519311
JB
8947 int err;
8948
ea90e0dc 8949 rtnl_lock();
5297c65c 8950 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
ea90e0dc
JB
8951 if (err) {
8952 rtnl_unlock();
67748893 8953 return err;
ea90e0dc 8954 }
2a519311 8955
48ab905d
JB
8956 wdev_lock(wdev);
8957 spin_lock_bh(&rdev->bss_lock);
d1e23c94
DK
8958
8959 /*
8960 * dump_scan will be called multiple times to break up the scan results
8961 * into multiple messages. It is unlikely that any more bss-es will be
8962 * expired after the first call, so only call only call this on the
8963 * first dump_scan invocation.
8964 */
8965 if (start == 0)
8966 cfg80211_bss_expire(rdev);
48ab905d 8967
9720bb3a
JB
8968 cb->seq = rdev->bss_generation;
8969
48ab905d 8970 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
8971 if (++idx <= start)
8972 continue;
9720bb3a 8973 if (nl80211_send_bss(skb, cb,
2a519311 8974 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 8975 rdev, wdev, scan) < 0) {
2a519311 8976 idx--;
67748893 8977 break;
2a519311
JB
8978 }
8979 }
8980
48ab905d
JB
8981 spin_unlock_bh(&rdev->bss_lock);
8982 wdev_unlock(wdev);
2a519311 8983
97990a06 8984 cb->args[2] = idx;
ea90e0dc 8985 rtnl_unlock();
2a519311 8986
67748893 8987 return skb->len;
2a519311
JB
8988}
8989
15e47304 8990static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
8991 int flags, struct net_device *dev,
8992 bool allow_radio_stats,
8993 struct survey_info *survey)
61fa713c
HS
8994{
8995 void *hdr;
8996 struct nlattr *infoattr;
8997
11f78ac3
JB
8998 /* skip radio stats if userspace didn't request them */
8999 if (!survey->channel && !allow_radio_stats)
9000 return 0;
9001
15e47304 9002 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
9003 NL80211_CMD_NEW_SURVEY_RESULTS);
9004 if (!hdr)
9005 return -ENOMEM;
9006
9360ffd1
DM
9007 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9008 goto nla_put_failure;
61fa713c 9009
ae0be8de 9010 infoattr = nla_nest_start_noflag(msg, NL80211_ATTR_SURVEY_INFO);
61fa713c
HS
9011 if (!infoattr)
9012 goto nla_put_failure;
9013
11f78ac3
JB
9014 if (survey->channel &&
9015 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
9016 survey->channel->center_freq))
9017 goto nla_put_failure;
9018
9019 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
9020 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
9021 goto nla_put_failure;
9022 if ((survey->filled & SURVEY_INFO_IN_USE) &&
9023 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
9024 goto nla_put_failure;
4ed20beb 9025 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
9026 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
9027 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 9028 goto nla_put_failure;
4ed20beb 9029 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
9030 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
9031 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9032 goto nla_put_failure;
4ed20beb 9033 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
9034 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
9035 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9036 goto nla_put_failure;
4ed20beb 9037 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
9038 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
9039 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9040 goto nla_put_failure;
4ed20beb 9041 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
9042 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
9043 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9044 goto nla_put_failure;
052536ab 9045 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
9046 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
9047 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 9048 goto nla_put_failure;
c8cd6e7f
FF
9049 if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) &&
9050 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX,
9051 survey->time_bss_rx, NL80211_SURVEY_INFO_PAD))
9052 goto nla_put_failure;
61fa713c
HS
9053
9054 nla_nest_end(msg, infoattr);
9055
053c095a
JB
9056 genlmsg_end(msg, hdr);
9057 return 0;
61fa713c
HS
9058
9059 nla_put_failure:
9060 genlmsg_cancel(msg, hdr);
9061 return -EMSGSIZE;
9062}
9063
11f78ac3 9064static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 9065{
50508d94 9066 struct nlattr **attrbuf;
61fa713c 9067 struct survey_info survey;
1b8ec87a 9068 struct cfg80211_registered_device *rdev;
97990a06
JB
9069 struct wireless_dev *wdev;
9070 int survey_idx = cb->args[2];
61fa713c 9071 int res;
11f78ac3 9072 bool radio_stats;
61fa713c 9073
50508d94
JB
9074 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
9075 if (!attrbuf)
9076 return -ENOMEM;
9077
ea90e0dc 9078 rtnl_lock();
5297c65c 9079 res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 9080 if (res)
ea90e0dc 9081 goto out_err;
61fa713c 9082
11f78ac3 9083 /* prepare_wdev_dump parsed the attributes */
c90c39da 9084 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 9085
97990a06
JB
9086 if (!wdev->netdev) {
9087 res = -EINVAL;
9088 goto out_err;
9089 }
9090
1b8ec87a 9091 if (!rdev->ops->dump_survey) {
61fa713c
HS
9092 res = -EOPNOTSUPP;
9093 goto out_err;
9094 }
9095
9096 while (1) {
1b8ec87a 9097 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
9098 if (res == -ENOENT)
9099 break;
9100 if (res)
9101 goto out_err;
9102
11f78ac3
JB
9103 /* don't send disabled channels, but do send non-channel data */
9104 if (survey.channel &&
9105 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
9106 survey_idx++;
9107 continue;
9108 }
9109
61fa713c 9110 if (nl80211_send_survey(skb,
15e47304 9111 NETLINK_CB(cb->skb).portid,
61fa713c 9112 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 9113 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
9114 goto out;
9115 survey_idx++;
9116 }
9117
9118 out:
97990a06 9119 cb->args[2] = survey_idx;
61fa713c
HS
9120 res = skb->len;
9121 out_err:
50508d94 9122 kfree(attrbuf);
ea90e0dc 9123 rtnl_unlock();
61fa713c
HS
9124 return res;
9125}
9126
b23aa676
SO
9127static bool nl80211_valid_wpa_versions(u32 wpa_versions)
9128{
9129 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
cc3e14c2
CHH
9130 NL80211_WPA_VERSION_2 |
9131 NL80211_WPA_VERSION_3));
b23aa676
SO
9132}
9133
636a5d36
JM
9134static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
9135{
4c476991
JB
9136 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9137 struct net_device *dev = info->user_ptr[1];
19957bb3 9138 struct ieee80211_channel *chan;
11b6b5a4
JM
9139 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
9140 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 9141 enum nl80211_auth_type auth_type;
fffd0934 9142 struct key_parse key;
d5cdfacb 9143 bool local_state_change;
636a5d36 9144
f4a11bb0
JB
9145 if (!info->attrs[NL80211_ATTR_MAC])
9146 return -EINVAL;
9147
1778092e
JM
9148 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
9149 return -EINVAL;
9150
19957bb3
JB
9151 if (!info->attrs[NL80211_ATTR_SSID])
9152 return -EINVAL;
9153
9154 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
9155 return -EINVAL;
9156
fffd0934
JB
9157 err = nl80211_parse_key(info, &key);
9158 if (err)
9159 return err;
9160
9161 if (key.idx >= 0) {
e31b8213
JB
9162 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
9163 return -EINVAL;
fffd0934
JB
9164 if (!key.p.key || !key.p.key_len)
9165 return -EINVAL;
9166 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
9167 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
9168 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
9169 key.p.key_len != WLAN_KEY_LEN_WEP104))
9170 return -EINVAL;
b6b5555b 9171 if (key.idx > 3)
fffd0934
JB
9172 return -EINVAL;
9173 } else {
9174 key.p.key_len = 0;
9175 key.p.key = NULL;
9176 }
9177
afea0b7a
JB
9178 if (key.idx >= 0) {
9179 int i;
9180 bool ok = false;
7a087e74 9181
afea0b7a
JB
9182 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
9183 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
9184 ok = true;
9185 break;
9186 }
9187 }
4c476991
JB
9188 if (!ok)
9189 return -EINVAL;
afea0b7a
JB
9190 }
9191
4c476991
JB
9192 if (!rdev->ops->auth)
9193 return -EOPNOTSUPP;
636a5d36 9194
074ac8df 9195 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9196 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9197 return -EOPNOTSUPP;
eec60b03 9198
19957bb3 9199 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
9200 chan = nl80211_get_valid_chan(&rdev->wiphy,
9201 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
9202 if (!chan)
4c476991 9203 return -EINVAL;
636a5d36 9204
19957bb3
JB
9205 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9206 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
9207
9208 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
9209 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9210 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9211 }
9212
19957bb3 9213 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 9214 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 9215 return -EINVAL;
636a5d36 9216
63181060
JM
9217 if ((auth_type == NL80211_AUTHTYPE_SAE ||
9218 auth_type == NL80211_AUTHTYPE_FILS_SK ||
9219 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
9220 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 9221 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
9222 return -EINVAL;
9223
11b6b5a4 9224 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
9225 if (auth_type != NL80211_AUTHTYPE_SAE &&
9226 auth_type != NL80211_AUTHTYPE_FILS_SK &&
9227 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
9228 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 9229 return -EINVAL;
11b6b5a4
JM
9230 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
9231 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e 9232 /* need to include at least Auth Transaction and Status Code */
11b6b5a4 9233 if (auth_data_len < 4)
e39e5b5e
JM
9234 return -EINVAL;
9235 }
9236
d5cdfacb
JM
9237 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
9238
95de817b
JB
9239 /*
9240 * Since we no longer track auth state, ignore
9241 * requests to only change local state.
9242 */
9243 if (local_state_change)
9244 return 0;
9245
91bf9b26
JB
9246 wdev_lock(dev->ieee80211_ptr);
9247 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
9248 ssid, ssid_len, ie, ie_len,
9249 key.p.key, key.p.key_len, key.idx,
11b6b5a4 9250 auth_data, auth_data_len);
91bf9b26
JB
9251 wdev_unlock(dev->ieee80211_ptr);
9252 return err;
636a5d36
JM
9253}
9254
64bf3d4b
DK
9255static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
9256 struct genl_info *info)
9257{
9258 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9259 GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
9260 return -EINVAL;
9261 }
9262
9263 if (!rdev->ops->tx_control_port ||
9264 !wiphy_ext_feature_isset(&rdev->wiphy,
9265 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
9266 return -EOPNOTSUPP;
9267
9268 return 0;
9269}
9270
c0692b8f
JB
9271static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
9272 struct genl_info *info,
3dc27d25
JB
9273 struct cfg80211_crypto_settings *settings,
9274 int cipher_limit)
b23aa676 9275{
c0b2bbd8
JB
9276 memset(settings, 0, sizeof(*settings));
9277
b23aa676
SO
9278 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
9279
c0692b8f
JB
9280 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
9281 u16 proto;
7a087e74 9282
c0692b8f
JB
9283 proto = nla_get_u16(
9284 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
9285 settings->control_port_ethertype = cpu_to_be16(proto);
9286 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
9287 proto != ETH_P_PAE)
9288 return -EINVAL;
9289 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
9290 settings->control_port_no_encrypt = true;
9291 } else
9292 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
9293
64bf3d4b
DK
9294 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
9295 int r = validate_pae_over_nl80211(rdev, info);
9296
9297 if (r < 0)
9298 return r;
9299
9300 settings->control_port_over_nl80211 = true;
9301 }
9302
b23aa676
SO
9303 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
9304 void *data;
9305 int len, i;
9306
9307 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
9308 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
9309 settings->n_ciphers_pairwise = len / sizeof(u32);
9310
9311 if (len % sizeof(u32))
9312 return -EINVAL;
9313
3dc27d25 9314 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
9315 return -EINVAL;
9316
9317 memcpy(settings->ciphers_pairwise, data, len);
9318
9319 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
9320 if (!cfg80211_supported_cipher_suite(
9321 &rdev->wiphy,
b23aa676
SO
9322 settings->ciphers_pairwise[i]))
9323 return -EINVAL;
9324 }
9325
9326 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
9327 settings->cipher_group =
9328 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
9329 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
9330 settings->cipher_group))
b23aa676
SO
9331 return -EINVAL;
9332 }
9333
9334 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
9335 settings->wpa_versions =
9336 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
9337 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
9338 return -EINVAL;
9339 }
9340
9341 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
9342 void *data;
6d30240e 9343 int len;
b23aa676
SO
9344
9345 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
9346 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
9347 settings->n_akm_suites = len / sizeof(u32);
9348
9349 if (len % sizeof(u32))
9350 return -EINVAL;
9351
1b9ca027
JM
9352 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
9353 return -EINVAL;
9354
b23aa676 9355 memcpy(settings->akm_suites, data, len);
b23aa676
SO
9356 }
9357
91b5ab62
EP
9358 if (info->attrs[NL80211_ATTR_PMK]) {
9359 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
9360 return -EINVAL;
9361 if (!wiphy_ext_feature_isset(&rdev->wiphy,
9362 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
9363 return -EINVAL;
9364 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
9365 }
9366
26f7044e
CHH
9367 if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
9368 if (!wiphy_ext_feature_isset(&rdev->wiphy,
9369 NL80211_EXT_FEATURE_SAE_OFFLOAD))
9370 return -EINVAL;
9371 settings->sae_pwd =
9372 nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
9373 settings->sae_pwd_len =
9374 nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
9375 }
9376
b23aa676
SO
9377 return 0;
9378}
9379
636a5d36
JM
9380static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
9381{
4c476991
JB
9382 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9383 struct net_device *dev = info->user_ptr[1];
f444de05 9384 struct ieee80211_channel *chan;
f62fab73
JB
9385 struct cfg80211_assoc_request req = {};
9386 const u8 *bssid, *ssid;
9387 int err, ssid_len = 0;
636a5d36 9388
bad29297
AZ
9389 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9390 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9391 return -EPERM;
9392
f4a11bb0 9393 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
9394 !info->attrs[NL80211_ATTR_SSID] ||
9395 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
9396 return -EINVAL;
9397
4c476991
JB
9398 if (!rdev->ops->assoc)
9399 return -EOPNOTSUPP;
636a5d36 9400
074ac8df 9401 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9402 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9403 return -EOPNOTSUPP;
eec60b03 9404
19957bb3 9405 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 9406
664834de
JM
9407 chan = nl80211_get_valid_chan(&rdev->wiphy,
9408 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
9409 if (!chan)
4c476991 9410 return -EINVAL;
636a5d36 9411
19957bb3
JB
9412 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9413 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
9414
9415 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
9416 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9417 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9418 }
9419
dc6382ce 9420 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 9421 enum nl80211_mfp mfp =
dc6382ce 9422 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 9423 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 9424 req.use_mfp = true;
4c476991
JB
9425 else if (mfp != NL80211_MFP_NO)
9426 return -EINVAL;
dc6382ce
JM
9427 }
9428
3e5d7649 9429 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 9430 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 9431
7e7c8926 9432 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 9433 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
9434
9435 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
9436 memcpy(&req.ht_capa_mask,
9437 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9438 sizeof(req.ht_capa_mask));
7e7c8926
BG
9439
9440 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 9441 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 9442 return -EINVAL;
f62fab73
JB
9443 memcpy(&req.ht_capa,
9444 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9445 sizeof(req.ht_capa));
7e7c8926
BG
9446 }
9447
ee2aca34 9448 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 9449 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
9450
9451 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
9452 memcpy(&req.vht_capa_mask,
9453 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
9454 sizeof(req.vht_capa_mask));
ee2aca34
JB
9455
9456 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 9457 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 9458 return -EINVAL;
f62fab73
JB
9459 memcpy(&req.vht_capa,
9460 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
9461 sizeof(req.vht_capa));
ee2aca34
JB
9462 }
9463
bab5ab7d 9464 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
9465 if (!((rdev->wiphy.features &
9466 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
9467 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
9468 !wiphy_ext_feature_isset(&rdev->wiphy,
9469 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
9470 return -EINVAL;
9471 req.flags |= ASSOC_REQ_USE_RRM;
9472 }
9473
348bd456
JM
9474 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
9475 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
9476 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
9477 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
9478 return -EINVAL;
9479 req.fils_nonces =
9480 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
9481 }
9482
f62fab73 9483 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
9484 if (!err) {
9485 wdev_lock(dev->ieee80211_ptr);
bd2522b1 9486
f62fab73
JB
9487 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
9488 ssid, ssid_len, &req);
bd2522b1
AZ
9489
9490 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9491 dev->ieee80211_ptr->conn_owner_nlportid =
9492 info->snd_portid;
9493 memcpy(dev->ieee80211_ptr->disconnect_bssid,
9494 bssid, ETH_ALEN);
9495 }
9496
91bf9b26
JB
9497 wdev_unlock(dev->ieee80211_ptr);
9498 }
636a5d36 9499
636a5d36
JM
9500 return err;
9501}
9502
9503static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
9504{
4c476991
JB
9505 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9506 struct net_device *dev = info->user_ptr[1];
19957bb3 9507 const u8 *ie = NULL, *bssid;
91bf9b26 9508 int ie_len = 0, err;
19957bb3 9509 u16 reason_code;
d5cdfacb 9510 bool local_state_change;
636a5d36 9511
bad29297
AZ
9512 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9513 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9514 return -EPERM;
9515
f4a11bb0
JB
9516 if (!info->attrs[NL80211_ATTR_MAC])
9517 return -EINVAL;
9518
9519 if (!info->attrs[NL80211_ATTR_REASON_CODE])
9520 return -EINVAL;
9521
4c476991
JB
9522 if (!rdev->ops->deauth)
9523 return -EOPNOTSUPP;
636a5d36 9524
074ac8df 9525 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9526 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9527 return -EOPNOTSUPP;
eec60b03 9528
19957bb3 9529 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 9530
19957bb3
JB
9531 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
9532 if (reason_code == 0) {
f4a11bb0 9533 /* Reason Code 0 is reserved */
4c476991 9534 return -EINVAL;
255e737e 9535 }
636a5d36
JM
9536
9537 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
9538 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9539 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9540 }
9541
d5cdfacb
JM
9542 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
9543
91bf9b26
JB
9544 wdev_lock(dev->ieee80211_ptr);
9545 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
9546 local_state_change);
9547 wdev_unlock(dev->ieee80211_ptr);
9548 return err;
636a5d36
JM
9549}
9550
9551static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
9552{
4c476991
JB
9553 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9554 struct net_device *dev = info->user_ptr[1];
19957bb3 9555 const u8 *ie = NULL, *bssid;
91bf9b26 9556 int ie_len = 0, err;
19957bb3 9557 u16 reason_code;
d5cdfacb 9558 bool local_state_change;
636a5d36 9559
bad29297
AZ
9560 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9561 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9562 return -EPERM;
9563
f4a11bb0
JB
9564 if (!info->attrs[NL80211_ATTR_MAC])
9565 return -EINVAL;
9566
9567 if (!info->attrs[NL80211_ATTR_REASON_CODE])
9568 return -EINVAL;
9569
4c476991
JB
9570 if (!rdev->ops->disassoc)
9571 return -EOPNOTSUPP;
636a5d36 9572
074ac8df 9573 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9574 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9575 return -EOPNOTSUPP;
eec60b03 9576
19957bb3 9577 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 9578
19957bb3
JB
9579 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
9580 if (reason_code == 0) {
f4a11bb0 9581 /* Reason Code 0 is reserved */
4c476991 9582 return -EINVAL;
255e737e 9583 }
636a5d36
JM
9584
9585 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
9586 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9587 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9588 }
9589
d5cdfacb
JM
9590 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
9591
91bf9b26
JB
9592 wdev_lock(dev->ieee80211_ptr);
9593 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
9594 local_state_change);
9595 wdev_unlock(dev->ieee80211_ptr);
9596 return err;
636a5d36
JM
9597}
9598
dd5b4cc7
FF
9599static bool
9600nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 9601 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
9602 int rateval)
9603{
9604 struct wiphy *wiphy = &rdev->wiphy;
9605 bool found = false;
9606 int band, i;
9607
57fbcce3 9608 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
9609 struct ieee80211_supported_band *sband;
9610
9611 sband = wiphy->bands[band];
9612 if (!sband)
9613 continue;
9614
9615 for (i = 0; i < sband->n_bitrates; i++) {
9616 if (sband->bitrates[i].bitrate == rateval) {
9617 mcast_rate[band] = i + 1;
9618 found = true;
9619 break;
9620 }
9621 }
9622 }
9623
9624 return found;
9625}
9626
04a773ad
JB
9627static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
9628{
4c476991
JB
9629 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9630 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
9631 struct cfg80211_ibss_params ibss;
9632 struct wiphy *wiphy;
fffd0934 9633 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
9634 int err;
9635
8e30bc55
JB
9636 memset(&ibss, 0, sizeof(ibss));
9637
683b6d3b 9638 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
9639 !nla_len(info->attrs[NL80211_ATTR_SSID]))
9640 return -EINVAL;
9641
8e30bc55
JB
9642 ibss.beacon_interval = 100;
9643
12d20fc9 9644 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
9645 ibss.beacon_interval =
9646 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 9647
0c317a02
PK
9648 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
9649 ibss.beacon_interval);
12d20fc9
PK
9650 if (err)
9651 return err;
8e30bc55 9652
4c476991
JB
9653 if (!rdev->ops->join_ibss)
9654 return -EOPNOTSUPP;
04a773ad 9655
4c476991
JB
9656 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
9657 return -EOPNOTSUPP;
04a773ad 9658
79c97e97 9659 wiphy = &rdev->wiphy;
04a773ad 9660
39193498 9661 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 9662 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
9663
9664 if (!is_valid_ether_addr(ibss.bssid))
9665 return -EINVAL;
9666 }
04a773ad
JB
9667 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9668 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
9669
9670 if (info->attrs[NL80211_ATTR_IE]) {
9671 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9672 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9673 }
9674
683b6d3b
JB
9675 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
9676 if (err)
9677 return err;
04a773ad 9678
174e0cd2
IP
9679 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
9680 NL80211_IFTYPE_ADHOC))
54858ee5
AS
9681 return -EINVAL;
9682
2f301ab2 9683 switch (ibss.chandef.width) {
bf372645
SW
9684 case NL80211_CHAN_WIDTH_5:
9685 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
9686 case NL80211_CHAN_WIDTH_20_NOHT:
9687 break;
9688 case NL80211_CHAN_WIDTH_20:
9689 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
9690 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
9691 return -EINVAL;
9692 break;
9693 case NL80211_CHAN_WIDTH_80:
9694 case NL80211_CHAN_WIDTH_80P80:
9695 case NL80211_CHAN_WIDTH_160:
9696 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
9697 return -EINVAL;
9698 if (!wiphy_ext_feature_isset(&rdev->wiphy,
9699 NL80211_EXT_FEATURE_VHT_IBSS))
9700 return -EINVAL;
9701 break;
2f301ab2 9702 default:
c04d6150 9703 return -EINVAL;
2f301ab2 9704 }
db9c64cf 9705
04a773ad 9706 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
9707 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
9708
fbd2c8dc
TP
9709 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
9710 u8 *rates =
9711 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9712 int n_rates =
9713 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9714 struct ieee80211_supported_band *sband =
683b6d3b 9715 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 9716
34850ab2
JB
9717 err = ieee80211_get_ratemask(sband, rates, n_rates,
9718 &ibss.basic_rates);
9719 if (err)
9720 return err;
fbd2c8dc 9721 }
dd5b4cc7 9722
803768f5
SW
9723 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9724 memcpy(&ibss.ht_capa_mask,
9725 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9726 sizeof(ibss.ht_capa_mask));
9727
9728 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
9729 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9730 return -EINVAL;
9731 memcpy(&ibss.ht_capa,
9732 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9733 sizeof(ibss.ht_capa));
9734 }
9735
dd5b4cc7
FF
9736 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
9737 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
9738 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
9739 return -EINVAL;
fbd2c8dc 9740
4c476991 9741 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
9742 bool no_ht = false;
9743
768075eb 9744 connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
4c476991
JB
9745 if (IS_ERR(connkeys))
9746 return PTR_ERR(connkeys);
de7044ee 9747
3d9d1d66
JB
9748 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
9749 no_ht) {
5e950a78 9750 kzfree(connkeys);
de7044ee
SM
9751 return -EINVAL;
9752 }
4c476991 9753 }
04a773ad 9754
267335d6
AQ
9755 ibss.control_port =
9756 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
9757
c3bfe1f6
DK
9758 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
9759 int r = validate_pae_over_nl80211(rdev, info);
9760
d350a0f4
JB
9761 if (r < 0) {
9762 kzfree(connkeys);
c3bfe1f6 9763 return r;
d350a0f4 9764 }
c3bfe1f6
DK
9765
9766 ibss.control_port_over_nl80211 = true;
9767 }
9768
5336fa88
SW
9769 ibss.userspace_handles_dfs =
9770 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
9771
f8d16d3e
DK
9772 wdev_lock(dev->ieee80211_ptr);
9773 err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 9774 if (err)
b47f610b 9775 kzfree(connkeys);
f8d16d3e
DK
9776 else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
9777 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
9778 wdev_unlock(dev->ieee80211_ptr);
9779
04a773ad
JB
9780 return err;
9781}
9782
9783static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
9784{
4c476991
JB
9785 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9786 struct net_device *dev = info->user_ptr[1];
04a773ad 9787
4c476991
JB
9788 if (!rdev->ops->leave_ibss)
9789 return -EOPNOTSUPP;
04a773ad 9790
4c476991
JB
9791 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
9792 return -EOPNOTSUPP;
04a773ad 9793
4c476991 9794 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
9795}
9796
f4e583c8
AQ
9797static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
9798{
9799 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9800 struct net_device *dev = info->user_ptr[1];
57fbcce3 9801 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
9802 u32 nla_rate;
9803 int err;
9804
9805 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
9806 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
9807 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
9808 return -EOPNOTSUPP;
9809
9810 if (!rdev->ops->set_mcast_rate)
9811 return -EOPNOTSUPP;
9812
9813 memset(mcast_rate, 0, sizeof(mcast_rate));
9814
9815 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
9816 return -EINVAL;
9817
9818 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
9819 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
9820 return -EINVAL;
9821
a1056b1b 9822 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
9823
9824 return err;
9825}
9826
ad7e718c
JB
9827static struct sk_buff *
9828__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
9829 struct wireless_dev *wdev, int approxlen,
9830 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
9831 enum nl80211_attrs attr,
9832 const struct nl80211_vendor_cmd_info *info,
9833 gfp_t gfp)
ad7e718c
JB
9834{
9835 struct sk_buff *skb;
9836 void *hdr;
9837 struct nlattr *data;
9838
9839 skb = nlmsg_new(approxlen + 100, gfp);
9840 if (!skb)
9841 return NULL;
9842
9843 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
9844 if (!hdr) {
9845 kfree_skb(skb);
9846 return NULL;
9847 }
9848
9849 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
9850 goto nla_put_failure;
567ffc35
JB
9851
9852 if (info) {
9853 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
9854 info->vendor_id))
9855 goto nla_put_failure;
9856 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
9857 info->subcmd))
9858 goto nla_put_failure;
9859 }
9860
6c09e791 9861 if (wdev) {
2dad624e
ND
9862 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
9863 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
9864 goto nla_put_failure;
9865 if (wdev->netdev &&
9866 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
9867 wdev->netdev->ifindex))
9868 goto nla_put_failure;
9869 }
9870
ae0be8de 9871 data = nla_nest_start_noflag(skb, attr);
76e1fb4b
JB
9872 if (!data)
9873 goto nla_put_failure;
ad7e718c
JB
9874
9875 ((void **)skb->cb)[0] = rdev;
9876 ((void **)skb->cb)[1] = hdr;
9877 ((void **)skb->cb)[2] = data;
9878
9879 return skb;
9880
9881 nla_put_failure:
9882 kfree_skb(skb);
9883 return NULL;
9884}
f4e583c8 9885
e03ad6ea 9886struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 9887 struct wireless_dev *wdev,
e03ad6ea
JB
9888 enum nl80211_commands cmd,
9889 enum nl80211_attrs attr,
55c1fdf0 9890 unsigned int portid,
e03ad6ea
JB
9891 int vendor_event_idx,
9892 int approxlen, gfp_t gfp)
9893{
f26cbf40 9894 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
9895 const struct nl80211_vendor_cmd_info *info;
9896
9897 switch (cmd) {
9898 case NL80211_CMD_TESTMODE:
9899 if (WARN_ON(vendor_event_idx != -1))
9900 return NULL;
9901 info = NULL;
9902 break;
9903 case NL80211_CMD_VENDOR:
9904 if (WARN_ON(vendor_event_idx < 0 ||
9905 vendor_event_idx >= wiphy->n_vendor_events))
9906 return NULL;
9907 info = &wiphy->vendor_events[vendor_event_idx];
9908 break;
9909 default:
9910 WARN_ON(1);
9911 return NULL;
9912 }
9913
55c1fdf0 9914 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0,
e03ad6ea
JB
9915 cmd, attr, info, gfp);
9916}
9917EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
9918
9919void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
9920{
9921 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
9922 void *hdr = ((void **)skb->cb)[1];
55c1fdf0 9923 struct nlmsghdr *nlhdr = nlmsg_hdr(skb);
e03ad6ea
JB
9924 struct nlattr *data = ((void **)skb->cb)[2];
9925 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
9926
bd8c78e7
JB
9927 /* clear CB data for netlink core to own from now on */
9928 memset(skb->cb, 0, sizeof(skb->cb));
9929
e03ad6ea
JB
9930 nla_nest_end(skb, data);
9931 genlmsg_end(skb, hdr);
9932
55c1fdf0
JB
9933 if (nlhdr->nlmsg_pid) {
9934 genlmsg_unicast(wiphy_net(&rdev->wiphy), skb,
9935 nlhdr->nlmsg_pid);
9936 } else {
9937 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
9938 mcgrp = NL80211_MCGRP_VENDOR;
e03ad6ea 9939
55c1fdf0
JB
9940 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
9941 skb, 0, mcgrp, gfp);
9942 }
e03ad6ea
JB
9943}
9944EXPORT_SYMBOL(__cfg80211_send_event_skb);
9945
aff89a9b 9946#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
9947static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
9948{
4c476991 9949 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
9950 struct wireless_dev *wdev =
9951 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
9952 int err;
9953
fc73f11f
DS
9954 if (!rdev->ops->testmode_cmd)
9955 return -EOPNOTSUPP;
9956
9957 if (IS_ERR(wdev)) {
9958 err = PTR_ERR(wdev);
9959 if (err != -EINVAL)
9960 return err;
9961 wdev = NULL;
9962 } else if (wdev->wiphy != &rdev->wiphy) {
9963 return -EINVAL;
9964 }
9965
aff89a9b
JB
9966 if (!info->attrs[NL80211_ATTR_TESTDATA])
9967 return -EINVAL;
9968
ad7e718c 9969 rdev->cur_cmd_info = info;
fc73f11f 9970 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
9971 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
9972 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 9973 rdev->cur_cmd_info = NULL;
aff89a9b 9974
aff89a9b
JB
9975 return err;
9976}
9977
71063f0e
WYG
9978static int nl80211_testmode_dump(struct sk_buff *skb,
9979 struct netlink_callback *cb)
9980{
00918d33 9981 struct cfg80211_registered_device *rdev;
50508d94 9982 struct nlattr **attrbuf = NULL;
71063f0e
WYG
9983 int err;
9984 long phy_idx;
9985 void *data = NULL;
9986 int data_len = 0;
9987
5fe231e8
JB
9988 rtnl_lock();
9989
71063f0e
WYG
9990 if (cb->args[0]) {
9991 /*
9992 * 0 is a valid index, but not valid for args[0],
9993 * so we need to offset by 1.
9994 */
9995 phy_idx = cb->args[0] - 1;
a4956dca
LC
9996
9997 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
9998 if (!rdev) {
9999 err = -ENOENT;
10000 goto out_err;
10001 }
71063f0e 10002 } else {
50508d94
JB
10003 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
10004 GFP_KERNEL);
10005 if (!attrbuf) {
10006 err = -ENOMEM;
10007 goto out_err;
10008 }
c90c39da 10009
8cb08174
JB
10010 err = nlmsg_parse_deprecated(cb->nlh,
10011 GENL_HDRLEN + nl80211_fam.hdrsize,
10012 attrbuf, nl80211_fam.maxattr,
10013 nl80211_policy, NULL);
71063f0e 10014 if (err)
5fe231e8 10015 goto out_err;
00918d33 10016
c90c39da 10017 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 10018 if (IS_ERR(rdev)) {
5fe231e8
JB
10019 err = PTR_ERR(rdev);
10020 goto out_err;
00918d33 10021 }
2bd7e35d 10022 phy_idx = rdev->wiphy_idx;
2bd7e35d 10023
c90c39da
JB
10024 if (attrbuf[NL80211_ATTR_TESTDATA])
10025 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
10026 }
10027
10028 if (cb->args[1]) {
10029 data = nla_data((void *)cb->args[1]);
10030 data_len = nla_len((void *)cb->args[1]);
10031 }
10032
00918d33 10033 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
10034 err = -EOPNOTSUPP;
10035 goto out_err;
10036 }
10037
10038 while (1) {
15e47304 10039 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
10040 cb->nlh->nlmsg_seq, NLM_F_MULTI,
10041 NL80211_CMD_TESTMODE);
10042 struct nlattr *tmdata;
10043
cb35fba3
DC
10044 if (!hdr)
10045 break;
10046
9360ffd1 10047 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
10048 genlmsg_cancel(skb, hdr);
10049 break;
10050 }
10051
ae0be8de 10052 tmdata = nla_nest_start_noflag(skb, NL80211_ATTR_TESTDATA);
71063f0e
WYG
10053 if (!tmdata) {
10054 genlmsg_cancel(skb, hdr);
10055 break;
10056 }
e35e4d28 10057 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
10058 nla_nest_end(skb, tmdata);
10059
10060 if (err == -ENOBUFS || err == -ENOENT) {
10061 genlmsg_cancel(skb, hdr);
10062 break;
10063 } else if (err) {
10064 genlmsg_cancel(skb, hdr);
10065 goto out_err;
10066 }
10067
10068 genlmsg_end(skb, hdr);
10069 }
10070
10071 err = skb->len;
10072 /* see above */
10073 cb->args[0] = phy_idx + 1;
10074 out_err:
50508d94 10075 kfree(attrbuf);
5fe231e8 10076 rtnl_unlock();
71063f0e
WYG
10077 return err;
10078}
aff89a9b
JB
10079#endif
10080
b23aa676
SO
10081static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
10082{
4c476991
JB
10083 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10084 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
10085 struct cfg80211_connect_params connect;
10086 struct wiphy *wiphy;
fffd0934 10087 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
10088 int err;
10089
10090 memset(&connect, 0, sizeof(connect));
10091
b23aa676
SO
10092 if (!info->attrs[NL80211_ATTR_SSID] ||
10093 !nla_len(info->attrs[NL80211_ATTR_SSID]))
10094 return -EINVAL;
10095
10096 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
10097 connect.auth_type =
10098 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
10099 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
10100 NL80211_CMD_CONNECT))
b23aa676
SO
10101 return -EINVAL;
10102 } else
10103 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
10104
10105 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
10106
3a00df57
AS
10107 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
10108 !wiphy_ext_feature_isset(&rdev->wiphy,
10109 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
10110 return -EINVAL;
10111 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
10112
c0692b8f 10113 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 10114 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
10115 if (err)
10116 return err;
b23aa676 10117
074ac8df 10118 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10119 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10120 return -EOPNOTSUPP;
b23aa676 10121
79c97e97 10122 wiphy = &rdev->wiphy;
b23aa676 10123
4486ea98
BS
10124 connect.bg_scan_period = -1;
10125 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
10126 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
10127 connect.bg_scan_period =
10128 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
10129 }
10130
b23aa676
SO
10131 if (info->attrs[NL80211_ATTR_MAC])
10132 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
10133 else if (info->attrs[NL80211_ATTR_MAC_HINT])
10134 connect.bssid_hint =
10135 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
10136 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10137 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10138
10139 if (info->attrs[NL80211_ATTR_IE]) {
10140 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10141 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10142 }
10143
cee00a95
JM
10144 if (info->attrs[NL80211_ATTR_USE_MFP]) {
10145 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
65026002
EG
10146 if (connect.mfp == NL80211_MFP_OPTIONAL &&
10147 !wiphy_ext_feature_isset(&rdev->wiphy,
10148 NL80211_EXT_FEATURE_MFP_OPTIONAL))
10149 return -EOPNOTSUPP;
cee00a95
JM
10150 } else {
10151 connect.mfp = NL80211_MFP_NO;
10152 }
10153
ba6fbacf
JM
10154 if (info->attrs[NL80211_ATTR_PREV_BSSID])
10155 connect.prev_bssid =
10156 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
10157
b23aa676 10158 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
10159 connect.channel = nl80211_get_valid_chan(
10160 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
10161 if (!connect.channel)
1df4a510
JM
10162 return -EINVAL;
10163 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
10164 connect.channel_hint = nl80211_get_valid_chan(
10165 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
10166 if (!connect.channel_hint)
4c476991 10167 return -EINVAL;
b23aa676
SO
10168 }
10169
2a38075c
AAL
10170 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
10171 connect.edmg.channels =
10172 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
10173
10174 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
10175 connect.edmg.bw_config =
10176 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
10177 }
10178
fffd0934 10179 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
768075eb 10180 connkeys = nl80211_parse_connkeys(rdev, info, NULL);
4c476991
JB
10181 if (IS_ERR(connkeys))
10182 return PTR_ERR(connkeys);
fffd0934
JB
10183 }
10184
7e7c8926
BG
10185 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
10186 connect.flags |= ASSOC_REQ_DISABLE_HT;
10187
10188 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10189 memcpy(&connect.ht_capa_mask,
10190 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10191 sizeof(connect.ht_capa_mask));
10192
10193 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 10194 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
b47f610b 10195 kzfree(connkeys);
7e7c8926 10196 return -EINVAL;
b4e4f47e 10197 }
7e7c8926
BG
10198 memcpy(&connect.ht_capa,
10199 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10200 sizeof(connect.ht_capa));
10201 }
10202
ee2aca34
JB
10203 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
10204 connect.flags |= ASSOC_REQ_DISABLE_VHT;
10205
10206 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
10207 memcpy(&connect.vht_capa_mask,
10208 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
10209 sizeof(connect.vht_capa_mask));
10210
10211 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
10212 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
b47f610b 10213 kzfree(connkeys);
ee2aca34
JB
10214 return -EINVAL;
10215 }
10216 memcpy(&connect.vht_capa,
10217 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
10218 sizeof(connect.vht_capa));
10219 }
10220
bab5ab7d 10221 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
10222 if (!((rdev->wiphy.features &
10223 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
10224 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
10225 !wiphy_ext_feature_isset(&rdev->wiphy,
10226 NL80211_EXT_FEATURE_RRM)) {
707554b4 10227 kzfree(connkeys);
bab5ab7d 10228 return -EINVAL;
707554b4 10229 }
bab5ab7d
AK
10230 connect.flags |= ASSOC_REQ_USE_RRM;
10231 }
10232
34d50519 10233 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 10234 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
34d50519
LD
10235 kzfree(connkeys);
10236 return -EOPNOTSUPP;
10237 }
10238
38de03d2
AS
10239 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
10240 /* bss selection makes no sense if bssid is set */
10241 if (connect.bssid) {
10242 kzfree(connkeys);
10243 return -EINVAL;
10244 }
10245
10246 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
10247 wiphy, &connect.bss_select);
10248 if (err) {
10249 kzfree(connkeys);
10250 return err;
10251 }
10252 }
10253
a3caf744
VK
10254 if (wiphy_ext_feature_isset(&rdev->wiphy,
10255 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
10256 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
10257 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
10258 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
10259 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10260 connect.fils_erp_username =
10261 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10262 connect.fils_erp_username_len =
10263 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10264 connect.fils_erp_realm =
10265 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10266 connect.fils_erp_realm_len =
10267 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10268 connect.fils_erp_next_seq_num =
10269 nla_get_u16(
10270 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
10271 connect.fils_erp_rrk =
10272 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10273 connect.fils_erp_rrk_len =
10274 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10275 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
10276 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
10277 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
10278 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10279 kzfree(connkeys);
10280 return -EINVAL;
10281 }
10282
40cbfa90
SD
10283 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
10284 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
2f0605a6 10285 kzfree(connkeys);
40cbfa90
SD
10286 GENL_SET_ERR_MSG(info,
10287 "external auth requires connection ownership");
10288 return -EINVAL;
10289 }
10290 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
10291 }
10292
83739b03 10293 wdev_lock(dev->ieee80211_ptr);
bd2522b1 10294
4ce2bd9c
JM
10295 err = cfg80211_connect(rdev, dev, &connect, connkeys,
10296 connect.prev_bssid);
fffd0934 10297 if (err)
b47f610b 10298 kzfree(connkeys);
bd2522b1
AZ
10299
10300 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10301 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10302 if (connect.bssid)
10303 memcpy(dev->ieee80211_ptr->disconnect_bssid,
10304 connect.bssid, ETH_ALEN);
10305 else
10306 memset(dev->ieee80211_ptr->disconnect_bssid,
10307 0, ETH_ALEN);
10308 }
10309
10310 wdev_unlock(dev->ieee80211_ptr);
10311
b23aa676
SO
10312 return err;
10313}
10314
088e8df8 10315static int nl80211_update_connect_params(struct sk_buff *skb,
10316 struct genl_info *info)
10317{
10318 struct cfg80211_connect_params connect = {};
10319 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10320 struct net_device *dev = info->user_ptr[1];
10321 struct wireless_dev *wdev = dev->ieee80211_ptr;
7f9a3e15
VK
10322 bool fils_sk_offload;
10323 u32 auth_type;
088e8df8 10324 u32 changed = 0;
10325 int ret;
10326
10327 if (!rdev->ops->update_connect_params)
10328 return -EOPNOTSUPP;
10329
10330 if (info->attrs[NL80211_ATTR_IE]) {
088e8df8 10331 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10332 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10333 changed |= UPDATE_ASSOC_IES;
10334 }
10335
7f9a3e15
VK
10336 fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
10337 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
10338
10339 /*
10340 * when driver supports fils-sk offload all attributes must be
10341 * provided. So the else covers "fils-sk-not-all" and
10342 * "no-fils-sk-any".
10343 */
10344 if (fils_sk_offload &&
10345 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
10346 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
10347 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
10348 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10349 connect.fils_erp_username =
10350 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10351 connect.fils_erp_username_len =
10352 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10353 connect.fils_erp_realm =
10354 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10355 connect.fils_erp_realm_len =
10356 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10357 connect.fils_erp_next_seq_num =
10358 nla_get_u16(
10359 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
10360 connect.fils_erp_rrk =
10361 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10362 connect.fils_erp_rrk_len =
10363 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10364 changed |= UPDATE_FILS_ERP_INFO;
10365 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
10366 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
10367 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
10368 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10369 return -EINVAL;
10370 }
10371
10372 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
10373 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
10374 if (!nl80211_valid_auth_type(rdev, auth_type,
10375 NL80211_CMD_CONNECT))
10376 return -EINVAL;
10377
10378 if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
10379 fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
10380 return -EINVAL;
10381
10382 connect.auth_type = auth_type;
10383 changed |= UPDATE_AUTH_TYPE;
10384 }
10385
088e8df8 10386 wdev_lock(dev->ieee80211_ptr);
10387 if (!wdev->current_bss)
10388 ret = -ENOLINK;
10389 else
10390 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
10391 wdev_unlock(dev->ieee80211_ptr);
10392
10393 return ret;
10394}
10395
b23aa676
SO
10396static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
10397{
4c476991
JB
10398 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10399 struct net_device *dev = info->user_ptr[1];
b23aa676 10400 u16 reason;
83739b03 10401 int ret;
b23aa676 10402
bad29297
AZ
10403 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10404 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10405 return -EPERM;
10406
b23aa676
SO
10407 if (!info->attrs[NL80211_ATTR_REASON_CODE])
10408 reason = WLAN_REASON_DEAUTH_LEAVING;
10409 else
10410 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
10411
10412 if (reason == 0)
10413 return -EINVAL;
10414
074ac8df 10415 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10416 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10417 return -EOPNOTSUPP;
b23aa676 10418
83739b03
JB
10419 wdev_lock(dev->ieee80211_ptr);
10420 ret = cfg80211_disconnect(rdev, dev, reason, true);
10421 wdev_unlock(dev->ieee80211_ptr);
10422 return ret;
b23aa676
SO
10423}
10424
463d0183
JB
10425static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
10426{
4c476991 10427 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
10428 struct net *net;
10429 int err;
463d0183 10430
4b681c82
VK
10431 if (info->attrs[NL80211_ATTR_PID]) {
10432 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
10433
10434 net = get_net_ns_by_pid(pid);
10435 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
10436 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 10437
4b681c82
VK
10438 net = get_net_ns_by_fd(fd);
10439 } else {
10440 return -EINVAL;
10441 }
463d0183 10442
4c476991
JB
10443 if (IS_ERR(net))
10444 return PTR_ERR(net);
463d0183
JB
10445
10446 err = 0;
10447
10448 /* check if anything to do */
4c476991
JB
10449 if (!net_eq(wiphy_net(&rdev->wiphy), net))
10450 err = cfg80211_switch_netns(rdev, net);
463d0183 10451
463d0183 10452 put_net(net);
463d0183
JB
10453 return err;
10454}
10455
67fbb16b
SO
10456static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
10457{
4c476991 10458 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
10459 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
10460 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 10461 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
10462 struct cfg80211_pmksa pmksa;
10463
10464 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
10465
67fbb16b
SO
10466 if (!info->attrs[NL80211_ATTR_PMKID])
10467 return -EINVAL;
10468
67fbb16b 10469 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
a3caf744
VK
10470
10471 if (info->attrs[NL80211_ATTR_MAC]) {
10472 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
10473 } else if (info->attrs[NL80211_ATTR_SSID] &&
10474 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
10475 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
10476 info->attrs[NL80211_ATTR_PMK])) {
10477 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10478 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10479 pmksa.cache_id =
10480 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
10481 } else {
10482 return -EINVAL;
10483 }
10484 if (info->attrs[NL80211_ATTR_PMK]) {
10485 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
10486 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
10487 }
67fbb16b 10488
074ac8df 10489 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
6c900360
LD
10490 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
10491 !(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP &&
10492 wiphy_ext_feature_isset(&rdev->wiphy,
10493 NL80211_EXT_FEATURE_AP_PMKSA_CACHING)))
4c476991 10494 return -EOPNOTSUPP;
67fbb16b
SO
10495
10496 switch (info->genlhdr->cmd) {
10497 case NL80211_CMD_SET_PMKSA:
10498 rdev_ops = rdev->ops->set_pmksa;
10499 break;
10500 case NL80211_CMD_DEL_PMKSA:
10501 rdev_ops = rdev->ops->del_pmksa;
10502 break;
10503 default:
10504 WARN_ON(1);
10505 break;
10506 }
10507
4c476991
JB
10508 if (!rdev_ops)
10509 return -EOPNOTSUPP;
67fbb16b 10510
4c476991 10511 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
10512}
10513
10514static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
10515{
4c476991
JB
10516 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10517 struct net_device *dev = info->user_ptr[1];
67fbb16b 10518
074ac8df 10519 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10520 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10521 return -EOPNOTSUPP;
67fbb16b 10522
4c476991
JB
10523 if (!rdev->ops->flush_pmksa)
10524 return -EOPNOTSUPP;
67fbb16b 10525
e35e4d28 10526 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
10527}
10528
109086ce
AN
10529static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
10530{
10531 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10532 struct net_device *dev = info->user_ptr[1];
10533 u8 action_code, dialog_token;
df942e7b 10534 u32 peer_capability = 0;
109086ce
AN
10535 u16 status_code;
10536 u8 *peer;
31fa97c5 10537 bool initiator;
109086ce
AN
10538
10539 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
10540 !rdev->ops->tdls_mgmt)
10541 return -EOPNOTSUPP;
10542
10543 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
10544 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
10545 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
10546 !info->attrs[NL80211_ATTR_IE] ||
10547 !info->attrs[NL80211_ATTR_MAC])
10548 return -EINVAL;
10549
10550 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
10551 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
10552 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
10553 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 10554 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
10555 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
10556 peer_capability =
10557 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 10558
e35e4d28 10559 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 10560 dialog_token, status_code, peer_capability,
31fa97c5 10561 initiator,
e35e4d28
HG
10562 nla_data(info->attrs[NL80211_ATTR_IE]),
10563 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
10564}
10565
10566static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
10567{
10568 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10569 struct net_device *dev = info->user_ptr[1];
10570 enum nl80211_tdls_operation operation;
10571 u8 *peer;
10572
10573 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
10574 !rdev->ops->tdls_oper)
10575 return -EOPNOTSUPP;
10576
10577 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
10578 !info->attrs[NL80211_ATTR_MAC])
10579 return -EINVAL;
10580
10581 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
10582 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
10583
e35e4d28 10584 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
10585}
10586
9588bbd5
JM
10587static int nl80211_remain_on_channel(struct sk_buff *skb,
10588 struct genl_info *info)
10589{
4c476991 10590 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10591 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 10592 struct cfg80211_chan_def chandef;
34373d12 10593 const struct cfg80211_chan_def *compat_chandef;
9588bbd5
JM
10594 struct sk_buff *msg;
10595 void *hdr;
10596 u64 cookie;
683b6d3b 10597 u32 duration;
9588bbd5
JM
10598 int err;
10599
10600 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
10601 !info->attrs[NL80211_ATTR_DURATION])
10602 return -EINVAL;
10603
10604 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
10605
ebf348fc
JB
10606 if (!rdev->ops->remain_on_channel ||
10607 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
10608 return -EOPNOTSUPP;
10609
9588bbd5 10610 /*
ebf348fc
JB
10611 * We should be on that channel for at least a minimum amount of
10612 * time (10ms) but no longer than the driver supports.
9588bbd5 10613 */
ebf348fc 10614 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 10615 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
10616 return -EINVAL;
10617
683b6d3b
JB
10618 err = nl80211_parse_chandef(rdev, info, &chandef);
10619 if (err)
10620 return err;
9588bbd5 10621
34373d12
VT
10622 wdev_lock(wdev);
10623 if (!cfg80211_off_channel_oper_allowed(wdev) &&
10624 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
10625 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
10626 &chandef);
10627 if (compat_chandef != &chandef) {
10628 wdev_unlock(wdev);
10629 return -EBUSY;
10630 }
10631 }
10632 wdev_unlock(wdev);
10633
9588bbd5 10634 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
10635 if (!msg)
10636 return -ENOMEM;
9588bbd5 10637
15e47304 10638 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 10639 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
10640 if (!hdr) {
10641 err = -ENOBUFS;
9588bbd5
JM
10642 goto free_msg;
10643 }
10644
683b6d3b
JB
10645 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
10646 duration, &cookie);
9588bbd5
JM
10647
10648 if (err)
10649 goto free_msg;
10650
2dad624e
ND
10651 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10652 NL80211_ATTR_PAD))
9360ffd1 10653 goto nla_put_failure;
9588bbd5
JM
10654
10655 genlmsg_end(msg, hdr);
4c476991
JB
10656
10657 return genlmsg_reply(msg, info);
9588bbd5
JM
10658
10659 nla_put_failure:
10660 err = -ENOBUFS;
10661 free_msg:
10662 nlmsg_free(msg);
9588bbd5
JM
10663 return err;
10664}
10665
10666static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
10667 struct genl_info *info)
10668{
4c476991 10669 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10670 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 10671 u64 cookie;
9588bbd5
JM
10672
10673 if (!info->attrs[NL80211_ATTR_COOKIE])
10674 return -EINVAL;
10675
4c476991
JB
10676 if (!rdev->ops->cancel_remain_on_channel)
10677 return -EOPNOTSUPP;
9588bbd5 10678
9588bbd5
JM
10679 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10680
e35e4d28 10681 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
10682}
10683
13ae75b1
JM
10684static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
10685 struct genl_info *info)
10686{
13ae75b1 10687 struct cfg80211_bitrate_mask mask;
a7c7fbff 10688 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 10689 struct net_device *dev = info->user_ptr[1];
a7c7fbff 10690 int err;
13ae75b1 10691
4c476991
JB
10692 if (!rdev->ops->set_bitrate_mask)
10693 return -EOPNOTSUPP;
13ae75b1 10694
a7c7fbff
PK
10695 err = nl80211_parse_tx_bitrate_mask(info, &mask);
10696 if (err)
10697 return err;
13ae75b1 10698
e35e4d28 10699 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
10700}
10701
2e161f78 10702static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 10703{
4c476991 10704 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10705 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 10706 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
10707
10708 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
10709 return -EINVAL;
10710
2e161f78
JB
10711 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
10712 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 10713
71bbc994
JB
10714 switch (wdev->iftype) {
10715 case NL80211_IFTYPE_STATION:
10716 case NL80211_IFTYPE_ADHOC:
10717 case NL80211_IFTYPE_P2P_CLIENT:
10718 case NL80211_IFTYPE_AP:
10719 case NL80211_IFTYPE_AP_VLAN:
10720 case NL80211_IFTYPE_MESH_POINT:
10721 case NL80211_IFTYPE_P2P_GO:
98104fde 10722 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 10723 break;
cb3b7d87 10724 case NL80211_IFTYPE_NAN:
71bbc994 10725 default:
4c476991 10726 return -EOPNOTSUPP;
71bbc994 10727 }
026331c4
JM
10728
10729 /* not much point in registering if we can't reply */
4c476991
JB
10730 if (!rdev->ops->mgmt_tx)
10731 return -EOPNOTSUPP;
026331c4 10732
15e47304 10733 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
ff74c51e
IP
10734 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
10735 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]),
10736 info->extack);
026331c4
JM
10737}
10738
2e161f78 10739static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 10740{
4c476991 10741 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10742 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 10743 struct cfg80211_chan_def chandef;
026331c4 10744 int err;
d64d373f 10745 void *hdr = NULL;
026331c4 10746 u64 cookie;
e247bd90 10747 struct sk_buff *msg = NULL;
b176e629
AO
10748 struct cfg80211_mgmt_tx_params params = {
10749 .dont_wait_for_ack =
10750 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
10751 };
026331c4 10752
683b6d3b 10753 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
10754 return -EINVAL;
10755
4c476991
JB
10756 if (!rdev->ops->mgmt_tx)
10757 return -EOPNOTSUPP;
026331c4 10758
71bbc994 10759 switch (wdev->iftype) {
ea141b75
AQ
10760 case NL80211_IFTYPE_P2P_DEVICE:
10761 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
10762 return -EINVAL;
71bbc994
JB
10763 case NL80211_IFTYPE_STATION:
10764 case NL80211_IFTYPE_ADHOC:
10765 case NL80211_IFTYPE_P2P_CLIENT:
10766 case NL80211_IFTYPE_AP:
10767 case NL80211_IFTYPE_AP_VLAN:
10768 case NL80211_IFTYPE_MESH_POINT:
10769 case NL80211_IFTYPE_P2P_GO:
10770 break;
cb3b7d87 10771 case NL80211_IFTYPE_NAN:
71bbc994 10772 default:
4c476991 10773 return -EOPNOTSUPP;
71bbc994 10774 }
026331c4 10775
f7ca38df 10776 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 10777 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 10778 return -EINVAL;
b176e629 10779 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
10780
10781 /*
10782 * We should wait on the channel for at least a minimum amount
10783 * of time (10ms) but no longer than the driver supports.
10784 */
b176e629
AO
10785 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
10786 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 10787 return -EINVAL;
f7ca38df
JB
10788 }
10789
b176e629 10790 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 10791
b176e629 10792 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
10793 return -EINVAL;
10794
b176e629 10795 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 10796
ea141b75
AQ
10797 /* get the channel if any has been specified, otherwise pass NULL to
10798 * the driver. The latter will use the current one
10799 */
10800 chandef.chan = NULL;
10801 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
10802 err = nl80211_parse_chandef(rdev, info, &chandef);
10803 if (err)
10804 return err;
10805 }
10806
b176e629 10807 if (!chandef.chan && params.offchan)
ea141b75 10808 return -EINVAL;
026331c4 10809
34373d12
VT
10810 wdev_lock(wdev);
10811 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
10812 wdev_unlock(wdev);
10813 return -EBUSY;
10814 }
10815 wdev_unlock(wdev);
10816
34d22ce2
AO
10817 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
10818 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
10819
10820 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
10821 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
10822 int i;
10823
10824 if (len % sizeof(u16))
10825 return -EINVAL;
10826
10827 params.n_csa_offsets = len / sizeof(u16);
10828 params.csa_offsets =
10829 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
10830
10831 /* check that all the offsets fit the frame */
10832 for (i = 0; i < params.n_csa_offsets; i++) {
10833 if (params.csa_offsets[i] >= params.len)
10834 return -EINVAL;
10835 }
10836 }
10837
b176e629 10838 if (!params.dont_wait_for_ack) {
e247bd90
JB
10839 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10840 if (!msg)
10841 return -ENOMEM;
026331c4 10842
15e47304 10843 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 10844 NL80211_CMD_FRAME);
cb35fba3
DC
10845 if (!hdr) {
10846 err = -ENOBUFS;
e247bd90
JB
10847 goto free_msg;
10848 }
026331c4 10849 }
e247bd90 10850
b176e629
AO
10851 params.chan = chandef.chan;
10852 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
10853 if (err)
10854 goto free_msg;
10855
e247bd90 10856 if (msg) {
2dad624e
ND
10857 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10858 NL80211_ATTR_PAD))
9360ffd1 10859 goto nla_put_failure;
026331c4 10860
e247bd90
JB
10861 genlmsg_end(msg, hdr);
10862 return genlmsg_reply(msg, info);
10863 }
10864
10865 return 0;
026331c4
JM
10866
10867 nla_put_failure:
10868 err = -ENOBUFS;
10869 free_msg:
10870 nlmsg_free(msg);
026331c4
JM
10871 return err;
10872}
10873
f7ca38df
JB
10874static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
10875{
10876 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10877 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
10878 u64 cookie;
10879
10880 if (!info->attrs[NL80211_ATTR_COOKIE])
10881 return -EINVAL;
10882
10883 if (!rdev->ops->mgmt_tx_cancel_wait)
10884 return -EOPNOTSUPP;
10885
71bbc994
JB
10886 switch (wdev->iftype) {
10887 case NL80211_IFTYPE_STATION:
10888 case NL80211_IFTYPE_ADHOC:
10889 case NL80211_IFTYPE_P2P_CLIENT:
10890 case NL80211_IFTYPE_AP:
10891 case NL80211_IFTYPE_AP_VLAN:
10892 case NL80211_IFTYPE_P2P_GO:
98104fde 10893 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 10894 break;
cb3b7d87 10895 case NL80211_IFTYPE_NAN:
71bbc994 10896 default:
f7ca38df 10897 return -EOPNOTSUPP;
71bbc994 10898 }
f7ca38df
JB
10899
10900 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10901
e35e4d28 10902 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
10903}
10904
ffb9eb3d
KV
10905static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
10906{
4c476991 10907 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 10908 struct wireless_dev *wdev;
4c476991 10909 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
10910 u8 ps_state;
10911 bool state;
10912 int err;
10913
4c476991
JB
10914 if (!info->attrs[NL80211_ATTR_PS_STATE])
10915 return -EINVAL;
ffb9eb3d
KV
10916
10917 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
10918
ffb9eb3d
KV
10919 wdev = dev->ieee80211_ptr;
10920
4c476991
JB
10921 if (!rdev->ops->set_power_mgmt)
10922 return -EOPNOTSUPP;
ffb9eb3d
KV
10923
10924 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
10925
10926 if (state == wdev->ps)
4c476991 10927 return 0;
ffb9eb3d 10928
e35e4d28 10929 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
10930 if (!err)
10931 wdev->ps = state;
ffb9eb3d
KV
10932 return err;
10933}
10934
10935static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
10936{
4c476991 10937 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
10938 enum nl80211_ps_state ps_state;
10939 struct wireless_dev *wdev;
4c476991 10940 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
10941 struct sk_buff *msg;
10942 void *hdr;
10943 int err;
10944
ffb9eb3d
KV
10945 wdev = dev->ieee80211_ptr;
10946
4c476991
JB
10947 if (!rdev->ops->set_power_mgmt)
10948 return -EOPNOTSUPP;
ffb9eb3d
KV
10949
10950 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
10951 if (!msg)
10952 return -ENOMEM;
ffb9eb3d 10953
15e47304 10954 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
10955 NL80211_CMD_GET_POWER_SAVE);
10956 if (!hdr) {
4c476991 10957 err = -ENOBUFS;
ffb9eb3d
KV
10958 goto free_msg;
10959 }
10960
10961 if (wdev->ps)
10962 ps_state = NL80211_PS_ENABLED;
10963 else
10964 ps_state = NL80211_PS_DISABLED;
10965
9360ffd1
DM
10966 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
10967 goto nla_put_failure;
ffb9eb3d
KV
10968
10969 genlmsg_end(msg, hdr);
4c476991 10970 return genlmsg_reply(msg, info);
ffb9eb3d 10971
4c476991 10972 nla_put_failure:
ffb9eb3d 10973 err = -ENOBUFS;
4c476991 10974 free_msg:
ffb9eb3d 10975 nlmsg_free(msg);
ffb9eb3d
KV
10976 return err;
10977}
10978
94e860f1
JB
10979static const struct nla_policy
10980nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
4a4b8169 10981 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
d6dc1a38
JO
10982 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
10983 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
10984 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
10985 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
10986 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
bee427b8 10987 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
d6dc1a38
JO
10988};
10989
84f10708 10990static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 10991 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
10992{
10993 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 10994 struct net_device *dev = info->user_ptr[1];
1da5fcc8 10995 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 10996
d9d8b019 10997 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
10998 return -EINVAL;
10999
84f10708
TP
11000 if (!rdev->ops->set_cqm_txe_config)
11001 return -EOPNOTSUPP;
11002
11003 if (wdev->iftype != NL80211_IFTYPE_STATION &&
11004 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
11005 return -EOPNOTSUPP;
11006
e35e4d28 11007 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
11008}
11009
4a4b8169
AZ
11010static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
11011 struct net_device *dev)
11012{
11013 struct wireless_dev *wdev = dev->ieee80211_ptr;
11014 s32 last, low, high;
11015 u32 hyst;
1222a160 11016 int i, n, low_index;
4a4b8169
AZ
11017 int err;
11018
11019 /* RSSI reporting disabled? */
11020 if (!wdev->cqm_config)
11021 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
11022
11023 /*
11024 * Obtain current RSSI value if possible, if not and no RSSI threshold
11025 * event has been received yet, we should receive an event after a
11026 * connection is established and enough beacons received to calculate
11027 * the average.
11028 */
11029 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
11030 rdev->ops->get_station) {
73887fd9 11031 struct station_info sinfo = {};
4a4b8169
AZ
11032 u8 *mac_addr;
11033
11034 mac_addr = wdev->current_bss->pub.bssid;
11035
73887fd9
JB
11036 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
11037 if (err)
4a4b8169
AZ
11038 return err;
11039
df16737d 11040 cfg80211_sinfo_release_content(&sinfo);
397c657a 11041 if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
4a4b8169 11042 wdev->cqm_config->last_rssi_event_value =
73887fd9 11043 (s8) sinfo.rx_beacon_signal_avg;
4a4b8169
AZ
11044 }
11045
11046 last = wdev->cqm_config->last_rssi_event_value;
11047 hyst = wdev->cqm_config->rssi_hyst;
11048 n = wdev->cqm_config->n_rssi_thresholds;
11049
4b2c5a14
MH
11050 for (i = 0; i < n; i++) {
11051 i = array_index_nospec(i, n);
4a4b8169
AZ
11052 if (last < wdev->cqm_config->rssi_thresholds[i])
11053 break;
4b2c5a14 11054 }
4a4b8169 11055
1222a160
MH
11056 low_index = i - 1;
11057 if (low_index >= 0) {
11058 low_index = array_index_nospec(low_index, n);
11059 low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
11060 } else {
11061 low = S32_MIN;
11062 }
11063 if (i < n) {
11064 i = array_index_nospec(i, n);
11065 high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
11066 } else {
11067 high = S32_MAX;
11068 }
4a4b8169
AZ
11069
11070 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
11071}
11072
d6dc1a38 11073static int nl80211_set_cqm_rssi(struct genl_info *info,
4a4b8169
AZ
11074 const s32 *thresholds, int n_thresholds,
11075 u32 hysteresis)
d6dc1a38 11076{
4c476991 11077 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 11078 struct net_device *dev = info->user_ptr[1];
1da5fcc8 11079 struct wireless_dev *wdev = dev->ieee80211_ptr;
4a4b8169
AZ
11080 int i, err;
11081 s32 prev = S32_MIN;
d6dc1a38 11082
4a4b8169
AZ
11083 /* Check all values negative and sorted */
11084 for (i = 0; i < n_thresholds; i++) {
11085 if (thresholds[i] > 0 || thresholds[i] <= prev)
11086 return -EINVAL;
d6dc1a38 11087
4a4b8169
AZ
11088 prev = thresholds[i];
11089 }
d6dc1a38 11090
074ac8df 11091 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11092 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
11093 return -EOPNOTSUPP;
d6dc1a38 11094
4a4b8169
AZ
11095 wdev_lock(wdev);
11096 cfg80211_cqm_config_free(wdev);
11097 wdev_unlock(wdev);
11098
11099 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
11100 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
11101 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
11102
11103 return rdev_set_cqm_rssi_config(rdev, dev,
11104 thresholds[0], hysteresis);
11105 }
11106
11107 if (!wiphy_ext_feature_isset(&rdev->wiphy,
11108 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
11109 return -EOPNOTSUPP;
11110
11111 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
11112 n_thresholds = 0;
11113
11114 wdev_lock(wdev);
11115 if (n_thresholds) {
11116 struct cfg80211_cqm_config *cqm_config;
11117
11118 cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
11119 n_thresholds * sizeof(s32), GFP_KERNEL);
11120 if (!cqm_config) {
11121 err = -ENOMEM;
11122 goto unlock;
11123 }
11124
11125 cqm_config->rssi_hyst = hysteresis;
11126 cqm_config->n_rssi_thresholds = n_thresholds;
11127 memcpy(cqm_config->rssi_thresholds, thresholds,
11128 n_thresholds * sizeof(s32));
11129
11130 wdev->cqm_config = cqm_config;
11131 }
11132
11133 err = cfg80211_cqm_rssi_update(rdev, dev);
11134
11135unlock:
11136 wdev_unlock(wdev);
11137
11138 return err;
d6dc1a38
JO
11139}
11140
11141static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
11142{
11143 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
11144 struct nlattr *cqm;
11145 int err;
11146
11147 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
11148 if (!cqm)
11149 return -EINVAL;
d6dc1a38 11150
8cb08174
JB
11151 err = nla_parse_nested_deprecated(attrs, NL80211_ATTR_CQM_MAX, cqm,
11152 nl80211_attr_cqm_policy,
11153 info->extack);
d6dc1a38 11154 if (err)
1da5fcc8 11155 return err;
d6dc1a38
JO
11156
11157 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
11158 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4a4b8169
AZ
11159 const s32 *thresholds =
11160 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
11161 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
1da5fcc8 11162 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 11163
4a4b8169
AZ
11164 if (len % 4)
11165 return -EINVAL;
11166
11167 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
11168 hysteresis);
1da5fcc8
JB
11169 }
11170
11171 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
11172 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
11173 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
11174 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
11175 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
11176 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
11177
11178 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
11179 }
11180
11181 return -EINVAL;
d6dc1a38
JO
11182}
11183
6e0bd6c3
RL
11184static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
11185{
11186 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11187 struct net_device *dev = info->user_ptr[1];
11188 struct ocb_setup setup = {};
11189 int err;
11190
11191 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
11192 if (err)
11193 return err;
11194
11195 return cfg80211_join_ocb(rdev, dev, &setup);
11196}
11197
11198static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
11199{
11200 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11201 struct net_device *dev = info->user_ptr[1];
11202
11203 return cfg80211_leave_ocb(rdev, dev);
11204}
11205
29cbe68c
JB
11206static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
11207{
11208 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11209 struct net_device *dev = info->user_ptr[1];
11210 struct mesh_config cfg;
c80d545d 11211 struct mesh_setup setup;
29cbe68c
JB
11212 int err;
11213
11214 /* start with default */
11215 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 11216 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 11217
24bdd9f4 11218 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 11219 /* and parse parameters if given */
24bdd9f4 11220 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
11221 if (err)
11222 return err;
11223 }
11224
11225 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
11226 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
11227 return -EINVAL;
11228
c80d545d
JC
11229 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
11230 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
11231
4bb62344
CYY
11232 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
11233 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
11234 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
11235 return -EINVAL;
11236
9bdbf04d
MP
11237 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
11238 setup.beacon_interval =
11239 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 11240
0c317a02
PK
11241 err = cfg80211_validate_beacon_int(rdev,
11242 NL80211_IFTYPE_MESH_POINT,
11243 setup.beacon_interval);
12d20fc9
PK
11244 if (err)
11245 return err;
9bdbf04d
MP
11246 }
11247
11248 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
11249 setup.dtim_period =
11250 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
11251 if (setup.dtim_period < 1 || setup.dtim_period > 100)
11252 return -EINVAL;
11253 }
11254
c80d545d
JC
11255 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
11256 /* parse additional setup parameters if given */
11257 err = nl80211_parse_mesh_setup(info, &setup);
11258 if (err)
11259 return err;
11260 }
11261
d37bb18a
TP
11262 if (setup.user_mpm)
11263 cfg.auto_open_plinks = false;
11264
cc1d2806 11265 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
11266 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
11267 if (err)
11268 return err;
cc1d2806 11269 } else {
188c1b3c 11270 /* __cfg80211_join_mesh() will sort it out */
683b6d3b 11271 setup.chandef.chan = NULL;
cc1d2806
JB
11272 }
11273
ffb3cf30
AN
11274 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
11275 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11276 int n_rates =
11277 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11278 struct ieee80211_supported_band *sband;
11279
11280 if (!setup.chandef.chan)
11281 return -EINVAL;
11282
11283 sband = rdev->wiphy.bands[setup.chandef.chan->band];
11284
11285 err = ieee80211_get_ratemask(sband, rates, n_rates,
11286 &setup.basic_rates);
11287 if (err)
11288 return err;
11289 }
11290
8564e382
JB
11291 if (info->attrs[NL80211_ATTR_TX_RATES]) {
11292 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
11293 if (err)
11294 return err;
11295
265698d7
JB
11296 if (!setup.chandef.chan)
11297 return -EINVAL;
11298
8564e382
JB
11299 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
11300 &setup.beacon_rate);
11301 if (err)
11302 return err;
11303 }
11304
d37d49c2
BB
11305 setup.userspace_handles_dfs =
11306 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
11307
1224f583
DK
11308 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
11309 int r = validate_pae_over_nl80211(rdev, info);
11310
11311 if (r < 0)
11312 return r;
11313
11314 setup.control_port_over_nl80211 = true;
11315 }
11316
188c1b3c
DK
11317 wdev_lock(dev->ieee80211_ptr);
11318 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
11319 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
11320 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
11321 wdev_unlock(dev->ieee80211_ptr);
11322
11323 return err;
29cbe68c
JB
11324}
11325
11326static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
11327{
11328 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11329 struct net_device *dev = info->user_ptr[1];
11330
11331 return cfg80211_leave_mesh(rdev, dev);
11332}
11333
dfb89c56 11334#ifdef CONFIG_PM
bb92d199
AK
11335static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
11336 struct cfg80211_registered_device *rdev)
11337{
6abb9cb9 11338 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
11339 struct nlattr *nl_pats, *nl_pat;
11340 int i, pat_len;
11341
6abb9cb9 11342 if (!wowlan->n_patterns)
bb92d199
AK
11343 return 0;
11344
ae0be8de 11345 nl_pats = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
bb92d199
AK
11346 if (!nl_pats)
11347 return -ENOBUFS;
11348
6abb9cb9 11349 for (i = 0; i < wowlan->n_patterns; i++) {
ae0be8de 11350 nl_pat = nla_nest_start_noflag(msg, i + 1);
bb92d199
AK
11351 if (!nl_pat)
11352 return -ENOBUFS;
6abb9cb9 11353 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 11354 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 11355 wowlan->patterns[i].mask) ||
50ac6607
AK
11356 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
11357 wowlan->patterns[i].pattern) ||
11358 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 11359 wowlan->patterns[i].pkt_offset))
bb92d199
AK
11360 return -ENOBUFS;
11361 nla_nest_end(msg, nl_pat);
11362 }
11363 nla_nest_end(msg, nl_pats);
11364
11365 return 0;
11366}
11367
2a0e047e
JB
11368static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
11369 struct cfg80211_wowlan_tcp *tcp)
11370{
11371 struct nlattr *nl_tcp;
11372
11373 if (!tcp)
11374 return 0;
11375
ae0be8de
MK
11376 nl_tcp = nla_nest_start_noflag(msg,
11377 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
2a0e047e
JB
11378 if (!nl_tcp)
11379 return -ENOBUFS;
11380
930345ea
JB
11381 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
11382 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
11383 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
11384 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
11385 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
11386 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
11387 tcp->payload_len, tcp->payload) ||
11388 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
11389 tcp->data_interval) ||
11390 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
11391 tcp->wake_len, tcp->wake_data) ||
11392 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
11393 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
11394 return -ENOBUFS;
11395
11396 if (tcp->payload_seq.len &&
11397 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
11398 sizeof(tcp->payload_seq), &tcp->payload_seq))
11399 return -ENOBUFS;
11400
11401 if (tcp->payload_tok.len &&
11402 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
11403 sizeof(tcp->payload_tok) + tcp->tokens_size,
11404 &tcp->payload_tok))
11405 return -ENOBUFS;
11406
e248ad30
JB
11407 nla_nest_end(msg, nl_tcp);
11408
2a0e047e
JB
11409 return 0;
11410}
11411
75453ccb
LC
11412static int nl80211_send_wowlan_nd(struct sk_buff *msg,
11413 struct cfg80211_sched_scan_request *req)
11414{
3b06d277 11415 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
11416 int i;
11417
11418 if (!req)
11419 return 0;
11420
ae0be8de 11421 nd = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
75453ccb
LC
11422 if (!nd)
11423 return -ENOBUFS;
11424
3b06d277
AS
11425 if (req->n_scan_plans == 1 &&
11426 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
11427 req->scan_plans[0].interval * 1000))
75453ccb
LC
11428 return -ENOBUFS;
11429
21fea567
LC
11430 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
11431 return -ENOBUFS;
11432
bf95ecdb 11433 if (req->relative_rssi_set) {
11434 struct nl80211_bss_select_rssi_adjust rssi_adjust;
11435
11436 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
11437 req->relative_rssi))
11438 return -ENOBUFS;
11439
11440 rssi_adjust.band = req->rssi_adjust.band;
11441 rssi_adjust.delta = req->rssi_adjust.delta;
11442 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
11443 sizeof(rssi_adjust), &rssi_adjust))
11444 return -ENOBUFS;
11445 }
11446
ae0be8de 11447 freqs = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
75453ccb
LC
11448 if (!freqs)
11449 return -ENOBUFS;
11450
53b18980
JB
11451 for (i = 0; i < req->n_channels; i++) {
11452 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
11453 return -ENOBUFS;
11454 }
75453ccb
LC
11455
11456 nla_nest_end(msg, freqs);
11457
11458 if (req->n_match_sets) {
ae0be8de
MK
11459 matches = nla_nest_start_noflag(msg,
11460 NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
11461 if (!matches)
11462 return -ENOBUFS;
11463
75453ccb 11464 for (i = 0; i < req->n_match_sets; i++) {
ae0be8de 11465 match = nla_nest_start_noflag(msg, i);
76e1fb4b
JB
11466 if (!match)
11467 return -ENOBUFS;
11468
53b18980
JB
11469 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
11470 req->match_sets[i].ssid.ssid_len,
11471 req->match_sets[i].ssid.ssid))
11472 return -ENOBUFS;
75453ccb
LC
11473 nla_nest_end(msg, match);
11474 }
11475 nla_nest_end(msg, matches);
11476 }
11477
ae0be8de 11478 scan_plans = nla_nest_start_noflag(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
3b06d277
AS
11479 if (!scan_plans)
11480 return -ENOBUFS;
11481
11482 for (i = 0; i < req->n_scan_plans; i++) {
ae0be8de 11483 scan_plan = nla_nest_start_noflag(msg, i + 1);
76e1fb4b
JB
11484 if (!scan_plan)
11485 return -ENOBUFS;
11486
67626964 11487 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
3b06d277
AS
11488 req->scan_plans[i].interval) ||
11489 (req->scan_plans[i].iterations &&
11490 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
11491 req->scan_plans[i].iterations)))
11492 return -ENOBUFS;
11493 nla_nest_end(msg, scan_plan);
11494 }
11495 nla_nest_end(msg, scan_plans);
11496
75453ccb
LC
11497 nla_nest_end(msg, nd);
11498
11499 return 0;
11500}
11501
ff1b6e69
JB
11502static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
11503{
11504 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11505 struct sk_buff *msg;
11506 void *hdr;
2a0e047e 11507 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 11508
964dc9e2 11509 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
11510 return -EOPNOTSUPP;
11511
6abb9cb9 11512 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 11513 /* adjust size to have room for all the data */
6abb9cb9
JB
11514 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
11515 rdev->wiphy.wowlan_config->tcp->payload_len +
11516 rdev->wiphy.wowlan_config->tcp->wake_len +
11517 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
11518 }
11519
11520 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
11521 if (!msg)
11522 return -ENOMEM;
11523
15e47304 11524 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
11525 NL80211_CMD_GET_WOWLAN);
11526 if (!hdr)
11527 goto nla_put_failure;
11528
6abb9cb9 11529 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
11530 struct nlattr *nl_wowlan;
11531
ae0be8de
MK
11532 nl_wowlan = nla_nest_start_noflag(msg,
11533 NL80211_ATTR_WOWLAN_TRIGGERS);
ff1b6e69
JB
11534 if (!nl_wowlan)
11535 goto nla_put_failure;
11536
6abb9cb9 11537 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 11538 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 11539 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 11540 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 11541 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 11542 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 11543 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 11544 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 11545 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 11546 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 11547 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 11548 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 11549 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
11550 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
11551 goto nla_put_failure;
2a0e047e 11552
bb92d199
AK
11553 if (nl80211_send_wowlan_patterns(msg, rdev))
11554 goto nla_put_failure;
2a0e047e 11555
6abb9cb9
JB
11556 if (nl80211_send_wowlan_tcp(msg,
11557 rdev->wiphy.wowlan_config->tcp))
2a0e047e 11558 goto nla_put_failure;
75453ccb
LC
11559
11560 if (nl80211_send_wowlan_nd(
11561 msg,
11562 rdev->wiphy.wowlan_config->nd_config))
11563 goto nla_put_failure;
2a0e047e 11564
ff1b6e69
JB
11565 nla_nest_end(msg, nl_wowlan);
11566 }
11567
11568 genlmsg_end(msg, hdr);
11569 return genlmsg_reply(msg, info);
11570
11571nla_put_failure:
11572 nlmsg_free(msg);
11573 return -ENOBUFS;
11574}
11575
2a0e047e
JB
11576static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
11577 struct nlattr *attr,
11578 struct cfg80211_wowlan *trig)
11579{
11580 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
11581 struct cfg80211_wowlan_tcp *cfg;
11582 struct nl80211_wowlan_tcp_data_token *tok = NULL;
11583 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
11584 u32 size;
11585 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
11586 int err, port;
11587
964dc9e2 11588 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
11589 return -EINVAL;
11590
8cb08174
JB
11591 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TCP, attr,
11592 nl80211_wowlan_tcp_policy, NULL);
2a0e047e
JB
11593 if (err)
11594 return err;
11595
11596 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
11597 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
11598 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
11599 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
11600 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
11601 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
11602 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
11603 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
11604 return -EINVAL;
11605
11606 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 11607 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
11608 return -EINVAL;
11609
11610 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 11611 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 11612 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
11613 return -EINVAL;
11614
11615 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 11616 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
11617 return -EINVAL;
11618
11619 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
11620 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
11621 return -EINVAL;
11622
11623 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
11624 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
11625
11626 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
11627 tokens_size = tokln - sizeof(*tok);
11628
11629 if (!tok->len || tokens_size % tok->len)
11630 return -EINVAL;
964dc9e2 11631 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 11632 return -EINVAL;
964dc9e2 11633 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 11634 return -EINVAL;
964dc9e2 11635 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 11636 return -EINVAL;
964dc9e2 11637 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
11638 return -EINVAL;
11639 if (tok->offset + tok->len > data_size)
11640 return -EINVAL;
11641 }
11642
11643 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
11644 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 11645 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
11646 return -EINVAL;
11647 if (seq->len == 0 || seq->len > 4)
11648 return -EINVAL;
11649 if (seq->len + seq->offset > data_size)
11650 return -EINVAL;
11651 }
11652
11653 size = sizeof(*cfg);
11654 size += data_size;
11655 size += wake_size + wake_mask_size;
11656 size += tokens_size;
11657
11658 cfg = kzalloc(size, GFP_KERNEL);
11659 if (!cfg)
11660 return -ENOMEM;
67b61f6c
JB
11661 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
11662 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
11663 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
11664 ETH_ALEN);
11665 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
11666 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
11667 else
11668 port = 0;
11669#ifdef CONFIG_INET
11670 /* allocate a socket and port for it and use it */
11671 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
11672 IPPROTO_TCP, &cfg->sock, 1);
11673 if (err) {
11674 kfree(cfg);
11675 return err;
11676 }
11677 if (inet_csk_get_port(cfg->sock->sk, port)) {
11678 sock_release(cfg->sock);
11679 kfree(cfg);
11680 return -EADDRINUSE;
11681 }
11682 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
11683#else
11684 if (!port) {
11685 kfree(cfg);
11686 return -EINVAL;
11687 }
11688 cfg->src_port = port;
11689#endif
11690
11691 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
11692 cfg->payload_len = data_size;
11693 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
11694 memcpy((void *)cfg->payload,
11695 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
11696 data_size);
11697 if (seq)
11698 cfg->payload_seq = *seq;
11699 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
11700 cfg->wake_len = wake_size;
11701 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
11702 memcpy((void *)cfg->wake_data,
11703 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
11704 wake_size);
11705 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
11706 data_size + wake_size;
11707 memcpy((void *)cfg->wake_mask,
11708 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
11709 wake_mask_size);
11710 if (tok) {
11711 cfg->tokens_size = tokens_size;
11712 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
11713 }
11714
11715 trig->tcp = cfg;
11716
11717 return 0;
11718}
11719
8cd4d456
LC
11720static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
11721 const struct wiphy_wowlan_support *wowlan,
11722 struct nlattr *attr,
11723 struct cfg80211_wowlan *trig)
11724{
11725 struct nlattr **tb;
11726 int err;
11727
6396bb22 11728 tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
8cd4d456
LC
11729 if (!tb)
11730 return -ENOMEM;
11731
11732 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
11733 err = -EOPNOTSUPP;
11734 goto out;
11735 }
11736
8cb08174
JB
11737 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_MAX, attr,
11738 nl80211_policy, NULL);
8cd4d456
LC
11739 if (err)
11740 goto out;
11741
aad1e812
AVS
11742 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
11743 wowlan->max_nd_match_sets);
8cd4d456
LC
11744 err = PTR_ERR_OR_ZERO(trig->nd_config);
11745 if (err)
11746 trig->nd_config = NULL;
11747
11748out:
11749 kfree(tb);
11750 return err;
11751}
11752
ff1b6e69
JB
11753static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
11754{
11755 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11756 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 11757 struct cfg80211_wowlan new_triggers = {};
ae33bd81 11758 struct cfg80211_wowlan *ntrig;
964dc9e2 11759 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 11760 int err, i;
6abb9cb9 11761 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 11762 bool regular = false;
ff1b6e69 11763
964dc9e2 11764 if (!wowlan)
ff1b6e69
JB
11765 return -EOPNOTSUPP;
11766
ae33bd81
JB
11767 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
11768 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 11769 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
11770 goto set_wakeup;
11771 }
ff1b6e69 11772
8cb08174
JB
11773 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TRIG,
11774 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
11775 nl80211_wowlan_policy, info->extack);
ff1b6e69
JB
11776 if (err)
11777 return err;
11778
11779 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
11780 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
11781 return -EINVAL;
11782 new_triggers.any = true;
11783 }
11784
11785 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
11786 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
11787 return -EINVAL;
11788 new_triggers.disconnect = true;
98fc4386 11789 regular = true;
ff1b6e69
JB
11790 }
11791
11792 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
11793 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
11794 return -EINVAL;
11795 new_triggers.magic_pkt = true;
98fc4386 11796 regular = true;
ff1b6e69
JB
11797 }
11798
77dbbb13
JB
11799 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
11800 return -EINVAL;
11801
11802 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
11803 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
11804 return -EINVAL;
11805 new_triggers.gtk_rekey_failure = true;
98fc4386 11806 regular = true;
77dbbb13
JB
11807 }
11808
11809 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
11810 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
11811 return -EINVAL;
11812 new_triggers.eap_identity_req = true;
98fc4386 11813 regular = true;
77dbbb13
JB
11814 }
11815
11816 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
11817 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
11818 return -EINVAL;
11819 new_triggers.four_way_handshake = true;
98fc4386 11820 regular = true;
77dbbb13
JB
11821 }
11822
11823 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
11824 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
11825 return -EINVAL;
11826 new_triggers.rfkill_release = true;
98fc4386 11827 regular = true;
77dbbb13
JB
11828 }
11829
ff1b6e69
JB
11830 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
11831 struct nlattr *pat;
11832 int n_patterns = 0;
bb92d199 11833 int rem, pat_len, mask_len, pkt_offset;
50ac6607 11834 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 11835
98fc4386
JB
11836 regular = true;
11837
ff1b6e69
JB
11838 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
11839 rem)
11840 n_patterns++;
11841 if (n_patterns > wowlan->n_patterns)
11842 return -EINVAL;
11843
11844 new_triggers.patterns = kcalloc(n_patterns,
11845 sizeof(new_triggers.patterns[0]),
11846 GFP_KERNEL);
11847 if (!new_triggers.patterns)
11848 return -ENOMEM;
11849
11850 new_triggers.n_patterns = n_patterns;
11851 i = 0;
11852
11853 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
11854 rem) {
922bd80f
JB
11855 u8 *mask_pat;
11856
8cb08174
JB
11857 err = nla_parse_nested_deprecated(pat_tb,
11858 MAX_NL80211_PKTPAT,
11859 pat,
11860 nl80211_packet_pattern_policy,
11861 info->extack);
95bca62f
JB
11862 if (err)
11863 goto error;
11864
ff1b6e69 11865 err = -EINVAL;
50ac6607
AK
11866 if (!pat_tb[NL80211_PKTPAT_MASK] ||
11867 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 11868 goto error;
50ac6607 11869 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 11870 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 11871 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
11872 goto error;
11873 if (pat_len > wowlan->pattern_max_len ||
11874 pat_len < wowlan->pattern_min_len)
11875 goto error;
11876
50ac6607 11877 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
11878 pkt_offset = 0;
11879 else
11880 pkt_offset = nla_get_u32(
50ac6607 11881 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
11882 if (pkt_offset > wowlan->max_pkt_offset)
11883 goto error;
11884 new_triggers.patterns[i].pkt_offset = pkt_offset;
11885
922bd80f
JB
11886 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
11887 if (!mask_pat) {
ff1b6e69
JB
11888 err = -ENOMEM;
11889 goto error;
11890 }
922bd80f
JB
11891 new_triggers.patterns[i].mask = mask_pat;
11892 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 11893 mask_len);
922bd80f
JB
11894 mask_pat += mask_len;
11895 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 11896 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 11897 memcpy(mask_pat,
50ac6607 11898 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
11899 pat_len);
11900 i++;
11901 }
11902 }
11903
2a0e047e 11904 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 11905 regular = true;
2a0e047e
JB
11906 err = nl80211_parse_wowlan_tcp(
11907 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
11908 &new_triggers);
11909 if (err)
11910 goto error;
11911 }
11912
8cd4d456 11913 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 11914 regular = true;
8cd4d456
LC
11915 err = nl80211_parse_wowlan_nd(
11916 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
11917 &new_triggers);
11918 if (err)
11919 goto error;
11920 }
11921
98fc4386
JB
11922 /* The 'any' trigger means the device continues operating more or less
11923 * as in its normal operation mode and wakes up the host on most of the
11924 * normal interrupts (like packet RX, ...)
11925 * It therefore makes little sense to combine with the more constrained
11926 * wakeup trigger modes.
11927 */
11928 if (new_triggers.any && regular) {
11929 err = -EINVAL;
11930 goto error;
11931 }
11932
ae33bd81
JB
11933 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
11934 if (!ntrig) {
11935 err = -ENOMEM;
11936 goto error;
ff1b6e69 11937 }
ae33bd81 11938 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 11939 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 11940
ae33bd81 11941 set_wakeup:
6abb9cb9
JB
11942 if (rdev->ops->set_wakeup &&
11943 prev_enabled != !!rdev->wiphy.wowlan_config)
11944 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 11945
ff1b6e69
JB
11946 return 0;
11947 error:
11948 for (i = 0; i < new_triggers.n_patterns; i++)
11949 kfree(new_triggers.patterns[i].mask);
11950 kfree(new_triggers.patterns);
2a0e047e
JB
11951 if (new_triggers.tcp && new_triggers.tcp->sock)
11952 sock_release(new_triggers.tcp->sock);
11953 kfree(new_triggers.tcp);
e5dbe070 11954 kfree(new_triggers.nd_config);
ff1b6e69
JB
11955 return err;
11956}
dfb89c56 11957#endif
ff1b6e69 11958
be29b99a
AK
11959static int nl80211_send_coalesce_rules(struct sk_buff *msg,
11960 struct cfg80211_registered_device *rdev)
11961{
11962 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
11963 int i, j, pat_len;
11964 struct cfg80211_coalesce_rules *rule;
11965
11966 if (!rdev->coalesce->n_rules)
11967 return 0;
11968
ae0be8de 11969 nl_rules = nla_nest_start_noflag(msg, NL80211_ATTR_COALESCE_RULE);
be29b99a
AK
11970 if (!nl_rules)
11971 return -ENOBUFS;
11972
11973 for (i = 0; i < rdev->coalesce->n_rules; i++) {
ae0be8de 11974 nl_rule = nla_nest_start_noflag(msg, i + 1);
be29b99a
AK
11975 if (!nl_rule)
11976 return -ENOBUFS;
11977
11978 rule = &rdev->coalesce->rules[i];
11979 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
11980 rule->delay))
11981 return -ENOBUFS;
11982
11983 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
11984 rule->condition))
11985 return -ENOBUFS;
11986
ae0be8de
MK
11987 nl_pats = nla_nest_start_noflag(msg,
11988 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
be29b99a
AK
11989 if (!nl_pats)
11990 return -ENOBUFS;
11991
11992 for (j = 0; j < rule->n_patterns; j++) {
ae0be8de 11993 nl_pat = nla_nest_start_noflag(msg, j + 1);
be29b99a
AK
11994 if (!nl_pat)
11995 return -ENOBUFS;
11996 pat_len = rule->patterns[j].pattern_len;
11997 if (nla_put(msg, NL80211_PKTPAT_MASK,
11998 DIV_ROUND_UP(pat_len, 8),
11999 rule->patterns[j].mask) ||
12000 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
12001 rule->patterns[j].pattern) ||
12002 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
12003 rule->patterns[j].pkt_offset))
12004 return -ENOBUFS;
12005 nla_nest_end(msg, nl_pat);
12006 }
12007 nla_nest_end(msg, nl_pats);
12008 nla_nest_end(msg, nl_rule);
12009 }
12010 nla_nest_end(msg, nl_rules);
12011
12012 return 0;
12013}
12014
12015static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
12016{
12017 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12018 struct sk_buff *msg;
12019 void *hdr;
12020
12021 if (!rdev->wiphy.coalesce)
12022 return -EOPNOTSUPP;
12023
12024 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12025 if (!msg)
12026 return -ENOMEM;
12027
12028 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12029 NL80211_CMD_GET_COALESCE);
12030 if (!hdr)
12031 goto nla_put_failure;
12032
12033 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
12034 goto nla_put_failure;
12035
12036 genlmsg_end(msg, hdr);
12037 return genlmsg_reply(msg, info);
12038
12039nla_put_failure:
12040 nlmsg_free(msg);
12041 return -ENOBUFS;
12042}
12043
12044void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
12045{
12046 struct cfg80211_coalesce *coalesce = rdev->coalesce;
12047 int i, j;
12048 struct cfg80211_coalesce_rules *rule;
12049
12050 if (!coalesce)
12051 return;
12052
12053 for (i = 0; i < coalesce->n_rules; i++) {
12054 rule = &coalesce->rules[i];
12055 for (j = 0; j < rule->n_patterns; j++)
12056 kfree(rule->patterns[j].mask);
12057 kfree(rule->patterns);
12058 }
12059 kfree(coalesce->rules);
12060 kfree(coalesce);
12061 rdev->coalesce = NULL;
12062}
12063
12064static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
12065 struct nlattr *rule,
12066 struct cfg80211_coalesce_rules *new_rule)
12067{
12068 int err, i;
12069 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
12070 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
12071 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
12072 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
12073
8cb08174
JB
12074 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_COALESCE_RULE_MAX,
12075 rule, nl80211_coalesce_policy, NULL);
be29b99a
AK
12076 if (err)
12077 return err;
12078
12079 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
12080 new_rule->delay =
12081 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
12082 if (new_rule->delay > coalesce->max_delay)
12083 return -EINVAL;
12084
12085 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
12086 new_rule->condition =
12087 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
be29b99a
AK
12088
12089 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
12090 return -EINVAL;
12091
12092 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
12093 rem)
12094 n_patterns++;
12095 if (n_patterns > coalesce->n_patterns)
12096 return -EINVAL;
12097
12098 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
12099 GFP_KERNEL);
12100 if (!new_rule->patterns)
12101 return -ENOMEM;
12102
12103 new_rule->n_patterns = n_patterns;
12104 i = 0;
12105
12106 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
12107 rem) {
922bd80f
JB
12108 u8 *mask_pat;
12109
8cb08174
JB
12110 err = nla_parse_nested_deprecated(pat_tb, MAX_NL80211_PKTPAT,
12111 pat,
12112 nl80211_packet_pattern_policy,
12113 NULL);
95bca62f
JB
12114 if (err)
12115 return err;
12116
be29b99a
AK
12117 if (!pat_tb[NL80211_PKTPAT_MASK] ||
12118 !pat_tb[NL80211_PKTPAT_PATTERN])
12119 return -EINVAL;
12120 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
12121 mask_len = DIV_ROUND_UP(pat_len, 8);
12122 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
12123 return -EINVAL;
12124 if (pat_len > coalesce->pattern_max_len ||
12125 pat_len < coalesce->pattern_min_len)
12126 return -EINVAL;
12127
12128 if (!pat_tb[NL80211_PKTPAT_OFFSET])
12129 pkt_offset = 0;
12130 else
12131 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
12132 if (pkt_offset > coalesce->max_pkt_offset)
12133 return -EINVAL;
12134 new_rule->patterns[i].pkt_offset = pkt_offset;
12135
922bd80f
JB
12136 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
12137 if (!mask_pat)
be29b99a 12138 return -ENOMEM;
922bd80f
JB
12139
12140 new_rule->patterns[i].mask = mask_pat;
12141 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
12142 mask_len);
12143
12144 mask_pat += mask_len;
12145 new_rule->patterns[i].pattern = mask_pat;
be29b99a 12146 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
12147 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
12148 pat_len);
be29b99a
AK
12149 i++;
12150 }
12151
12152 return 0;
12153}
12154
12155static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
12156{
12157 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12158 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
12159 struct cfg80211_coalesce new_coalesce = {};
12160 struct cfg80211_coalesce *n_coalesce;
12161 int err, rem_rule, n_rules = 0, i, j;
12162 struct nlattr *rule;
12163 struct cfg80211_coalesce_rules *tmp_rule;
12164
12165 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
12166 return -EOPNOTSUPP;
12167
12168 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
12169 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 12170 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
12171 return 0;
12172 }
12173
12174 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
12175 rem_rule)
12176 n_rules++;
12177 if (n_rules > coalesce->n_rules)
12178 return -EINVAL;
12179
12180 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
12181 GFP_KERNEL);
12182 if (!new_coalesce.rules)
12183 return -ENOMEM;
12184
12185 new_coalesce.n_rules = n_rules;
12186 i = 0;
12187
12188 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
12189 rem_rule) {
12190 err = nl80211_parse_coalesce_rule(rdev, rule,
12191 &new_coalesce.rules[i]);
12192 if (err)
12193 goto error;
12194
12195 i++;
12196 }
12197
a1056b1b 12198 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
12199 if (err)
12200 goto error;
12201
12202 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
12203 if (!n_coalesce) {
12204 err = -ENOMEM;
12205 goto error;
12206 }
12207 cfg80211_rdev_free_coalesce(rdev);
12208 rdev->coalesce = n_coalesce;
12209
12210 return 0;
12211error:
12212 for (i = 0; i < new_coalesce.n_rules; i++) {
12213 tmp_rule = &new_coalesce.rules[i];
12214 for (j = 0; j < tmp_rule->n_patterns; j++)
12215 kfree(tmp_rule->patterns[j].mask);
12216 kfree(tmp_rule->patterns);
12217 }
12218 kfree(new_coalesce.rules);
12219
12220 return err;
12221}
12222
e5497d76
JB
12223static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
12224{
12225 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12226 struct net_device *dev = info->user_ptr[1];
12227 struct wireless_dev *wdev = dev->ieee80211_ptr;
12228 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
12229 struct cfg80211_gtk_rekey_data rekey_data;
12230 int err;
12231
12232 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
12233 return -EINVAL;
12234
8cb08174
JB
12235 err = nla_parse_nested_deprecated(tb, MAX_NL80211_REKEY_DATA,
12236 info->attrs[NL80211_ATTR_REKEY_DATA],
12237 nl80211_rekey_policy, info->extack);
e5497d76
JB
12238 if (err)
12239 return err;
12240
e785fa0a
VD
12241 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
12242 !tb[NL80211_REKEY_DATA_KCK])
12243 return -EINVAL;
e5497d76
JB
12244 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
12245 return -ERANGE;
12246 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
12247 return -ERANGE;
12248 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
12249 return -ERANGE;
12250
78f686ca
JB
12251 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
12252 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
12253 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
e5497d76
JB
12254
12255 wdev_lock(wdev);
12256 if (!wdev->current_bss) {
12257 err = -ENOTCONN;
12258 goto out;
12259 }
12260
12261 if (!rdev->ops->set_rekey_data) {
12262 err = -EOPNOTSUPP;
12263 goto out;
12264 }
12265
e35e4d28 12266 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
12267 out:
12268 wdev_unlock(wdev);
12269 return err;
12270}
12271
28946da7
JB
12272static int nl80211_register_unexpected_frame(struct sk_buff *skb,
12273 struct genl_info *info)
12274{
12275 struct net_device *dev = info->user_ptr[1];
12276 struct wireless_dev *wdev = dev->ieee80211_ptr;
12277
12278 if (wdev->iftype != NL80211_IFTYPE_AP &&
12279 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12280 return -EINVAL;
12281
15e47304 12282 if (wdev->ap_unexpected_nlportid)
28946da7
JB
12283 return -EBUSY;
12284
15e47304 12285 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
12286 return 0;
12287}
12288
7f6cf311
JB
12289static int nl80211_probe_client(struct sk_buff *skb,
12290 struct genl_info *info)
12291{
12292 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12293 struct net_device *dev = info->user_ptr[1];
12294 struct wireless_dev *wdev = dev->ieee80211_ptr;
12295 struct sk_buff *msg;
12296 void *hdr;
12297 const u8 *addr;
12298 u64 cookie;
12299 int err;
12300
12301 if (wdev->iftype != NL80211_IFTYPE_AP &&
12302 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12303 return -EOPNOTSUPP;
12304
12305 if (!info->attrs[NL80211_ATTR_MAC])
12306 return -EINVAL;
12307
12308 if (!rdev->ops->probe_client)
12309 return -EOPNOTSUPP;
12310
12311 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12312 if (!msg)
12313 return -ENOMEM;
12314
15e47304 12315 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 12316 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
12317 if (!hdr) {
12318 err = -ENOBUFS;
7f6cf311
JB
12319 goto free_msg;
12320 }
12321
12322 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12323
e35e4d28 12324 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
12325 if (err)
12326 goto free_msg;
12327
2dad624e
ND
12328 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12329 NL80211_ATTR_PAD))
9360ffd1 12330 goto nla_put_failure;
7f6cf311
JB
12331
12332 genlmsg_end(msg, hdr);
12333
12334 return genlmsg_reply(msg, info);
12335
12336 nla_put_failure:
12337 err = -ENOBUFS;
12338 free_msg:
12339 nlmsg_free(msg);
12340 return err;
12341}
12342
5e760230
JB
12343static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
12344{
12345 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
12346 struct cfg80211_beacon_registration *reg, *nreg;
12347 int rv;
5e760230
JB
12348
12349 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
12350 return -EOPNOTSUPP;
12351
37c73b5f
BG
12352 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
12353 if (!nreg)
12354 return -ENOMEM;
12355
12356 /* First, check if already registered. */
12357 spin_lock_bh(&rdev->beacon_registrations_lock);
12358 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
12359 if (reg->nlportid == info->snd_portid) {
12360 rv = -EALREADY;
12361 goto out_err;
12362 }
12363 }
12364 /* Add it to the list */
12365 nreg->nlportid = info->snd_portid;
12366 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 12367
37c73b5f 12368 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
12369
12370 return 0;
37c73b5f
BG
12371out_err:
12372 spin_unlock_bh(&rdev->beacon_registrations_lock);
12373 kfree(nreg);
12374 return rv;
5e760230
JB
12375}
12376
98104fde
JB
12377static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
12378{
12379 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12380 struct wireless_dev *wdev = info->user_ptr[1];
12381 int err;
12382
12383 if (!rdev->ops->start_p2p_device)
12384 return -EOPNOTSUPP;
12385
12386 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
12387 return -EOPNOTSUPP;
12388
73c7da3d 12389 if (wdev_running(wdev))
98104fde
JB
12390 return 0;
12391
b6a55015
LC
12392 if (rfkill_blocked(rdev->rfkill))
12393 return -ERFKILL;
98104fde 12394
eeb126e9 12395 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
12396 if (err)
12397 return err;
12398
73c7da3d 12399 wdev->is_running = true;
98104fde 12400 rdev->opencount++;
98104fde
JB
12401
12402 return 0;
12403}
12404
12405static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
12406{
12407 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12408 struct wireless_dev *wdev = info->user_ptr[1];
12409
12410 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
12411 return -EOPNOTSUPP;
12412
12413 if (!rdev->ops->stop_p2p_device)
12414 return -EOPNOTSUPP;
12415
f9f47529 12416 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
12417
12418 return 0;
12419}
12420
cb3b7d87
AB
12421static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
12422{
12423 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12424 struct wireless_dev *wdev = info->user_ptr[1];
12425 struct cfg80211_nan_conf conf = {};
12426 int err;
12427
12428 if (wdev->iftype != NL80211_IFTYPE_NAN)
12429 return -EOPNOTSUPP;
12430
eeb04a96 12431 if (wdev_running(wdev))
cb3b7d87
AB
12432 return -EEXIST;
12433
12434 if (rfkill_blocked(rdev->rfkill))
12435 return -ERFKILL;
12436
12437 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
12438 return -EINVAL;
12439
cb3b7d87
AB
12440 conf.master_pref =
12441 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
cb3b7d87 12442
8585989d
LC
12443 if (info->attrs[NL80211_ATTR_BANDS]) {
12444 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
12445
12446 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
12447 return -EOPNOTSUPP;
12448
12449 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
12450 return -EINVAL;
12451
12452 conf.bands = bands;
12453 }
cb3b7d87
AB
12454
12455 err = rdev_start_nan(rdev, wdev, &conf);
12456 if (err)
12457 return err;
12458
73c7da3d 12459 wdev->is_running = true;
cb3b7d87
AB
12460 rdev->opencount++;
12461
12462 return 0;
12463}
12464
12465static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
12466{
12467 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12468 struct wireless_dev *wdev = info->user_ptr[1];
12469
12470 if (wdev->iftype != NL80211_IFTYPE_NAN)
12471 return -EOPNOTSUPP;
12472
12473 cfg80211_stop_nan(rdev, wdev);
12474
12475 return 0;
12476}
12477
a442b761
AB
12478static int validate_nan_filter(struct nlattr *filter_attr)
12479{
12480 struct nlattr *attr;
12481 int len = 0, n_entries = 0, rem;
12482
12483 nla_for_each_nested(attr, filter_attr, rem) {
12484 len += nla_len(attr);
12485 n_entries++;
12486 }
12487
12488 if (len >= U8_MAX)
12489 return -EINVAL;
12490
12491 return n_entries;
12492}
12493
12494static int handle_nan_filter(struct nlattr *attr_filter,
12495 struct cfg80211_nan_func *func,
12496 bool tx)
12497{
12498 struct nlattr *attr;
12499 int n_entries, rem, i;
12500 struct cfg80211_nan_func_filter *filter;
12501
12502 n_entries = validate_nan_filter(attr_filter);
12503 if (n_entries < 0)
12504 return n_entries;
12505
12506 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
12507
12508 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
12509 if (!filter)
12510 return -ENOMEM;
12511
12512 i = 0;
12513 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 12514 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
a442b761
AB
12515 filter[i].len = nla_len(attr);
12516 i++;
12517 }
12518 if (tx) {
12519 func->num_tx_filters = n_entries;
12520 func->tx_filters = filter;
12521 } else {
12522 func->num_rx_filters = n_entries;
12523 func->rx_filters = filter;
12524 }
12525
12526 return 0;
12527}
12528
12529static int nl80211_nan_add_func(struct sk_buff *skb,
12530 struct genl_info *info)
12531{
12532 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12533 struct wireless_dev *wdev = info->user_ptr[1];
12534 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
12535 struct cfg80211_nan_func *func;
12536 struct sk_buff *msg = NULL;
12537 void *hdr = NULL;
12538 int err = 0;
12539
12540 if (wdev->iftype != NL80211_IFTYPE_NAN)
12541 return -EOPNOTSUPP;
12542
73c7da3d 12543 if (!wdev_running(wdev))
a442b761
AB
12544 return -ENOTCONN;
12545
12546 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
12547 return -EINVAL;
12548
8cb08174
JB
12549 err = nla_parse_nested_deprecated(tb, NL80211_NAN_FUNC_ATTR_MAX,
12550 info->attrs[NL80211_ATTR_NAN_FUNC],
12551 nl80211_nan_func_policy,
12552 info->extack);
a442b761
AB
12553 if (err)
12554 return err;
12555
12556 func = kzalloc(sizeof(*func), GFP_KERNEL);
12557 if (!func)
12558 return -ENOMEM;
12559
b60ad348 12560 func->cookie = cfg80211_assign_cookie(rdev);
a442b761
AB
12561
12562 if (!tb[NL80211_NAN_FUNC_TYPE] ||
12563 nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
12564 err = -EINVAL;
12565 goto out;
12566 }
12567
12568
12569 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
12570
12571 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
12572 err = -EINVAL;
12573 goto out;
12574 }
12575
12576 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
12577 sizeof(func->service_id));
12578
12579 func->close_range =
12580 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
12581
12582 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
12583 func->serv_spec_info_len =
12584 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
12585 func->serv_spec_info =
12586 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
12587 func->serv_spec_info_len,
12588 GFP_KERNEL);
12589 if (!func->serv_spec_info) {
12590 err = -ENOMEM;
12591 goto out;
12592 }
12593 }
12594
12595 if (tb[NL80211_NAN_FUNC_TTL])
12596 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
12597
12598 switch (func->type) {
12599 case NL80211_NAN_FUNC_PUBLISH:
12600 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
12601 err = -EINVAL;
12602 goto out;
12603 }
12604
12605 func->publish_type =
12606 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
12607 func->publish_bcast =
12608 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
12609
12610 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
12611 func->publish_bcast) {
12612 err = -EINVAL;
12613 goto out;
12614 }
12615 break;
12616 case NL80211_NAN_FUNC_SUBSCRIBE:
12617 func->subscribe_active =
12618 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
12619 break;
12620 case NL80211_NAN_FUNC_FOLLOW_UP:
12621 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
3ea15452
HC
12622 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
12623 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
a442b761
AB
12624 err = -EINVAL;
12625 goto out;
12626 }
12627
12628 func->followup_id =
12629 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
12630 func->followup_reqid =
12631 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
12632 memcpy(func->followup_dest.addr,
12633 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
12634 sizeof(func->followup_dest.addr));
12635 if (func->ttl) {
12636 err = -EINVAL;
12637 goto out;
12638 }
12639 break;
12640 default:
12641 err = -EINVAL;
12642 goto out;
12643 }
12644
12645 if (tb[NL80211_NAN_FUNC_SRF]) {
12646 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
12647
8cb08174
JB
12648 err = nla_parse_nested_deprecated(srf_tb,
12649 NL80211_NAN_SRF_ATTR_MAX,
12650 tb[NL80211_NAN_FUNC_SRF],
12651 nl80211_nan_srf_policy,
12652 info->extack);
a442b761
AB
12653 if (err)
12654 goto out;
12655
12656 func->srf_include =
12657 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
12658
12659 if (srf_tb[NL80211_NAN_SRF_BF]) {
12660 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
12661 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
12662 err = -EINVAL;
12663 goto out;
12664 }
12665
12666 func->srf_bf_len =
12667 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
12668 func->srf_bf =
12669 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
12670 func->srf_bf_len, GFP_KERNEL);
12671 if (!func->srf_bf) {
12672 err = -ENOMEM;
12673 goto out;
12674 }
12675
12676 func->srf_bf_idx =
12677 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
12678 } else {
12679 struct nlattr *attr, *mac_attr =
12680 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
12681 int n_entries, rem, i = 0;
12682
12683 if (!mac_attr) {
12684 err = -EINVAL;
12685 goto out;
12686 }
12687
12688 n_entries = validate_acl_mac_addrs(mac_attr);
12689 if (n_entries <= 0) {
12690 err = -EINVAL;
12691 goto out;
12692 }
12693
12694 func->srf_num_macs = n_entries;
12695 func->srf_macs =
6396bb22 12696 kcalloc(n_entries, sizeof(*func->srf_macs),
a442b761
AB
12697 GFP_KERNEL);
12698 if (!func->srf_macs) {
12699 err = -ENOMEM;
12700 goto out;
12701 }
12702
12703 nla_for_each_nested(attr, mac_attr, rem)
12704 memcpy(func->srf_macs[i++].addr, nla_data(attr),
12705 sizeof(*func->srf_macs));
12706 }
12707 }
12708
12709 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
12710 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
12711 func, true);
12712 if (err)
12713 goto out;
12714 }
12715
12716 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
12717 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
12718 func, false);
12719 if (err)
12720 goto out;
12721 }
12722
12723 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12724 if (!msg) {
12725 err = -ENOMEM;
12726 goto out;
12727 }
12728
12729 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12730 NL80211_CMD_ADD_NAN_FUNCTION);
12731 /* This can't really happen - we just allocated 4KB */
12732 if (WARN_ON(!hdr)) {
12733 err = -ENOMEM;
12734 goto out;
12735 }
12736
12737 err = rdev_add_nan_func(rdev, wdev, func);
12738out:
12739 if (err < 0) {
12740 cfg80211_free_nan_func(func);
12741 nlmsg_free(msg);
12742 return err;
12743 }
12744
12745 /* propagate the instance id and cookie to userspace */
12746 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
12747 NL80211_ATTR_PAD))
12748 goto nla_put_failure;
12749
ae0be8de 12750 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
a442b761
AB
12751 if (!func_attr)
12752 goto nla_put_failure;
12753
12754 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
12755 func->instance_id))
12756 goto nla_put_failure;
12757
12758 nla_nest_end(msg, func_attr);
12759
12760 genlmsg_end(msg, hdr);
12761 return genlmsg_reply(msg, info);
12762
12763nla_put_failure:
12764 nlmsg_free(msg);
12765 return -ENOBUFS;
12766}
12767
12768static int nl80211_nan_del_func(struct sk_buff *skb,
12769 struct genl_info *info)
12770{
12771 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12772 struct wireless_dev *wdev = info->user_ptr[1];
12773 u64 cookie;
12774
12775 if (wdev->iftype != NL80211_IFTYPE_NAN)
12776 return -EOPNOTSUPP;
12777
73c7da3d 12778 if (!wdev_running(wdev))
a442b761
AB
12779 return -ENOTCONN;
12780
12781 if (!info->attrs[NL80211_ATTR_COOKIE])
12782 return -EINVAL;
12783
a442b761
AB
12784 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
12785
12786 rdev_del_nan_func(rdev, wdev, cookie);
12787
12788 return 0;
12789}
12790
a5a9dcf2
AB
12791static int nl80211_nan_change_config(struct sk_buff *skb,
12792 struct genl_info *info)
12793{
12794 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12795 struct wireless_dev *wdev = info->user_ptr[1];
12796 struct cfg80211_nan_conf conf = {};
12797 u32 changed = 0;
12798
12799 if (wdev->iftype != NL80211_IFTYPE_NAN)
12800 return -EOPNOTSUPP;
12801
73c7da3d 12802 if (!wdev_running(wdev))
a5a9dcf2
AB
12803 return -ENOTCONN;
12804
12805 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
12806 conf.master_pref =
12807 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
12808 if (conf.master_pref <= 1 || conf.master_pref == 255)
12809 return -EINVAL;
12810
12811 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
12812 }
12813
8585989d
LC
12814 if (info->attrs[NL80211_ATTR_BANDS]) {
12815 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
12816
12817 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
12818 return -EOPNOTSUPP;
12819
12820 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
12821 return -EINVAL;
12822
12823 conf.bands = bands;
12824 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
12825 }
12826
12827 if (!changed)
12828 return -EINVAL;
12829
12830 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
12831}
12832
50bcd31d
AB
12833void cfg80211_nan_match(struct wireless_dev *wdev,
12834 struct cfg80211_nan_match_params *match, gfp_t gfp)
12835{
12836 struct wiphy *wiphy = wdev->wiphy;
12837 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
12838 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
12839 struct sk_buff *msg;
12840 void *hdr;
12841
12842 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
12843 return;
12844
12845 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
12846 if (!msg)
12847 return;
12848
12849 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
12850 if (!hdr) {
12851 nlmsg_free(msg);
12852 return;
12853 }
12854
12855 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12856 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12857 wdev->netdev->ifindex)) ||
12858 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12859 NL80211_ATTR_PAD))
12860 goto nla_put_failure;
12861
12862 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
12863 NL80211_ATTR_PAD) ||
12864 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
12865 goto nla_put_failure;
12866
ae0be8de 12867 match_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_MATCH);
50bcd31d
AB
12868 if (!match_attr)
12869 goto nla_put_failure;
12870
ae0be8de
MK
12871 local_func_attr = nla_nest_start_noflag(msg,
12872 NL80211_NAN_MATCH_FUNC_LOCAL);
50bcd31d
AB
12873 if (!local_func_attr)
12874 goto nla_put_failure;
12875
12876 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
12877 goto nla_put_failure;
12878
12879 nla_nest_end(msg, local_func_attr);
12880
ae0be8de
MK
12881 peer_func_attr = nla_nest_start_noflag(msg,
12882 NL80211_NAN_MATCH_FUNC_PEER);
50bcd31d
AB
12883 if (!peer_func_attr)
12884 goto nla_put_failure;
12885
12886 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
12887 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
12888 goto nla_put_failure;
12889
12890 if (match->info && match->info_len &&
12891 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
12892 match->info))
12893 goto nla_put_failure;
12894
12895 nla_nest_end(msg, peer_func_attr);
12896 nla_nest_end(msg, match_attr);
12897 genlmsg_end(msg, hdr);
12898
12899 if (!wdev->owner_nlportid)
12900 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
12901 msg, 0, NL80211_MCGRP_NAN, gfp);
12902 else
12903 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
12904 wdev->owner_nlportid);
12905
12906 return;
12907
12908nla_put_failure:
12909 nlmsg_free(msg);
12910}
12911EXPORT_SYMBOL(cfg80211_nan_match);
12912
368e5a7b
AB
12913void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
12914 u8 inst_id,
12915 enum nl80211_nan_func_term_reason reason,
12916 u64 cookie, gfp_t gfp)
12917{
12918 struct wiphy *wiphy = wdev->wiphy;
12919 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
12920 struct sk_buff *msg;
12921 struct nlattr *func_attr;
12922 void *hdr;
12923
12924 if (WARN_ON(!inst_id))
12925 return;
12926
12927 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
12928 if (!msg)
12929 return;
12930
12931 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
12932 if (!hdr) {
12933 nlmsg_free(msg);
12934 return;
12935 }
12936
12937 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12938 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12939 wdev->netdev->ifindex)) ||
12940 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12941 NL80211_ATTR_PAD))
12942 goto nla_put_failure;
12943
12944 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12945 NL80211_ATTR_PAD))
12946 goto nla_put_failure;
12947
ae0be8de 12948 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
368e5a7b
AB
12949 if (!func_attr)
12950 goto nla_put_failure;
12951
12952 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
12953 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
12954 goto nla_put_failure;
12955
12956 nla_nest_end(msg, func_attr);
12957 genlmsg_end(msg, hdr);
12958
12959 if (!wdev->owner_nlportid)
12960 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
12961 msg, 0, NL80211_MCGRP_NAN, gfp);
12962 else
12963 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
12964 wdev->owner_nlportid);
12965
12966 return;
12967
12968nla_put_failure:
12969 nlmsg_free(msg);
12970}
12971EXPORT_SYMBOL(cfg80211_nan_func_terminated);
12972
3713b4e3
JB
12973static int nl80211_get_protocol_features(struct sk_buff *skb,
12974 struct genl_info *info)
12975{
12976 void *hdr;
12977 struct sk_buff *msg;
12978
12979 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12980 if (!msg)
12981 return -ENOMEM;
12982
12983 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12984 NL80211_CMD_GET_PROTOCOL_FEATURES);
12985 if (!hdr)
12986 goto nla_put_failure;
12987
12988 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
12989 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
12990 goto nla_put_failure;
12991
12992 genlmsg_end(msg, hdr);
12993 return genlmsg_reply(msg, info);
12994
12995 nla_put_failure:
12996 kfree_skb(msg);
12997 return -ENOBUFS;
12998}
12999
355199e0
JM
13000static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
13001{
13002 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13003 struct cfg80211_update_ft_ies_params ft_params;
13004 struct net_device *dev = info->user_ptr[1];
13005
13006 if (!rdev->ops->update_ft_ies)
13007 return -EOPNOTSUPP;
13008
13009 if (!info->attrs[NL80211_ATTR_MDID] ||
3d7af878 13010 !info->attrs[NL80211_ATTR_IE])
355199e0
JM
13011 return -EINVAL;
13012
13013 memset(&ft_params, 0, sizeof(ft_params));
13014 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
13015 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
13016 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
13017
13018 return rdev_update_ft_ies(rdev, dev, &ft_params);
13019}
13020
5de17984
AS
13021static int nl80211_crit_protocol_start(struct sk_buff *skb,
13022 struct genl_info *info)
13023{
13024 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13025 struct wireless_dev *wdev = info->user_ptr[1];
13026 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
13027 u16 duration;
13028 int ret;
13029
13030 if (!rdev->ops->crit_proto_start)
13031 return -EOPNOTSUPP;
13032
13033 if (WARN_ON(!rdev->ops->crit_proto_stop))
13034 return -EINVAL;
13035
13036 if (rdev->crit_proto_nlportid)
13037 return -EBUSY;
13038
13039 /* determine protocol if provided */
13040 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
13041 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
13042
13043 if (proto >= NUM_NL80211_CRIT_PROTO)
13044 return -EINVAL;
13045
13046 /* timeout must be provided */
13047 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
13048 return -EINVAL;
13049
13050 duration =
13051 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
13052
13053 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
13054 return -ERANGE;
13055
13056 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
13057 if (!ret)
13058 rdev->crit_proto_nlportid = info->snd_portid;
13059
13060 return ret;
13061}
13062
13063static int nl80211_crit_protocol_stop(struct sk_buff *skb,
13064 struct genl_info *info)
13065{
13066 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13067 struct wireless_dev *wdev = info->user_ptr[1];
13068
13069 if (!rdev->ops->crit_proto_stop)
13070 return -EOPNOTSUPP;
13071
13072 if (rdev->crit_proto_nlportid) {
13073 rdev->crit_proto_nlportid = 0;
13074 rdev_crit_proto_stop(rdev, wdev);
13075 }
13076 return 0;
13077}
13078
901bb989
JB
13079static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
13080 struct nlattr *attr,
13081 struct netlink_ext_ack *extack)
13082{
13083 if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
13084 if (attr->nla_type & NLA_F_NESTED) {
13085 NL_SET_ERR_MSG_ATTR(extack, attr,
13086 "unexpected nested data");
13087 return -EINVAL;
13088 }
13089
13090 return 0;
13091 }
13092
13093 if (!(attr->nla_type & NLA_F_NESTED)) {
13094 NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
13095 return -EINVAL;
13096 }
13097
32d5109a 13098 return nla_validate_nested(attr, vcmd->maxattr, vcmd->policy, extack);
901bb989
JB
13099}
13100
ad7e718c
JB
13101static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
13102{
13103 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13104 struct wireless_dev *wdev =
13105 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
13106 int i, err;
13107 u32 vid, subcmd;
13108
13109 if (!rdev->wiphy.vendor_commands)
13110 return -EOPNOTSUPP;
13111
13112 if (IS_ERR(wdev)) {
13113 err = PTR_ERR(wdev);
13114 if (err != -EINVAL)
13115 return err;
13116 wdev = NULL;
13117 } else if (wdev->wiphy != &rdev->wiphy) {
13118 return -EINVAL;
13119 }
13120
13121 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
13122 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
13123 return -EINVAL;
13124
13125 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
13126 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
13127 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
13128 const struct wiphy_vendor_command *vcmd;
13129 void *data = NULL;
13130 int len = 0;
13131
13132 vcmd = &rdev->wiphy.vendor_commands[i];
13133
13134 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
13135 continue;
13136
13137 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
13138 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
13139 if (!wdev)
13140 return -EINVAL;
13141 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
13142 !wdev->netdev)
13143 return -EINVAL;
13144
13145 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 13146 if (!wdev_running(wdev))
ad7e718c
JB
13147 return -ENETDOWN;
13148 }
7bdbe400
JB
13149
13150 if (!vcmd->doit)
13151 return -EOPNOTSUPP;
ad7e718c
JB
13152 } else {
13153 wdev = NULL;
13154 }
13155
13156 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
13157 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
13158 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
13159
13160 err = nl80211_vendor_check_policy(vcmd,
13161 info->attrs[NL80211_ATTR_VENDOR_DATA],
13162 info->extack);
13163 if (err)
13164 return err;
ad7e718c
JB
13165 }
13166
13167 rdev->cur_cmd_info = info;
901bb989 13168 err = vcmd->doit(&rdev->wiphy, wdev, data, len);
ad7e718c
JB
13169 rdev->cur_cmd_info = NULL;
13170 return err;
13171 }
13172
13173 return -EOPNOTSUPP;
13174}
13175
7bdbe400
JB
13176static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
13177 struct netlink_callback *cb,
13178 struct cfg80211_registered_device **rdev,
13179 struct wireless_dev **wdev)
13180{
50508d94 13181 struct nlattr **attrbuf;
7bdbe400
JB
13182 u32 vid, subcmd;
13183 unsigned int i;
13184 int vcmd_idx = -1;
13185 int err;
13186 void *data = NULL;
13187 unsigned int data_len = 0;
13188
7bdbe400
JB
13189 if (cb->args[0]) {
13190 /* subtract the 1 again here */
13191 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
13192 struct wireless_dev *tmp;
13193
ea90e0dc
JB
13194 if (!wiphy)
13195 return -ENODEV;
7bdbe400
JB
13196 *rdev = wiphy_to_rdev(wiphy);
13197 *wdev = NULL;
13198
13199 if (cb->args[1]) {
53873f13 13200 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
13201 if (tmp->identifier == cb->args[1] - 1) {
13202 *wdev = tmp;
13203 break;
13204 }
13205 }
13206 }
13207
13208 /* keep rtnl locked in successful case */
13209 return 0;
13210 }
13211
50508d94
JB
13212 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
13213 if (!attrbuf)
13214 return -ENOMEM;
13215
8cb08174
JB
13216 err = nlmsg_parse_deprecated(cb->nlh,
13217 GENL_HDRLEN + nl80211_fam.hdrsize,
13218 attrbuf, nl80211_fam.maxattr,
13219 nl80211_policy, NULL);
7bdbe400 13220 if (err)
50508d94 13221 goto out;
7bdbe400 13222
c90c39da 13223 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
50508d94
JB
13224 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
13225 err = -EINVAL;
13226 goto out;
13227 }
7bdbe400 13228
c90c39da 13229 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
7bdbe400
JB
13230 if (IS_ERR(*wdev))
13231 *wdev = NULL;
13232
c90c39da 13233 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
50508d94
JB
13234 if (IS_ERR(*rdev)) {
13235 err = PTR_ERR(*rdev);
13236 goto out;
13237 }
7bdbe400 13238
c90c39da
JB
13239 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
13240 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
13241
13242 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
13243 const struct wiphy_vendor_command *vcmd;
13244
13245 vcmd = &(*rdev)->wiphy.vendor_commands[i];
13246
13247 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
13248 continue;
13249
50508d94
JB
13250 if (!vcmd->dumpit) {
13251 err = -EOPNOTSUPP;
13252 goto out;
13253 }
7bdbe400
JB
13254
13255 vcmd_idx = i;
13256 break;
13257 }
13258
50508d94
JB
13259 if (vcmd_idx < 0) {
13260 err = -EOPNOTSUPP;
13261 goto out;
13262 }
7bdbe400 13263
c90c39da
JB
13264 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
13265 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
13266 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
13267
13268 err = nl80211_vendor_check_policy(
13269 &(*rdev)->wiphy.vendor_commands[vcmd_idx],
13270 attrbuf[NL80211_ATTR_VENDOR_DATA],
13271 cb->extack);
13272 if (err)
50508d94 13273 goto out;
7bdbe400
JB
13274 }
13275
13276 /* 0 is the first index - add 1 to parse only once */
13277 cb->args[0] = (*rdev)->wiphy_idx + 1;
13278 /* add 1 to know if it was NULL */
13279 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
13280 cb->args[2] = vcmd_idx;
13281 cb->args[3] = (unsigned long)data;
13282 cb->args[4] = data_len;
13283
13284 /* keep rtnl locked in successful case */
50508d94
JB
13285 err = 0;
13286out:
13287 kfree(attrbuf);
13288 return err;
7bdbe400
JB
13289}
13290
13291static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
13292 struct netlink_callback *cb)
13293{
13294 struct cfg80211_registered_device *rdev;
13295 struct wireless_dev *wdev;
13296 unsigned int vcmd_idx;
13297 const struct wiphy_vendor_command *vcmd;
13298 void *data;
13299 int data_len;
13300 int err;
13301 struct nlattr *vendor_data;
13302
ea90e0dc 13303 rtnl_lock();
7bdbe400
JB
13304 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
13305 if (err)
ea90e0dc 13306 goto out;
7bdbe400
JB
13307
13308 vcmd_idx = cb->args[2];
13309 data = (void *)cb->args[3];
13310 data_len = cb->args[4];
13311 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
13312
13313 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
13314 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
13315 if (!wdev) {
13316 err = -EINVAL;
13317 goto out;
13318 }
7bdbe400 13319 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
13320 !wdev->netdev) {
13321 err = -EINVAL;
13322 goto out;
13323 }
7bdbe400
JB
13324
13325 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
13326 if (!wdev_running(wdev)) {
13327 err = -ENETDOWN;
13328 goto out;
13329 }
7bdbe400
JB
13330 }
13331 }
13332
13333 while (1) {
13334 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
13335 cb->nlh->nlmsg_seq, NLM_F_MULTI,
13336 NL80211_CMD_VENDOR);
13337 if (!hdr)
13338 break;
13339
13340 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
13341 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
13342 wdev_id(wdev),
13343 NL80211_ATTR_PAD))) {
7bdbe400
JB
13344 genlmsg_cancel(skb, hdr);
13345 break;
13346 }
13347
ae0be8de
MK
13348 vendor_data = nla_nest_start_noflag(skb,
13349 NL80211_ATTR_VENDOR_DATA);
7bdbe400
JB
13350 if (!vendor_data) {
13351 genlmsg_cancel(skb, hdr);
13352 break;
13353 }
13354
13355 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
13356 (unsigned long *)&cb->args[5]);
13357 nla_nest_end(skb, vendor_data);
13358
13359 if (err == -ENOBUFS || err == -ENOENT) {
13360 genlmsg_cancel(skb, hdr);
13361 break;
13362 } else if (err) {
13363 genlmsg_cancel(skb, hdr);
13364 goto out;
13365 }
13366
13367 genlmsg_end(skb, hdr);
13368 }
13369
13370 err = skb->len;
13371 out:
13372 rtnl_unlock();
13373 return err;
13374}
13375
ad7e718c
JB
13376struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
13377 enum nl80211_commands cmd,
13378 enum nl80211_attrs attr,
13379 int approxlen)
13380{
f26cbf40 13381 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
13382
13383 if (WARN_ON(!rdev->cur_cmd_info))
13384 return NULL;
13385
6c09e791 13386 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
13387 rdev->cur_cmd_info->snd_portid,
13388 rdev->cur_cmd_info->snd_seq,
567ffc35 13389 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
13390}
13391EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
13392
13393int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
13394{
13395 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
13396 void *hdr = ((void **)skb->cb)[1];
13397 struct nlattr *data = ((void **)skb->cb)[2];
13398
bd8c78e7
JB
13399 /* clear CB data for netlink core to own from now on */
13400 memset(skb->cb, 0, sizeof(skb->cb));
13401
ad7e718c
JB
13402 if (WARN_ON(!rdev->cur_cmd_info)) {
13403 kfree_skb(skb);
13404 return -EINVAL;
13405 }
13406
13407 nla_nest_end(skb, data);
13408 genlmsg_end(skb, hdr);
13409 return genlmsg_reply(skb, rdev->cur_cmd_info);
13410}
13411EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
13412
55c1fdf0
JB
13413unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy)
13414{
13415 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13416
13417 if (WARN_ON(!rdev->cur_cmd_info))
13418 return 0;
13419
13420 return rdev->cur_cmd_info->snd_portid;
13421}
13422EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender);
13423
fa9ffc74
KP
13424static int nl80211_set_qos_map(struct sk_buff *skb,
13425 struct genl_info *info)
13426{
13427 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13428 struct cfg80211_qos_map *qos_map = NULL;
13429 struct net_device *dev = info->user_ptr[1];
13430 u8 *pos, len, num_des, des_len, des;
13431 int ret;
13432
13433 if (!rdev->ops->set_qos_map)
13434 return -EOPNOTSUPP;
13435
13436 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
13437 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
13438 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
13439
13440 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
13441 len > IEEE80211_QOS_MAP_LEN_MAX)
13442 return -EINVAL;
13443
13444 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
13445 if (!qos_map)
13446 return -ENOMEM;
13447
13448 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
13449 if (num_des) {
13450 des_len = num_des *
13451 sizeof(struct cfg80211_dscp_exception);
13452 memcpy(qos_map->dscp_exception, pos, des_len);
13453 qos_map->num_des = num_des;
13454 for (des = 0; des < num_des; des++) {
13455 if (qos_map->dscp_exception[des].up > 7) {
13456 kfree(qos_map);
13457 return -EINVAL;
13458 }
13459 }
13460 pos += des_len;
13461 }
13462 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
13463 }
13464
13465 wdev_lock(dev->ieee80211_ptr);
13466 ret = nl80211_key_allowed(dev->ieee80211_ptr);
13467 if (!ret)
13468 ret = rdev_set_qos_map(rdev, dev, qos_map);
13469 wdev_unlock(dev->ieee80211_ptr);
13470
13471 kfree(qos_map);
13472 return ret;
13473}
13474
960d01ac
JB
13475static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
13476{
13477 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13478 struct net_device *dev = info->user_ptr[1];
13479 struct wireless_dev *wdev = dev->ieee80211_ptr;
13480 const u8 *peer;
13481 u8 tsid, up;
13482 u16 admitted_time = 0;
13483 int err;
13484
723e73ac 13485 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
13486 return -EOPNOTSUPP;
13487
13488 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
13489 !info->attrs[NL80211_ATTR_USER_PRIO])
13490 return -EINVAL;
13491
13492 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
960d01ac 13493 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
960d01ac
JB
13494
13495 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 13496 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 13497 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
13498 * need more attributes for that (e.g. BA session requirement);
13499 * change the WMM adminssion test above to allow both then
960d01ac
JB
13500 */
13501 return -EINVAL;
13502 }
13503
13504 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
13505
13506 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
13507 admitted_time =
13508 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
13509 if (!admitted_time)
13510 return -EINVAL;
13511 }
13512
13513 wdev_lock(wdev);
13514 switch (wdev->iftype) {
13515 case NL80211_IFTYPE_STATION:
13516 case NL80211_IFTYPE_P2P_CLIENT:
13517 if (wdev->current_bss)
13518 break;
13519 err = -ENOTCONN;
13520 goto out;
13521 default:
13522 err = -EOPNOTSUPP;
13523 goto out;
13524 }
13525
13526 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
13527
13528 out:
13529 wdev_unlock(wdev);
13530 return err;
13531}
13532
13533static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
13534{
13535 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13536 struct net_device *dev = info->user_ptr[1];
13537 struct wireless_dev *wdev = dev->ieee80211_ptr;
13538 const u8 *peer;
13539 u8 tsid;
13540 int err;
13541
13542 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
13543 return -EINVAL;
13544
13545 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
13546 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
13547
13548 wdev_lock(wdev);
13549 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
13550 wdev_unlock(wdev);
13551
13552 return err;
13553}
13554
1057d35e
AN
13555static int nl80211_tdls_channel_switch(struct sk_buff *skb,
13556 struct genl_info *info)
13557{
13558 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13559 struct net_device *dev = info->user_ptr[1];
13560 struct wireless_dev *wdev = dev->ieee80211_ptr;
13561 struct cfg80211_chan_def chandef = {};
13562 const u8 *addr;
13563 u8 oper_class;
13564 int err;
13565
13566 if (!rdev->ops->tdls_channel_switch ||
13567 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
13568 return -EOPNOTSUPP;
13569
13570 switch (dev->ieee80211_ptr->iftype) {
13571 case NL80211_IFTYPE_STATION:
13572 case NL80211_IFTYPE_P2P_CLIENT:
13573 break;
13574 default:
13575 return -EOPNOTSUPP;
13576 }
13577
13578 if (!info->attrs[NL80211_ATTR_MAC] ||
13579 !info->attrs[NL80211_ATTR_OPER_CLASS])
13580 return -EINVAL;
13581
13582 err = nl80211_parse_chandef(rdev, info, &chandef);
13583 if (err)
13584 return err;
13585
13586 /*
13587 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
13588 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
13589 * specification is not defined for them.
13590 */
57fbcce3 13591 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
13592 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
13593 chandef.width != NL80211_CHAN_WIDTH_20)
13594 return -EINVAL;
13595
13596 /* we will be active on the TDLS link */
923b352f
AN
13597 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
13598 wdev->iftype))
1057d35e
AN
13599 return -EINVAL;
13600
13601 /* don't allow switching to DFS channels */
13602 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
13603 return -EINVAL;
13604
13605 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
13606 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
13607
13608 wdev_lock(wdev);
13609 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
13610 wdev_unlock(wdev);
13611
13612 return err;
13613}
13614
13615static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
13616 struct genl_info *info)
13617{
13618 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13619 struct net_device *dev = info->user_ptr[1];
13620 struct wireless_dev *wdev = dev->ieee80211_ptr;
13621 const u8 *addr;
13622
13623 if (!rdev->ops->tdls_channel_switch ||
13624 !rdev->ops->tdls_cancel_channel_switch ||
13625 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
13626 return -EOPNOTSUPP;
13627
13628 switch (dev->ieee80211_ptr->iftype) {
13629 case NL80211_IFTYPE_STATION:
13630 case NL80211_IFTYPE_P2P_CLIENT:
13631 break;
13632 default:
13633 return -EOPNOTSUPP;
13634 }
13635
13636 if (!info->attrs[NL80211_ATTR_MAC])
13637 return -EINVAL;
13638
13639 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
13640
13641 wdev_lock(wdev);
13642 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
13643 wdev_unlock(wdev);
13644
13645 return 0;
13646}
13647
ce0ce13a
MB
13648static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
13649 struct genl_info *info)
13650{
13651 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13652 struct net_device *dev = info->user_ptr[1];
13653 struct wireless_dev *wdev = dev->ieee80211_ptr;
13654 const struct nlattr *nla;
13655 bool enabled;
13656
ce0ce13a
MB
13657 if (!rdev->ops->set_multicast_to_unicast)
13658 return -EOPNOTSUPP;
13659
13660 if (wdev->iftype != NL80211_IFTYPE_AP &&
13661 wdev->iftype != NL80211_IFTYPE_P2P_GO)
13662 return -EOPNOTSUPP;
13663
13664 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
13665 enabled = nla_get_flag(nla);
13666
13667 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
13668}
13669
3a00df57
AS
13670static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
13671{
13672 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13673 struct net_device *dev = info->user_ptr[1];
13674 struct wireless_dev *wdev = dev->ieee80211_ptr;
13675 struct cfg80211_pmk_conf pmk_conf = {};
13676 int ret;
13677
13678 if (wdev->iftype != NL80211_IFTYPE_STATION &&
13679 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
13680 return -EOPNOTSUPP;
13681
13682 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13683 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
13684 return -EOPNOTSUPP;
13685
13686 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
13687 return -EINVAL;
13688
13689 wdev_lock(wdev);
13690 if (!wdev->current_bss) {
13691 ret = -ENOTCONN;
13692 goto out;
13693 }
13694
13695 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
13696 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
13697 ret = -EINVAL;
13698 goto out;
13699 }
13700
13701 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
13702 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
13703 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
13704 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
13705 ret = -EINVAL;
13706 goto out;
13707 }
13708
13709 if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
13710 int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
13711
13712 if (r0_name_len != WLAN_PMK_NAME_LEN) {
13713 ret = -EINVAL;
13714 goto out;
13715 }
13716
13717 pmk_conf.pmk_r0_name =
13718 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
13719 }
13720
13721 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
13722out:
13723 wdev_unlock(wdev);
13724 return ret;
13725}
13726
13727static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
13728{
13729 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13730 struct net_device *dev = info->user_ptr[1];
13731 struct wireless_dev *wdev = dev->ieee80211_ptr;
13732 const u8 *aa;
13733 int ret;
13734
13735 if (wdev->iftype != NL80211_IFTYPE_STATION &&
13736 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
13737 return -EOPNOTSUPP;
13738
13739 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13740 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
13741 return -EOPNOTSUPP;
13742
13743 if (!info->attrs[NL80211_ATTR_MAC])
13744 return -EINVAL;
13745
13746 wdev_lock(wdev);
13747 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
13748 ret = rdev_del_pmk(rdev, dev, aa);
13749 wdev_unlock(wdev);
13750
13751 return ret;
13752}
13753
40cbfa90
SD
13754static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
13755{
13756 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13757 struct net_device *dev = info->user_ptr[1];
13758 struct cfg80211_external_auth_params params;
13759
db8d93a7 13760 if (!rdev->ops->external_auth)
40cbfa90
SD
13761 return -EOPNOTSUPP;
13762
fe494370
SD
13763 if (!info->attrs[NL80211_ATTR_SSID] &&
13764 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
13765 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
40cbfa90
SD
13766 return -EINVAL;
13767
13768 if (!info->attrs[NL80211_ATTR_BSSID])
13769 return -EINVAL;
13770
13771 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
13772 return -EINVAL;
13773
13774 memset(&params, 0, sizeof(params));
13775
fe494370
SD
13776 if (info->attrs[NL80211_ATTR_SSID]) {
13777 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
13778 if (params.ssid.ssid_len == 0 ||
13779 params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
13780 return -EINVAL;
13781 memcpy(params.ssid.ssid,
13782 nla_data(info->attrs[NL80211_ATTR_SSID]),
13783 params.ssid.ssid_len);
13784 }
40cbfa90
SD
13785
13786 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
13787 ETH_ALEN);
13788
13789 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
13790
fe494370
SD
13791 if (info->attrs[NL80211_ATTR_PMKID])
13792 params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
13793
40cbfa90
SD
13794 return rdev_external_auth(rdev, dev, &params);
13795}
13796
2576a9ac
DK
13797static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
13798{
13799 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13800 struct net_device *dev = info->user_ptr[1];
13801 struct wireless_dev *wdev = dev->ieee80211_ptr;
13802 const u8 *buf;
13803 size_t len;
13804 u8 *dest;
13805 u16 proto;
13806 bool noencrypt;
13807 int err;
13808
13809 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13810 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
13811 return -EOPNOTSUPP;
13812
13813 if (!rdev->ops->tx_control_port)
13814 return -EOPNOTSUPP;
13815
13816 if (!info->attrs[NL80211_ATTR_FRAME] ||
13817 !info->attrs[NL80211_ATTR_MAC] ||
13818 !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
13819 GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
13820 return -EINVAL;
13821 }
13822
13823 wdev_lock(wdev);
13824
13825 switch (wdev->iftype) {
13826 case NL80211_IFTYPE_AP:
13827 case NL80211_IFTYPE_P2P_GO:
13828 case NL80211_IFTYPE_MESH_POINT:
13829 break;
13830 case NL80211_IFTYPE_ADHOC:
13831 case NL80211_IFTYPE_STATION:
13832 case NL80211_IFTYPE_P2P_CLIENT:
13833 if (wdev->current_bss)
13834 break;
13835 err = -ENOTCONN;
13836 goto out;
13837 default:
13838 err = -EOPNOTSUPP;
13839 goto out;
13840 }
13841
13842 wdev_unlock(wdev);
13843
13844 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
13845 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
13846 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
13847 proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
13848 noencrypt =
13849 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
13850
13851 return rdev_tx_control_port(rdev, dev, buf, len,
8d74a623 13852 dest, cpu_to_be16(proto), noencrypt);
2576a9ac
DK
13853
13854 out:
13855 wdev_unlock(wdev);
13856 return err;
13857}
13858
81e54d08
PKC
13859static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
13860 struct genl_info *info)
13861{
13862 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13863 struct net_device *dev = info->user_ptr[1];
13864 struct wireless_dev *wdev = dev->ieee80211_ptr;
13865 struct cfg80211_ftm_responder_stats ftm_stats = {};
13866 struct sk_buff *msg;
13867 void *hdr;
13868 struct nlattr *ftm_stats_attr;
13869 int err;
13870
13871 if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval)
13872 return -EOPNOTSUPP;
13873
13874 err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
13875 if (err)
13876 return err;
13877
13878 if (!ftm_stats.filled)
13879 return -ENODATA;
13880
13881 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13882 if (!msg)
13883 return -ENOMEM;
13884
13885 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13886 NL80211_CMD_GET_FTM_RESPONDER_STATS);
13887 if (!hdr)
1399c59f 13888 goto nla_put_failure;
81e54d08
PKC
13889
13890 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
13891 goto nla_put_failure;
13892
ae0be8de
MK
13893 ftm_stats_attr = nla_nest_start_noflag(msg,
13894 NL80211_ATTR_FTM_RESPONDER_STATS);
81e54d08
PKC
13895 if (!ftm_stats_attr)
13896 goto nla_put_failure;
13897
13898#define SET_FTM(field, name, type) \
13899 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
13900 nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name, \
13901 ftm_stats.field)) \
13902 goto nla_put_failure; } while (0)
13903#define SET_FTM_U64(field, name) \
13904 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
13905 nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name, \
13906 ftm_stats.field, NL80211_FTM_STATS_PAD)) \
13907 goto nla_put_failure; } while (0)
13908
13909 SET_FTM(success_num, SUCCESS_NUM, u32);
13910 SET_FTM(partial_num, PARTIAL_NUM, u32);
13911 SET_FTM(failed_num, FAILED_NUM, u32);
13912 SET_FTM(asap_num, ASAP_NUM, u32);
13913 SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
13914 SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
13915 SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
13916 SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
13917 SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
13918#undef SET_FTM
13919
13920 nla_nest_end(msg, ftm_stats_attr);
13921
13922 genlmsg_end(msg, hdr);
13923 return genlmsg_reply(msg, info);
13924
13925nla_put_failure:
13926 nlmsg_free(msg);
13927 return -ENOBUFS;
13928}
13929
cb74e977
SD
13930static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
13931{
13932 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13933 struct cfg80211_update_owe_info owe_info;
13934 struct net_device *dev = info->user_ptr[1];
13935
13936 if (!rdev->ops->update_owe_info)
13937 return -EOPNOTSUPP;
13938
13939 if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
13940 !info->attrs[NL80211_ATTR_MAC])
13941 return -EINVAL;
13942
13943 memset(&owe_info, 0, sizeof(owe_info));
13944 owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
13945 nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
13946
13947 if (info->attrs[NL80211_ATTR_IE]) {
13948 owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
13949 owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
13950 }
13951
13952 return rdev_update_owe_info(rdev, dev, &owe_info);
13953}
13954
5ab92e7f
RM
13955static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
13956{
13957 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13958 struct net_device *dev = info->user_ptr[1];
13959 struct wireless_dev *wdev = dev->ieee80211_ptr;
13960 struct station_info sinfo = {};
13961 const u8 *buf;
13962 size_t len;
13963 u8 *dest;
13964 int err;
13965
13966 if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
13967 return -EOPNOTSUPP;
13968
13969 if (!info->attrs[NL80211_ATTR_MAC] ||
13970 !info->attrs[NL80211_ATTR_FRAME]) {
13971 GENL_SET_ERR_MSG(info, "Frame or MAC missing");
13972 return -EINVAL;
13973 }
13974
13975 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
13976 return -EOPNOTSUPP;
13977
13978 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
13979 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
13980 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
13981
13982 if (len < sizeof(struct ethhdr))
13983 return -EINVAL;
13984
13985 if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
13986 !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
13987 return -EINVAL;
13988
13989 err = rdev_get_station(rdev, dev, dest, &sinfo);
13990 if (err)
13991 return err;
13992
2a279b34
FF
13993 cfg80211_sinfo_release_content(&sinfo);
13994
5ab92e7f
RM
13995 return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
13996}
13997
77f576de
T
13998static int parse_tid_conf(struct cfg80211_registered_device *rdev,
13999 struct nlattr *attrs[], struct net_device *dev,
3710a8a6 14000 struct cfg80211_tid_cfg *tid_conf,
77f576de
T
14001 struct genl_info *info, const u8 *peer)
14002{
14003 struct netlink_ext_ack *extack = info->extack;
3710a8a6 14004 u64 mask;
77f576de
T
14005 int err;
14006
14007 if (!attrs[NL80211_TID_CONFIG_ATTR_TIDS])
14008 return -EINVAL;
14009
14010 tid_conf->config_override =
14011 nla_get_flag(attrs[NL80211_TID_CONFIG_ATTR_OVERRIDE]);
3710a8a6 14012 tid_conf->tids = nla_get_u16(attrs[NL80211_TID_CONFIG_ATTR_TIDS]);
77f576de
T
14013
14014 if (tid_conf->config_override) {
14015 if (rdev->ops->reset_tid_config) {
14016 err = rdev_reset_tid_config(rdev, dev, peer,
3710a8a6 14017 tid_conf->tids);
77f576de
T
14018 /* If peer is there no other configuration will be
14019 * allowed
14020 */
14021 if (err || peer)
14022 return err;
14023 } else {
14024 return -EINVAL;
14025 }
14026 }
14027
14028 if (attrs[NL80211_TID_CONFIG_ATTR_NOACK]) {
3710a8a6 14029 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_NOACK);
77f576de
T
14030 tid_conf->noack =
14031 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_NOACK]);
14032 }
14033
6a21d16c
T
14034 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]) {
14035 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT);
14036 tid_conf->retry_short =
14037 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]);
14038
14039 if (tid_conf->retry_short > rdev->wiphy.max_data_retry_count)
14040 return -EINVAL;
14041 }
14042
14043 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]) {
14044 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
14045 tid_conf->retry_long =
14046 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]);
14047
14048 if (tid_conf->retry_long > rdev->wiphy.max_data_retry_count)
14049 return -EINVAL;
14050 }
14051
ade274b2
T
14052 if (attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]) {
14053 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
14054 tid_conf->ampdu =
14055 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]);
14056 }
14057
3710a8a6
JB
14058 if (peer)
14059 mask = rdev->wiphy.tid_config_support.peer;
14060 else
14061 mask = rdev->wiphy.tid_config_support.vif;
14062
14063 if (tid_conf->mask & ~mask) {
14064 NL_SET_ERR_MSG(extack, "unsupported TID configuration");
14065 return -ENOTSUPP;
14066 }
14067
77f576de
T
14068 return 0;
14069}
14070
14071static int nl80211_set_tid_config(struct sk_buff *skb,
14072 struct genl_info *info)
14073{
14074 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14075 struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1];
14076 struct net_device *dev = info->user_ptr[1];
3710a8a6 14077 struct cfg80211_tid_config *tid_config;
77f576de
T
14078 struct nlattr *tid;
14079 int conf_idx = 0, rem_conf;
14080 int ret = -EINVAL;
14081 u32 num_conf = 0;
14082
14083 if (!info->attrs[NL80211_ATTR_TID_CONFIG])
14084 return -EINVAL;
14085
14086 if (!rdev->ops->set_tid_config)
14087 return -EOPNOTSUPP;
14088
14089 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
14090 rem_conf)
14091 num_conf++;
14092
14093 tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf),
14094 GFP_KERNEL);
14095 if (!tid_config)
14096 return -ENOMEM;
14097
14098 tid_config->n_tid_conf = num_conf;
14099
14100 if (info->attrs[NL80211_ATTR_MAC])
14101 tid_config->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14102
14103 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
14104 rem_conf) {
14105 ret = nla_parse_nested(attrs, NL80211_TID_CONFIG_ATTR_MAX,
14106 tid, NULL, NULL);
14107
14108 if (ret)
14109 goto bad_tid_conf;
14110
14111 ret = parse_tid_conf(rdev, attrs, dev,
14112 &tid_config->tid_conf[conf_idx],
14113 info, tid_config->peer);
14114 if (ret)
14115 goto bad_tid_conf;
14116
14117 conf_idx++;
14118 }
14119
14120 ret = rdev_set_tid_config(rdev, dev, tid_config);
14121
14122bad_tid_conf:
14123 kfree(tid_config);
14124 return ret;
14125}
14126
4c476991
JB
14127#define NL80211_FLAG_NEED_WIPHY 0x01
14128#define NL80211_FLAG_NEED_NETDEV 0x02
14129#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
14130#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
14131#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
14132 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 14133#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 14134/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
14135#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
14136 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 14137#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 14138
f84f771d 14139static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
14140 struct genl_info *info)
14141{
14142 struct cfg80211_registered_device *rdev;
89a54e48 14143 struct wireless_dev *wdev;
4c476991 14144 struct net_device *dev;
4c476991
JB
14145 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
14146
14147 if (rtnl)
14148 rtnl_lock();
14149
14150 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 14151 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
14152 if (IS_ERR(rdev)) {
14153 if (rtnl)
14154 rtnl_unlock();
14155 return PTR_ERR(rdev);
14156 }
14157 info->user_ptr[0] = rdev;
1bf614ef
JB
14158 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
14159 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
14160 ASSERT_RTNL();
14161
89a54e48
JB
14162 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
14163 info->attrs);
14164 if (IS_ERR(wdev)) {
4c476991
JB
14165 if (rtnl)
14166 rtnl_unlock();
89a54e48 14167 return PTR_ERR(wdev);
4c476991 14168 }
89a54e48 14169
89a54e48 14170 dev = wdev->netdev;
f26cbf40 14171 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 14172
1bf614ef
JB
14173 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
14174 if (!dev) {
1bf614ef
JB
14175 if (rtnl)
14176 rtnl_unlock();
14177 return -EINVAL;
14178 }
14179
14180 info->user_ptr[1] = dev;
14181 } else {
14182 info->user_ptr[1] = wdev;
41265714 14183 }
1bf614ef 14184
73c7da3d
AVS
14185 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
14186 !wdev_running(wdev)) {
14187 if (rtnl)
14188 rtnl_unlock();
14189 return -ENETDOWN;
14190 }
1bf614ef 14191
73c7da3d 14192 if (dev)
1bf614ef 14193 dev_hold(dev);
89a54e48 14194
4c476991 14195 info->user_ptr[0] = rdev;
4c476991
JB
14196 }
14197
14198 return 0;
14199}
14200
f84f771d 14201static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
14202 struct genl_info *info)
14203{
1bf614ef
JB
14204 if (info->user_ptr[1]) {
14205 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
14206 struct wireless_dev *wdev = info->user_ptr[1];
14207
14208 if (wdev->netdev)
14209 dev_put(wdev->netdev);
14210 } else {
14211 dev_put(info->user_ptr[1]);
14212 }
14213 }
5393b917 14214
4c476991
JB
14215 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
14216 rtnl_unlock();
5393b917
JB
14217
14218 /* If needed, clear the netlink message payload from the SKB
14219 * as it might contain key data that shouldn't stick around on
14220 * the heap after the SKB is freed. The netlink message header
14221 * is still needed for further processing, so leave it intact.
14222 */
14223 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
14224 struct nlmsghdr *nlh = nlmsg_hdr(skb);
14225
14226 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
14227 }
4c476991
JB
14228}
14229
4534de83 14230static const struct genl_ops nl80211_ops[] = {
55682965
JB
14231 {
14232 .cmd = NL80211_CMD_GET_WIPHY,
ef6243ac 14233 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
14234 .doit = nl80211_get_wiphy,
14235 .dumpit = nl80211_dump_wiphy,
86e8cf98 14236 .done = nl80211_dump_wiphy_done,
55682965 14237 /* can be retrieved by unprivileged users */
5fe231e8
JB
14238 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14239 NL80211_FLAG_NEED_RTNL,
55682965
JB
14240 },
14241 {
14242 .cmd = NL80211_CMD_SET_WIPHY,
ef6243ac 14243 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 14244 .doit = nl80211_set_wiphy,
5617c6cd 14245 .flags = GENL_UNS_ADMIN_PERM,
4c476991 14246 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
14247 },
14248 {
14249 .cmd = NL80211_CMD_GET_INTERFACE,
ef6243ac 14250 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
14251 .doit = nl80211_get_interface,
14252 .dumpit = nl80211_dump_interface,
55682965 14253 /* can be retrieved by unprivileged users */
5fe231e8
JB
14254 .internal_flags = NL80211_FLAG_NEED_WDEV |
14255 NL80211_FLAG_NEED_RTNL,
55682965
JB
14256 },
14257 {
14258 .cmd = NL80211_CMD_SET_INTERFACE,
ef6243ac 14259 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 14260 .doit = nl80211_set_interface,
5617c6cd 14261 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14262 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14263 NL80211_FLAG_NEED_RTNL,
55682965
JB
14264 },
14265 {
14266 .cmd = NL80211_CMD_NEW_INTERFACE,
ef6243ac 14267 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 14268 .doit = nl80211_new_interface,
5617c6cd 14269 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14270 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14271 NL80211_FLAG_NEED_RTNL,
55682965
JB
14272 },
14273 {
14274 .cmd = NL80211_CMD_DEL_INTERFACE,
ef6243ac 14275 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 14276 .doit = nl80211_del_interface,
5617c6cd 14277 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 14278 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 14279 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
14280 },
14281 {
14282 .cmd = NL80211_CMD_GET_KEY,
ef6243ac 14283 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 14284 .doit = nl80211_get_key,
5617c6cd 14285 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14286 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14287 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
14288 },
14289 {
14290 .cmd = NL80211_CMD_SET_KEY,
ef6243ac 14291 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 14292 .doit = nl80211_set_key,
5617c6cd 14293 .flags = GENL_UNS_ADMIN_PERM,
41265714 14294 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
14295 NL80211_FLAG_NEED_RTNL |
14296 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
14297 },
14298 {
14299 .cmd = NL80211_CMD_NEW_KEY,
ef6243ac 14300 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 14301 .doit = nl80211_new_key,
5617c6cd 14302 .flags = GENL_UNS_ADMIN_PERM,
41265714 14303 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
14304 NL80211_FLAG_NEED_RTNL |
14305 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
14306 },
14307 {
14308 .cmd = NL80211_CMD_DEL_KEY,
ef6243ac 14309 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 14310 .doit = nl80211_del_key,
5617c6cd 14311 .flags = GENL_UNS_ADMIN_PERM,
41265714 14312 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14313 NL80211_FLAG_NEED_RTNL,
55682965 14314 },
ed1b6cc7
JB
14315 {
14316 .cmd = NL80211_CMD_SET_BEACON,
ef6243ac 14317 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 14318 .flags = GENL_UNS_ADMIN_PERM,
8860020e 14319 .doit = nl80211_set_beacon,
2b5f8b0b 14320 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14321 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
14322 },
14323 {
8860020e 14324 .cmd = NL80211_CMD_START_AP,
ef6243ac 14325 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 14326 .flags = GENL_UNS_ADMIN_PERM,
8860020e 14327 .doit = nl80211_start_ap,
2b5f8b0b 14328 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14329 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
14330 },
14331 {
8860020e 14332 .cmd = NL80211_CMD_STOP_AP,
ef6243ac 14333 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 14334 .flags = GENL_UNS_ADMIN_PERM,
8860020e 14335 .doit = nl80211_stop_ap,
2b5f8b0b 14336 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14337 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 14338 },
5727ef1b
JB
14339 {
14340 .cmd = NL80211_CMD_GET_STATION,
ef6243ac 14341 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 14342 .doit = nl80211_get_station,
2ec600d6 14343 .dumpit = nl80211_dump_station,
4c476991
JB
14344 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14345 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
14346 },
14347 {
14348 .cmd = NL80211_CMD_SET_STATION,
ef6243ac 14349 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 14350 .doit = nl80211_set_station,
5617c6cd 14351 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14352 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14353 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
14354 },
14355 {
14356 .cmd = NL80211_CMD_NEW_STATION,
ef6243ac 14357 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 14358 .doit = nl80211_new_station,
5617c6cd 14359 .flags = GENL_UNS_ADMIN_PERM,
41265714 14360 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14361 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
14362 },
14363 {
14364 .cmd = NL80211_CMD_DEL_STATION,
ef6243ac 14365 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 14366 .doit = nl80211_del_station,
5617c6cd 14367 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14368 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14369 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
14370 },
14371 {
14372 .cmd = NL80211_CMD_GET_MPATH,
ef6243ac 14373 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6
LCC
14374 .doit = nl80211_get_mpath,
14375 .dumpit = nl80211_dump_mpath,
5617c6cd 14376 .flags = GENL_UNS_ADMIN_PERM,
41265714 14377 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14378 NL80211_FLAG_NEED_RTNL,
2ec600d6 14379 },
66be7d2b
HR
14380 {
14381 .cmd = NL80211_CMD_GET_MPP,
ef6243ac 14382 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
66be7d2b
HR
14383 .doit = nl80211_get_mpp,
14384 .dumpit = nl80211_dump_mpp,
5617c6cd 14385 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
14386 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14387 NL80211_FLAG_NEED_RTNL,
14388 },
2ec600d6
LCC
14389 {
14390 .cmd = NL80211_CMD_SET_MPATH,
ef6243ac 14391 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 14392 .doit = nl80211_set_mpath,
5617c6cd 14393 .flags = GENL_UNS_ADMIN_PERM,
41265714 14394 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14395 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
14396 },
14397 {
14398 .cmd = NL80211_CMD_NEW_MPATH,
ef6243ac 14399 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 14400 .doit = nl80211_new_mpath,
5617c6cd 14401 .flags = GENL_UNS_ADMIN_PERM,
41265714 14402 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14403 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
14404 },
14405 {
14406 .cmd = NL80211_CMD_DEL_MPATH,
ef6243ac 14407 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 14408 .doit = nl80211_del_mpath,
5617c6cd 14409 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14410 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14411 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
14412 },
14413 {
14414 .cmd = NL80211_CMD_SET_BSS,
ef6243ac 14415 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9f1ba906 14416 .doit = nl80211_set_bss,
5617c6cd 14417 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14418 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14419 NL80211_FLAG_NEED_RTNL,
b2e1b302 14420 },
f130347c
LR
14421 {
14422 .cmd = NL80211_CMD_GET_REG,
ef6243ac 14423 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad30ca2c
AN
14424 .doit = nl80211_get_reg_do,
14425 .dumpit = nl80211_get_reg_dump,
5fe231e8 14426 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
14427 /* can be retrieved by unprivileged users */
14428 },
b6863036 14429#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
14430 {
14431 .cmd = NL80211_CMD_SET_REG,
ef6243ac 14432 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 14433 .doit = nl80211_set_reg,
b2e1b302 14434 .flags = GENL_ADMIN_PERM,
5fe231e8 14435 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 14436 },
b6863036 14437#endif
b2e1b302
LR
14438 {
14439 .cmd = NL80211_CMD_REQ_SET_REG,
ef6243ac 14440 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 14441 .doit = nl80211_req_set_reg,
93da9cc1 14442 .flags = GENL_ADMIN_PERM,
14443 },
1ea4ff3e
JB
14444 {
14445 .cmd = NL80211_CMD_RELOAD_REGDB,
ef6243ac 14446 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1ea4ff3e 14447 .doit = nl80211_reload_regdb,
1ea4ff3e
JB
14448 .flags = GENL_ADMIN_PERM,
14449 },
93da9cc1 14450 {
24bdd9f4 14451 .cmd = NL80211_CMD_GET_MESH_CONFIG,
ef6243ac 14452 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 14453 .doit = nl80211_get_mesh_config,
93da9cc1 14454 /* can be retrieved by unprivileged users */
2b5f8b0b 14455 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14456 NL80211_FLAG_NEED_RTNL,
93da9cc1 14457 },
14458 {
24bdd9f4 14459 .cmd = NL80211_CMD_SET_MESH_CONFIG,
ef6243ac 14460 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 14461 .doit = nl80211_update_mesh_config,
5617c6cd 14462 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 14463 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14464 NL80211_FLAG_NEED_RTNL,
9aed3cc1 14465 },
2a519311
JB
14466 {
14467 .cmd = NL80211_CMD_TRIGGER_SCAN,
ef6243ac 14468 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311 14469 .doit = nl80211_trigger_scan,
5617c6cd 14470 .flags = GENL_UNS_ADMIN_PERM,
fd014284 14471 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 14472 NL80211_FLAG_NEED_RTNL,
2a519311 14473 },
91d3ab46
VK
14474 {
14475 .cmd = NL80211_CMD_ABORT_SCAN,
ef6243ac 14476 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
91d3ab46 14477 .doit = nl80211_abort_scan,
5617c6cd 14478 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
14479 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14480 NL80211_FLAG_NEED_RTNL,
14481 },
2a519311
JB
14482 {
14483 .cmd = NL80211_CMD_GET_SCAN,
ef6243ac 14484 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311
JB
14485 .dumpit = nl80211_dump_scan,
14486 },
807f8a8c
LC
14487 {
14488 .cmd = NL80211_CMD_START_SCHED_SCAN,
ef6243ac 14489 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 14490 .doit = nl80211_start_sched_scan,
5617c6cd 14491 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
14492 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14493 NL80211_FLAG_NEED_RTNL,
14494 },
14495 {
14496 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
ef6243ac 14497 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 14498 .doit = nl80211_stop_sched_scan,
5617c6cd 14499 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
14500 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14501 NL80211_FLAG_NEED_RTNL,
14502 },
636a5d36
JM
14503 {
14504 .cmd = NL80211_CMD_AUTHENTICATE,
ef6243ac 14505 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 14506 .doit = nl80211_authenticate,
5617c6cd 14507 .flags = GENL_UNS_ADMIN_PERM,
41265714 14508 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
14509 NL80211_FLAG_NEED_RTNL |
14510 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
14511 },
14512 {
14513 .cmd = NL80211_CMD_ASSOCIATE,
ef6243ac 14514 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 14515 .doit = nl80211_associate,
5617c6cd 14516 .flags = GENL_UNS_ADMIN_PERM,
41265714 14517 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
14518 NL80211_FLAG_NEED_RTNL |
14519 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
14520 },
14521 {
14522 .cmd = NL80211_CMD_DEAUTHENTICATE,
ef6243ac 14523 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 14524 .doit = nl80211_deauthenticate,
5617c6cd 14525 .flags = GENL_UNS_ADMIN_PERM,
41265714 14526 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14527 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
14528 },
14529 {
14530 .cmd = NL80211_CMD_DISASSOCIATE,
ef6243ac 14531 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 14532 .doit = nl80211_disassociate,
5617c6cd 14533 .flags = GENL_UNS_ADMIN_PERM,
41265714 14534 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14535 NL80211_FLAG_NEED_RTNL,
636a5d36 14536 },
04a773ad
JB
14537 {
14538 .cmd = NL80211_CMD_JOIN_IBSS,
ef6243ac 14539 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 14540 .doit = nl80211_join_ibss,
5617c6cd 14541 .flags = GENL_UNS_ADMIN_PERM,
41265714 14542 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14543 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
14544 },
14545 {
14546 .cmd = NL80211_CMD_LEAVE_IBSS,
ef6243ac 14547 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 14548 .doit = nl80211_leave_ibss,
5617c6cd 14549 .flags = GENL_UNS_ADMIN_PERM,
41265714 14550 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14551 NL80211_FLAG_NEED_RTNL,
04a773ad 14552 },
aff89a9b
JB
14553#ifdef CONFIG_NL80211_TESTMODE
14554 {
14555 .cmd = NL80211_CMD_TESTMODE,
ef6243ac 14556 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
aff89a9b 14557 .doit = nl80211_testmode_do,
71063f0e 14558 .dumpit = nl80211_testmode_dump,
5617c6cd 14559 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14560 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14561 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
14562 },
14563#endif
b23aa676
SO
14564 {
14565 .cmd = NL80211_CMD_CONNECT,
ef6243ac 14566 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 14567 .doit = nl80211_connect,
5617c6cd 14568 .flags = GENL_UNS_ADMIN_PERM,
41265714 14569 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
14570 NL80211_FLAG_NEED_RTNL |
14571 NL80211_FLAG_CLEAR_SKB,
b23aa676 14572 },
088e8df8 14573 {
14574 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
ef6243ac 14575 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
088e8df8 14576 .doit = nl80211_update_connect_params,
088e8df8 14577 .flags = GENL_ADMIN_PERM,
14578 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
14579 NL80211_FLAG_NEED_RTNL |
14580 NL80211_FLAG_CLEAR_SKB,
088e8df8 14581 },
b23aa676
SO
14582 {
14583 .cmd = NL80211_CMD_DISCONNECT,
ef6243ac 14584 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 14585 .doit = nl80211_disconnect,
5617c6cd 14586 .flags = GENL_UNS_ADMIN_PERM,
41265714 14587 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14588 NL80211_FLAG_NEED_RTNL,
b23aa676 14589 },
463d0183
JB
14590 {
14591 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
ef6243ac 14592 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
463d0183 14593 .doit = nl80211_wiphy_netns,
5617c6cd 14594 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14595 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14596 NL80211_FLAG_NEED_RTNL,
463d0183 14597 },
61fa713c
HS
14598 {
14599 .cmd = NL80211_CMD_GET_SURVEY,
ef6243ac 14600 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
61fa713c
HS
14601 .dumpit = nl80211_dump_survey,
14602 },
67fbb16b
SO
14603 {
14604 .cmd = NL80211_CMD_SET_PMKSA,
ef6243ac 14605 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 14606 .doit = nl80211_setdel_pmksa,
5617c6cd 14607 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14608 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
14609 NL80211_FLAG_NEED_RTNL |
14610 NL80211_FLAG_CLEAR_SKB,
67fbb16b
SO
14611 },
14612 {
14613 .cmd = NL80211_CMD_DEL_PMKSA,
ef6243ac 14614 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 14615 .doit = nl80211_setdel_pmksa,
5617c6cd 14616 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14617 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14618 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
14619 },
14620 {
14621 .cmd = NL80211_CMD_FLUSH_PMKSA,
ef6243ac 14622 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 14623 .doit = nl80211_flush_pmksa,
5617c6cd 14624 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14625 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 14626 NL80211_FLAG_NEED_RTNL,
67fbb16b 14627 },
9588bbd5
JM
14628 {
14629 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
ef6243ac 14630 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 14631 .doit = nl80211_remain_on_channel,
5617c6cd 14632 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14633 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 14634 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
14635 },
14636 {
14637 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
ef6243ac 14638 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 14639 .doit = nl80211_cancel_remain_on_channel,
5617c6cd 14640 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14641 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 14642 NL80211_FLAG_NEED_RTNL,
9588bbd5 14643 },
13ae75b1
JM
14644 {
14645 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
ef6243ac 14646 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
13ae75b1 14647 .doit = nl80211_set_tx_bitrate_mask,
5617c6cd 14648 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14649 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14650 NL80211_FLAG_NEED_RTNL,
13ae75b1 14651 },
026331c4 14652 {
2e161f78 14653 .cmd = NL80211_CMD_REGISTER_FRAME,
ef6243ac 14654 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 14655 .doit = nl80211_register_mgmt,
5617c6cd 14656 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14657 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 14658 NL80211_FLAG_NEED_RTNL,
026331c4
JM
14659 },
14660 {
2e161f78 14661 .cmd = NL80211_CMD_FRAME,
ef6243ac 14662 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 14663 .doit = nl80211_tx_mgmt,
5617c6cd 14664 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14665 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
14666 NL80211_FLAG_NEED_RTNL,
14667 },
14668 {
14669 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
ef6243ac 14670 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f7ca38df 14671 .doit = nl80211_tx_mgmt_cancel_wait,
5617c6cd 14672 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14673 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 14674 NL80211_FLAG_NEED_RTNL,
026331c4 14675 },
ffb9eb3d
KV
14676 {
14677 .cmd = NL80211_CMD_SET_POWER_SAVE,
ef6243ac 14678 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 14679 .doit = nl80211_set_power_save,
5617c6cd 14680 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14681 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14682 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
14683 },
14684 {
14685 .cmd = NL80211_CMD_GET_POWER_SAVE,
ef6243ac 14686 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 14687 .doit = nl80211_get_power_save,
ffb9eb3d 14688 /* can be retrieved by unprivileged users */
4c476991
JB
14689 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14690 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 14691 },
d6dc1a38
JO
14692 {
14693 .cmd = NL80211_CMD_SET_CQM,
ef6243ac 14694 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
d6dc1a38 14695 .doit = nl80211_set_cqm,
5617c6cd 14696 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14697 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14698 NL80211_FLAG_NEED_RTNL,
d6dc1a38 14699 },
f444de05
JB
14700 {
14701 .cmd = NL80211_CMD_SET_CHANNEL,
ef6243ac 14702 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f444de05 14703 .doit = nl80211_set_channel,
5617c6cd 14704 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14705 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14706 NL80211_FLAG_NEED_RTNL,
f444de05 14707 },
e8347eba
BJ
14708 {
14709 .cmd = NL80211_CMD_SET_WDS_PEER,
ef6243ac 14710 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
e8347eba 14711 .doit = nl80211_set_wds_peer,
5617c6cd 14712 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
14713 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14714 NL80211_FLAG_NEED_RTNL,
e8347eba 14715 },
29cbe68c
JB
14716 {
14717 .cmd = NL80211_CMD_JOIN_MESH,
ef6243ac 14718 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 14719 .doit = nl80211_join_mesh,
5617c6cd 14720 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
14721 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14722 NL80211_FLAG_NEED_RTNL,
14723 },
14724 {
14725 .cmd = NL80211_CMD_LEAVE_MESH,
ef6243ac 14726 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 14727 .doit = nl80211_leave_mesh,
5617c6cd 14728 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
14729 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14730 NL80211_FLAG_NEED_RTNL,
14731 },
6e0bd6c3
RL
14732 {
14733 .cmd = NL80211_CMD_JOIN_OCB,
ef6243ac 14734 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 14735 .doit = nl80211_join_ocb,
5617c6cd 14736 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
14737 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14738 NL80211_FLAG_NEED_RTNL,
14739 },
14740 {
14741 .cmd = NL80211_CMD_LEAVE_OCB,
ef6243ac 14742 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 14743 .doit = nl80211_leave_ocb,
5617c6cd 14744 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
14745 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14746 NL80211_FLAG_NEED_RTNL,
14747 },
dfb89c56 14748#ifdef CONFIG_PM
ff1b6e69
JB
14749 {
14750 .cmd = NL80211_CMD_GET_WOWLAN,
ef6243ac 14751 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 14752 .doit = nl80211_get_wowlan,
ff1b6e69
JB
14753 /* can be retrieved by unprivileged users */
14754 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14755 NL80211_FLAG_NEED_RTNL,
14756 },
14757 {
14758 .cmd = NL80211_CMD_SET_WOWLAN,
ef6243ac 14759 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 14760 .doit = nl80211_set_wowlan,
5617c6cd 14761 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
14762 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14763 NL80211_FLAG_NEED_RTNL,
14764 },
dfb89c56 14765#endif
e5497d76
JB
14766 {
14767 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
ef6243ac 14768 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
e5497d76 14769 .doit = nl80211_set_rekey_data,
5617c6cd 14770 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 14771 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
14772 NL80211_FLAG_NEED_RTNL |
14773 NL80211_FLAG_CLEAR_SKB,
e5497d76 14774 },
109086ce
AN
14775 {
14776 .cmd = NL80211_CMD_TDLS_MGMT,
ef6243ac 14777 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 14778 .doit = nl80211_tdls_mgmt,
5617c6cd 14779 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
14780 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14781 NL80211_FLAG_NEED_RTNL,
14782 },
14783 {
14784 .cmd = NL80211_CMD_TDLS_OPER,
ef6243ac 14785 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 14786 .doit = nl80211_tdls_oper,
5617c6cd 14787 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
14788 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14789 NL80211_FLAG_NEED_RTNL,
14790 },
28946da7
JB
14791 {
14792 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
ef6243ac 14793 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
28946da7 14794 .doit = nl80211_register_unexpected_frame,
5617c6cd 14795 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
14796 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14797 NL80211_FLAG_NEED_RTNL,
14798 },
7f6cf311
JB
14799 {
14800 .cmd = NL80211_CMD_PROBE_CLIENT,
ef6243ac 14801 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7f6cf311 14802 .doit = nl80211_probe_client,
5617c6cd 14803 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14804 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
14805 NL80211_FLAG_NEED_RTNL,
14806 },
5e760230
JB
14807 {
14808 .cmd = NL80211_CMD_REGISTER_BEACONS,
ef6243ac 14809 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5e760230 14810 .doit = nl80211_register_beacons,
5617c6cd 14811 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
14812 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14813 NL80211_FLAG_NEED_RTNL,
14814 },
1d9d9213
SW
14815 {
14816 .cmd = NL80211_CMD_SET_NOACK_MAP,
ef6243ac 14817 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1d9d9213 14818 .doit = nl80211_set_noack_map,
5617c6cd 14819 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
14820 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14821 NL80211_FLAG_NEED_RTNL,
14822 },
98104fde
JB
14823 {
14824 .cmd = NL80211_CMD_START_P2P_DEVICE,
ef6243ac 14825 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 14826 .doit = nl80211_start_p2p_device,
5617c6cd 14827 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
14828 .internal_flags = NL80211_FLAG_NEED_WDEV |
14829 NL80211_FLAG_NEED_RTNL,
14830 },
14831 {
14832 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
ef6243ac 14833 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 14834 .doit = nl80211_stop_p2p_device,
5617c6cd 14835 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
14836 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14837 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
14838 },
14839 {
14840 .cmd = NL80211_CMD_START_NAN,
ef6243ac 14841 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 14842 .doit = nl80211_start_nan,
cb3b7d87
AB
14843 .flags = GENL_ADMIN_PERM,
14844 .internal_flags = NL80211_FLAG_NEED_WDEV |
14845 NL80211_FLAG_NEED_RTNL,
14846 },
14847 {
14848 .cmd = NL80211_CMD_STOP_NAN,
ef6243ac 14849 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 14850 .doit = nl80211_stop_nan,
cb3b7d87
AB
14851 .flags = GENL_ADMIN_PERM,
14852 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14853 NL80211_FLAG_NEED_RTNL,
a442b761
AB
14854 },
14855 {
14856 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
ef6243ac 14857 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 14858 .doit = nl80211_nan_add_func,
a442b761
AB
14859 .flags = GENL_ADMIN_PERM,
14860 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14861 NL80211_FLAG_NEED_RTNL,
14862 },
14863 {
14864 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
ef6243ac 14865 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 14866 .doit = nl80211_nan_del_func,
a442b761
AB
14867 .flags = GENL_ADMIN_PERM,
14868 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14869 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
14870 },
14871 {
14872 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
ef6243ac 14873 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a5a9dcf2 14874 .doit = nl80211_nan_change_config,
a5a9dcf2
AB
14875 .flags = GENL_ADMIN_PERM,
14876 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14877 NL80211_FLAG_NEED_RTNL,
98104fde 14878 },
f4e583c8
AQ
14879 {
14880 .cmd = NL80211_CMD_SET_MCAST_RATE,
ef6243ac 14881 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f4e583c8 14882 .doit = nl80211_set_mcast_rate,
5617c6cd 14883 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
14884 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14885 NL80211_FLAG_NEED_RTNL,
14886 },
14887 {
14888 .cmd = NL80211_CMD_SET_MAC_ACL,
ef6243ac 14889 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
77765eaf 14890 .doit = nl80211_set_mac_acl,
5617c6cd 14891 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
14892 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14893 NL80211_FLAG_NEED_RTNL,
14894 },
04f39047
SW
14895 {
14896 .cmd = NL80211_CMD_RADAR_DETECT,
ef6243ac 14897 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04f39047 14898 .doit = nl80211_start_radar_detection,
5617c6cd 14899 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
14900 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14901 NL80211_FLAG_NEED_RTNL,
14902 },
3713b4e3
JB
14903 {
14904 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
ef6243ac 14905 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3713b4e3 14906 .doit = nl80211_get_protocol_features,
3713b4e3 14907 },
355199e0
JM
14908 {
14909 .cmd = NL80211_CMD_UPDATE_FT_IES,
ef6243ac 14910 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
355199e0 14911 .doit = nl80211_update_ft_ies,
5617c6cd 14912 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
14913 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14914 NL80211_FLAG_NEED_RTNL,
14915 },
5de17984
AS
14916 {
14917 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
ef6243ac 14918 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 14919 .doit = nl80211_crit_protocol_start,
5617c6cd 14920 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
14921 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14922 NL80211_FLAG_NEED_RTNL,
14923 },
14924 {
14925 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
ef6243ac 14926 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 14927 .doit = nl80211_crit_protocol_stop,
5617c6cd 14928 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
14929 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14930 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
14931 },
14932 {
14933 .cmd = NL80211_CMD_GET_COALESCE,
ef6243ac 14934 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 14935 .doit = nl80211_get_coalesce,
be29b99a
AK
14936 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14937 NL80211_FLAG_NEED_RTNL,
14938 },
14939 {
14940 .cmd = NL80211_CMD_SET_COALESCE,
ef6243ac 14941 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 14942 .doit = nl80211_set_coalesce,
5617c6cd 14943 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
14944 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14945 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
14946 },
14947 {
14948 .cmd = NL80211_CMD_CHANNEL_SWITCH,
ef6243ac 14949 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16ef1fe2 14950 .doit = nl80211_channel_switch,
5617c6cd 14951 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
14952 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14953 NL80211_FLAG_NEED_RTNL,
14954 },
ad7e718c
JB
14955 {
14956 .cmd = NL80211_CMD_VENDOR,
ef6243ac 14957 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad7e718c 14958 .doit = nl80211_vendor_cmd,
7bdbe400 14959 .dumpit = nl80211_vendor_cmd_dump,
5617c6cd 14960 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c 14961 .internal_flags = NL80211_FLAG_NEED_WIPHY |
d6db02a8
SD
14962 NL80211_FLAG_NEED_RTNL |
14963 NL80211_FLAG_CLEAR_SKB,
ad7e718c 14964 },
fa9ffc74
KP
14965 {
14966 .cmd = NL80211_CMD_SET_QOS_MAP,
ef6243ac 14967 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
fa9ffc74 14968 .doit = nl80211_set_qos_map,
5617c6cd 14969 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
14970 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14971 NL80211_FLAG_NEED_RTNL,
14972 },
960d01ac
JB
14973 {
14974 .cmd = NL80211_CMD_ADD_TX_TS,
ef6243ac 14975 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 14976 .doit = nl80211_add_tx_ts,
5617c6cd 14977 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
14978 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14979 NL80211_FLAG_NEED_RTNL,
14980 },
14981 {
14982 .cmd = NL80211_CMD_DEL_TX_TS,
ef6243ac 14983 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 14984 .doit = nl80211_del_tx_ts,
5617c6cd 14985 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
14986 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14987 NL80211_FLAG_NEED_RTNL,
14988 },
1057d35e
AN
14989 {
14990 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
ef6243ac 14991 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 14992 .doit = nl80211_tdls_channel_switch,
5617c6cd 14993 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
14994 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14995 NL80211_FLAG_NEED_RTNL,
14996 },
14997 {
14998 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
ef6243ac 14999 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 15000 .doit = nl80211_tdls_cancel_channel_switch,
5617c6cd 15001 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
15002 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
15003 NL80211_FLAG_NEED_RTNL,
15004 },
ce0ce13a
MB
15005 {
15006 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
ef6243ac 15007 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ce0ce13a 15008 .doit = nl80211_set_multicast_to_unicast,
ce0ce13a
MB
15009 .flags = GENL_UNS_ADMIN_PERM,
15010 .internal_flags = NL80211_FLAG_NEED_NETDEV |
15011 NL80211_FLAG_NEED_RTNL,
15012 },
3a00df57
AS
15013 {
15014 .cmd = NL80211_CMD_SET_PMK,
ef6243ac 15015 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 15016 .doit = nl80211_set_pmk,
3a00df57 15017 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
15018 NL80211_FLAG_NEED_RTNL |
15019 NL80211_FLAG_CLEAR_SKB,
3a00df57
AS
15020 },
15021 {
15022 .cmd = NL80211_CMD_DEL_PMK,
ef6243ac 15023 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 15024 .doit = nl80211_del_pmk,
3a00df57
AS
15025 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
15026 NL80211_FLAG_NEED_RTNL,
15027 },
40cbfa90
SD
15028 {
15029 .cmd = NL80211_CMD_EXTERNAL_AUTH,
ef6243ac 15030 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
40cbfa90 15031 .doit = nl80211_external_auth,
40cbfa90
SD
15032 .flags = GENL_ADMIN_PERM,
15033 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
15034 NL80211_FLAG_NEED_RTNL,
15035 },
2576a9ac
DK
15036 {
15037 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
ef6243ac 15038 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2576a9ac 15039 .doit = nl80211_tx_control_port,
2576a9ac
DK
15040 .flags = GENL_UNS_ADMIN_PERM,
15041 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
15042 NL80211_FLAG_NEED_RTNL,
15043 },
81e54d08
PKC
15044 {
15045 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
ef6243ac 15046 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
81e54d08 15047 .doit = nl80211_get_ftm_responder_stats,
81e54d08
PKC
15048 .internal_flags = NL80211_FLAG_NEED_NETDEV |
15049 NL80211_FLAG_NEED_RTNL,
15050 },
9bb7e0f2
JB
15051 {
15052 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
ef6243ac 15053 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9bb7e0f2 15054 .doit = nl80211_pmsr_start,
9bb7e0f2
JB
15055 .flags = GENL_UNS_ADMIN_PERM,
15056 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
15057 NL80211_FLAG_NEED_RTNL,
15058 },
30c63115
S
15059 {
15060 .cmd = NL80211_CMD_NOTIFY_RADAR,
ef6243ac 15061 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
30c63115 15062 .doit = nl80211_notify_radar_detection,
30c63115
S
15063 .flags = GENL_UNS_ADMIN_PERM,
15064 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
15065 NL80211_FLAG_NEED_RTNL,
15066 },
cb74e977
SD
15067 {
15068 .cmd = NL80211_CMD_UPDATE_OWE_INFO,
15069 .doit = nl80211_update_owe_info,
15070 .flags = GENL_ADMIN_PERM,
5ab92e7f
RM
15071 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
15072 NL80211_FLAG_NEED_RTNL,
15073 },
15074 {
15075 .cmd = NL80211_CMD_PROBE_MESH_LINK,
15076 .doit = nl80211_probe_mesh_link,
15077 .flags = GENL_UNS_ADMIN_PERM,
cb74e977
SD
15078 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
15079 NL80211_FLAG_NEED_RTNL,
15080 },
77f576de
T
15081 {
15082 .cmd = NL80211_CMD_SET_TID_CONFIG,
15083 .doit = nl80211_set_tid_config,
15084 .flags = GENL_UNS_ADMIN_PERM,
15085 .internal_flags = NL80211_FLAG_NEED_NETDEV |
15086 NL80211_FLAG_NEED_RTNL,
15087 },
55682965 15088};
9588bbd5 15089
56989f6d 15090static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
15091 .name = NL80211_GENL_NAME, /* have users key off the name instead */
15092 .hdrsize = 0, /* no private header */
15093 .version = 1, /* no particular meaning now */
15094 .maxattr = NL80211_ATTR_MAX,
3b0f31f2 15095 .policy = nl80211_policy,
489111e5
JB
15096 .netnsok = true,
15097 .pre_doit = nl80211_pre_doit,
15098 .post_doit = nl80211_post_doit,
15099 .module = THIS_MODULE,
15100 .ops = nl80211_ops,
15101 .n_ops = ARRAY_SIZE(nl80211_ops),
15102 .mcgrps = nl80211_mcgrps,
15103 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
50508d94 15104 .parallel_ops = true,
489111e5
JB
15105};
15106
55682965
JB
15107/* notification functions */
15108
3bb20556
JB
15109void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
15110 enum nl80211_commands cmd)
55682965
JB
15111{
15112 struct sk_buff *msg;
86e8cf98 15113 struct nl80211_dump_wiphy_state state = {};
55682965 15114
3bb20556
JB
15115 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
15116 cmd != NL80211_CMD_DEL_WIPHY);
15117
fd2120ca 15118 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
15119 if (!msg)
15120 return;
15121
3bb20556 15122 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
15123 nlmsg_free(msg);
15124 return;
15125 }
15126
68eb5503 15127 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15128 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
15129}
15130
896ff063
DK
15131void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
15132 struct wireless_dev *wdev,
15133 enum nl80211_commands cmd)
15134{
15135 struct sk_buff *msg;
15136
896ff063
DK
15137 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15138 if (!msg)
15139 return;
15140
3d1a5bbf 15141 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
896ff063
DK
15142 nlmsg_free(msg);
15143 return;
15144 }
15145
15146 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
15147 NL80211_MCGRP_CONFIG, GFP_KERNEL);
15148}
15149
362a415d
JB
15150static int nl80211_add_scan_req(struct sk_buff *msg,
15151 struct cfg80211_registered_device *rdev)
15152{
15153 struct cfg80211_scan_request *req = rdev->scan_req;
15154 struct nlattr *nest;
15155 int i;
15156
15157 if (WARN_ON(!req))
15158 return 0;
15159
ae0be8de 15160 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_SSIDS);
362a415d
JB
15161 if (!nest)
15162 goto nla_put_failure;
9360ffd1
DM
15163 for (i = 0; i < req->n_ssids; i++) {
15164 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
15165 goto nla_put_failure;
15166 }
362a415d
JB
15167 nla_nest_end(msg, nest);
15168
ae0be8de 15169 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
362a415d
JB
15170 if (!nest)
15171 goto nla_put_failure;
9360ffd1
DM
15172 for (i = 0; i < req->n_channels; i++) {
15173 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
15174 goto nla_put_failure;
15175 }
362a415d
JB
15176 nla_nest_end(msg, nest);
15177
9360ffd1
DM
15178 if (req->ie &&
15179 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
15180 goto nla_put_failure;
362a415d 15181
ae917c9f
JB
15182 if (req->flags &&
15183 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
15184 goto nla_put_failure;
ed473771 15185
1d76250b
AS
15186 if (req->info.scan_start_tsf &&
15187 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
15188 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
15189 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
15190 req->info.tsf_bssid)))
15191 goto nla_put_failure;
15192
362a415d
JB
15193 return 0;
15194 nla_put_failure:
15195 return -ENOBUFS;
15196}
15197
505a2e88 15198static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 15199 struct cfg80211_registered_device *rdev,
fd014284 15200 struct wireless_dev *wdev,
15e47304 15201 u32 portid, u32 seq, int flags,
a538e2d5 15202 u32 cmd)
2a519311
JB
15203{
15204 void *hdr;
15205
15e47304 15206 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
15207 if (!hdr)
15208 return -1;
15209
9360ffd1 15210 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
15211 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15212 wdev->netdev->ifindex)) ||
2dad624e
ND
15213 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15214 NL80211_ATTR_PAD))
9360ffd1 15215 goto nla_put_failure;
2a519311 15216
362a415d
JB
15217 /* ignore errors and send incomplete event anyway */
15218 nl80211_add_scan_req(msg, rdev);
2a519311 15219
053c095a
JB
15220 genlmsg_end(msg, hdr);
15221 return 0;
2a519311
JB
15222
15223 nla_put_failure:
15224 genlmsg_cancel(msg, hdr);
15225 return -EMSGSIZE;
15226}
15227
807f8a8c 15228static int
505a2e88 15229nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 15230 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
15231{
15232 void *hdr;
15233
96b08fd6 15234 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
15235 if (!hdr)
15236 return -1;
15237
96b08fd6
AVS
15238 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
15239 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
15240 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
15241 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
15242 NL80211_ATTR_PAD))
9360ffd1 15243 goto nla_put_failure;
807f8a8c 15244
053c095a
JB
15245 genlmsg_end(msg, hdr);
15246 return 0;
807f8a8c
LC
15247
15248 nla_put_failure:
15249 genlmsg_cancel(msg, hdr);
15250 return -EMSGSIZE;
15251}
15252
a538e2d5 15253void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 15254 struct wireless_dev *wdev)
a538e2d5
JB
15255{
15256 struct sk_buff *msg;
15257
58050fce 15258 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
15259 if (!msg)
15260 return;
15261
505a2e88 15262 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
15263 NL80211_CMD_TRIGGER_SCAN) < 0) {
15264 nlmsg_free(msg);
15265 return;
15266 }
15267
68eb5503 15268 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15269 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
15270}
15271
f9d15d16
JB
15272struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
15273 struct wireless_dev *wdev, bool aborted)
2a519311
JB
15274{
15275 struct sk_buff *msg;
15276
fd2120ca 15277 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 15278 if (!msg)
f9d15d16 15279 return NULL;
2a519311 15280
505a2e88 15281 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
15282 aborted ? NL80211_CMD_SCAN_ABORTED :
15283 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 15284 nlmsg_free(msg);
f9d15d16 15285 return NULL;
2a519311
JB
15286 }
15287
f9d15d16 15288 return msg;
2a519311
JB
15289}
15290
505a2e88
AVS
15291/* send message created by nl80211_build_scan_msg() */
15292void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
15293 struct sk_buff *msg)
807f8a8c 15294{
807f8a8c
LC
15295 if (!msg)
15296 return;
15297
68eb5503 15298 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15299 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
15300}
15301
96b08fd6 15302void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
15303{
15304 struct sk_buff *msg;
15305
58050fce 15306 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
15307 if (!msg)
15308 return;
15309
96b08fd6 15310 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
15311 nlmsg_free(msg);
15312 return;
15313 }
15314
96b08fd6 15315 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 15316 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
15317}
15318
b0d7aa59
JD
15319static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
15320 struct regulatory_request *request)
73d54c9e 15321{
73d54c9e 15322 /* Userspace can always count this one always being set */
9360ffd1
DM
15323 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
15324 goto nla_put_failure;
15325
15326 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
15327 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
15328 NL80211_REGDOM_TYPE_WORLD))
15329 goto nla_put_failure;
15330 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
15331 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
15332 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
15333 goto nla_put_failure;
15334 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
15335 request->intersect) {
15336 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
15337 NL80211_REGDOM_TYPE_INTERSECTION))
15338 goto nla_put_failure;
15339 } else {
15340 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
15341 NL80211_REGDOM_TYPE_COUNTRY) ||
15342 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
15343 request->alpha2))
15344 goto nla_put_failure;
15345 }
15346
ad30ca2c
AN
15347 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
15348 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
15349
15350 if (wiphy &&
15351 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
15352 goto nla_put_failure;
1bdd716c
AN
15353
15354 if (wiphy &&
15355 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
15356 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
15357 goto nla_put_failure;
ad30ca2c 15358 }
73d54c9e 15359
b0d7aa59
JD
15360 return true;
15361
15362nla_put_failure:
15363 return false;
15364}
15365
15366/*
15367 * This can happen on global regulatory changes or device specific settings
15368 * based on custom regulatory domains.
15369 */
15370void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
15371 struct regulatory_request *request)
15372{
15373 struct sk_buff *msg;
15374 void *hdr;
15375
15376 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15377 if (!msg)
15378 return;
15379
15380 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
24f6d765 15381 if (!hdr)
15382 goto nla_put_failure;
b0d7aa59 15383
24f6d765 15384 if (!nl80211_reg_change_event_fill(msg, request))
b0d7aa59
JD
15385 goto nla_put_failure;
15386
3b7b72ee 15387 genlmsg_end(msg, hdr);
73d54c9e 15388
bc43b28c 15389 rcu_read_lock();
68eb5503 15390 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 15391 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 15392 rcu_read_unlock();
73d54c9e
LR
15393
15394 return;
15395
15396nla_put_failure:
73d54c9e
LR
15397 nlmsg_free(msg);
15398}
15399
6039f6d2
JM
15400static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
15401 struct net_device *netdev,
15402 const u8 *buf, size_t len,
b0b6aa2c 15403 enum nl80211_commands cmd, gfp_t gfp,
4d9ec73d
JM
15404 int uapsd_queues, const u8 *req_ies,
15405 size_t req_ies_len)
6039f6d2
JM
15406{
15407 struct sk_buff *msg;
15408 void *hdr;
15409
4d9ec73d 15410 msg = nlmsg_new(100 + len + req_ies_len, gfp);
6039f6d2
JM
15411 if (!msg)
15412 return;
15413
15414 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
15415 if (!hdr) {
15416 nlmsg_free(msg);
15417 return;
15418 }
15419
9360ffd1
DM
15420 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15421 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
4d9ec73d
JM
15422 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
15423 (req_ies &&
15424 nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
9360ffd1 15425 goto nla_put_failure;
6039f6d2 15426
b0b6aa2c
EP
15427 if (uapsd_queues >= 0) {
15428 struct nlattr *nla_wmm =
ae0be8de 15429 nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
b0b6aa2c
EP
15430 if (!nla_wmm)
15431 goto nla_put_failure;
15432
15433 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
15434 uapsd_queues))
15435 goto nla_put_failure;
15436
15437 nla_nest_end(msg, nla_wmm);
15438 }
15439
3b7b72ee 15440 genlmsg_end(msg, hdr);
6039f6d2 15441
68eb5503 15442 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15443 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
15444 return;
15445
15446 nla_put_failure:
6039f6d2
JM
15447 nlmsg_free(msg);
15448}
15449
15450void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
15451 struct net_device *netdev, const u8 *buf,
15452 size_t len, gfp_t gfp)
6039f6d2
JM
15453{
15454 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 15455 NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0);
6039f6d2
JM
15456}
15457
15458void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
15459 struct net_device *netdev, const u8 *buf,
4d9ec73d
JM
15460 size_t len, gfp_t gfp, int uapsd_queues,
15461 const u8 *req_ies, size_t req_ies_len)
6039f6d2 15462{
e6d6e342 15463 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d
JM
15464 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
15465 req_ies, req_ies_len);
6039f6d2
JM
15466}
15467
53b46b84 15468void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
15469 struct net_device *netdev, const u8 *buf,
15470 size_t len, gfp_t gfp)
6039f6d2
JM
15471{
15472 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 15473 NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0);
6039f6d2
JM
15474}
15475
53b46b84
JM
15476void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
15477 struct net_device *netdev, const u8 *buf,
e6d6e342 15478 size_t len, gfp_t gfp)
6039f6d2
JM
15479{
15480 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 15481 NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0);
6039f6d2
JM
15482}
15483
6ff57cf8
JB
15484void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
15485 size_t len)
cf4e594e 15486{
947add36
JB
15487 struct wireless_dev *wdev = dev->ieee80211_ptr;
15488 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15489 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
15490 const struct ieee80211_mgmt *mgmt = (void *)buf;
15491 u32 cmd;
947add36 15492
6ff57cf8
JB
15493 if (WARN_ON(len < 2))
15494 return;
cf4e594e 15495
6ff57cf8
JB
15496 if (ieee80211_is_deauth(mgmt->frame_control))
15497 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
15498 else
15499 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 15500
6ff57cf8 15501 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
4d9ec73d
JM
15502 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
15503 NULL, 0);
cf4e594e 15504}
6ff57cf8 15505EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 15506
1b06bb40
LR
15507static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
15508 struct net_device *netdev, int cmd,
e6d6e342 15509 const u8 *addr, gfp_t gfp)
1965c853
JM
15510{
15511 struct sk_buff *msg;
15512 void *hdr;
15513
e6d6e342 15514 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
15515 if (!msg)
15516 return;
15517
15518 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
15519 if (!hdr) {
15520 nlmsg_free(msg);
15521 return;
15522 }
15523
9360ffd1
DM
15524 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15525 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15526 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
15527 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
15528 goto nla_put_failure;
1965c853 15529
3b7b72ee 15530 genlmsg_end(msg, hdr);
1965c853 15531
68eb5503 15532 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15533 NL80211_MCGRP_MLME, gfp);
1965c853
JM
15534 return;
15535
15536 nla_put_failure:
1965c853
JM
15537 nlmsg_free(msg);
15538}
15539
15540void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
15541 struct net_device *netdev, const u8 *addr,
15542 gfp_t gfp)
1965c853
JM
15543{
15544 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 15545 addr, gfp);
1965c853
JM
15546}
15547
15548void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
15549 struct net_device *netdev, const u8 *addr,
15550 gfp_t gfp)
1965c853 15551{
e6d6e342
JB
15552 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
15553 addr, gfp);
1965c853
JM
15554}
15555
b23aa676 15556void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
15557 struct net_device *netdev,
15558 struct cfg80211_connect_resp_params *cr,
3093ebbe 15559 gfp_t gfp)
b23aa676
SO
15560{
15561 struct sk_buff *msg;
15562 void *hdr;
15563
a3caf744 15564 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
76804d28
AVS
15565 cr->fils.kek_len + cr->fils.pmk_len +
15566 (cr->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
15567 if (!msg)
15568 return;
15569
15570 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
15571 if (!hdr) {
15572 nlmsg_free(msg);
15573 return;
15574 }
15575
9360ffd1
DM
15576 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15577 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
15578 (cr->bssid &&
15579 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 15580 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
15581 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
15582 cr->status) ||
15583 (cr->status < 0 &&
3093ebbe 15584 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
15585 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
15586 cr->timeout_reason))) ||
15587 (cr->req_ie &&
15588 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
15589 (cr->resp_ie &&
15590 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744 15591 cr->resp_ie)) ||
76804d28 15592 (cr->fils.update_erp_next_seq_num &&
a3caf744 15593 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
76804d28 15594 cr->fils.erp_next_seq_num)) ||
a3caf744 15595 (cr->status == WLAN_STATUS_SUCCESS &&
76804d28
AVS
15596 ((cr->fils.kek &&
15597 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
15598 cr->fils.kek)) ||
15599 (cr->fils.pmk &&
15600 nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
15601 (cr->fils.pmkid &&
15602 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
9360ffd1 15603 goto nla_put_failure;
b23aa676 15604
3b7b72ee 15605 genlmsg_end(msg, hdr);
b23aa676 15606
68eb5503 15607 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15608 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
15609 return;
15610
15611 nla_put_failure:
b23aa676 15612 nlmsg_free(msg);
b23aa676
SO
15613}
15614
15615void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
15616 struct net_device *netdev,
15617 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
15618{
15619 struct sk_buff *msg;
15620 void *hdr;
29ce6ecb 15621 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 15622
e841b7b1
AVS
15623 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
15624 info->fils.kek_len + info->fils.pmk_len +
15625 (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
15626 if (!msg)
15627 return;
15628
15629 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
15630 if (!hdr) {
15631 nlmsg_free(msg);
15632 return;
15633 }
15634
9360ffd1
DM
15635 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15636 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15637 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
15638 (info->req_ie &&
15639 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
15640 info->req_ie)) ||
15641 (info->resp_ie &&
15642 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
e841b7b1
AVS
15643 info->resp_ie)) ||
15644 (info->fils.update_erp_next_seq_num &&
15645 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
15646 info->fils.erp_next_seq_num)) ||
15647 (info->fils.kek &&
15648 nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
15649 info->fils.kek)) ||
15650 (info->fils.pmk &&
15651 nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
15652 (info->fils.pmkid &&
15653 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
9360ffd1 15654 goto nla_put_failure;
b23aa676 15655
3b7b72ee 15656 genlmsg_end(msg, hdr);
b23aa676 15657
68eb5503 15658 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15659 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
15660 return;
15661
503c1fb9 15662 nla_put_failure:
503c1fb9
AS
15663 nlmsg_free(msg);
15664}
15665
15666void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
15667 struct net_device *netdev, const u8 *bssid)
15668{
15669 struct sk_buff *msg;
15670 void *hdr;
15671
15672 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15673 if (!msg)
15674 return;
15675
15676 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
15677 if (!hdr) {
15678 nlmsg_free(msg);
15679 return;
15680 }
15681
f4d75993
CHH
15682 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15683 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15684 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
503c1fb9
AS
15685 goto nla_put_failure;
15686
15687 genlmsg_end(msg, hdr);
15688
15689 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
15690 NL80211_MCGRP_MLME, GFP_KERNEL);
15691 return;
15692
b23aa676 15693 nla_put_failure:
b23aa676 15694 nlmsg_free(msg);
b23aa676
SO
15695}
15696
15697void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
15698 struct net_device *netdev, u16 reason,
667503dd 15699 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
15700{
15701 struct sk_buff *msg;
15702 void *hdr;
15703
4ef8c1c9 15704 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
15705 if (!msg)
15706 return;
15707
15708 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
15709 if (!hdr) {
15710 nlmsg_free(msg);
15711 return;
15712 }
15713
9360ffd1
DM
15714 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15715 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
86b6c465 15716 (reason &&
9360ffd1
DM
15717 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
15718 (from_ap &&
15719 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
15720 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
15721 goto nla_put_failure;
b23aa676 15722
3b7b72ee 15723 genlmsg_end(msg, hdr);
b23aa676 15724
68eb5503 15725 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15726 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
15727 return;
15728
15729 nla_put_failure:
b23aa676 15730 nlmsg_free(msg);
b23aa676
SO
15731}
15732
04a773ad
JB
15733void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
15734 struct net_device *netdev, const u8 *bssid,
15735 gfp_t gfp)
15736{
15737 struct sk_buff *msg;
15738 void *hdr;
15739
fd2120ca 15740 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
15741 if (!msg)
15742 return;
15743
15744 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
15745 if (!hdr) {
15746 nlmsg_free(msg);
15747 return;
15748 }
15749
9360ffd1
DM
15750 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15751 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15752 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
15753 goto nla_put_failure;
04a773ad 15754
3b7b72ee 15755 genlmsg_end(msg, hdr);
04a773ad 15756
68eb5503 15757 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15758 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
15759 return;
15760
15761 nla_put_failure:
04a773ad
JB
15762 nlmsg_free(msg);
15763}
15764
947add36 15765void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
ecbc12ad
BC
15766 const u8 *ie, u8 ie_len,
15767 int sig_dbm, gfp_t gfp)
c93b5e71 15768{
947add36 15769 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15770 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
15771 struct sk_buff *msg;
15772 void *hdr;
15773
947add36
JB
15774 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
15775 return;
15776
15777 trace_cfg80211_notify_new_peer_candidate(dev, addr);
15778
4ef8c1c9 15779 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
15780 if (!msg)
15781 return;
15782
15783 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
15784 if (!hdr) {
15785 nlmsg_free(msg);
15786 return;
15787 }
15788
9360ffd1 15789 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
15790 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15791 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1 15792 (ie_len && ie &&
ecbc12ad
BC
15793 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
15794 (sig_dbm &&
15795 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
9360ffd1 15796 goto nla_put_failure;
c93b5e71 15797
3b7b72ee 15798 genlmsg_end(msg, hdr);
c93b5e71 15799
68eb5503 15800 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15801 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
15802 return;
15803
15804 nla_put_failure:
c93b5e71
JC
15805 nlmsg_free(msg);
15806}
947add36 15807EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 15808
a3b8b056
JM
15809void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
15810 struct net_device *netdev, const u8 *addr,
15811 enum nl80211_key_type key_type, int key_id,
e6d6e342 15812 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
15813{
15814 struct sk_buff *msg;
15815 void *hdr;
15816
e6d6e342 15817 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
15818 if (!msg)
15819 return;
15820
15821 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
15822 if (!hdr) {
15823 nlmsg_free(msg);
15824 return;
15825 }
15826
9360ffd1
DM
15827 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15828 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15829 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
15830 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
15831 (key_id != -1 &&
15832 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
15833 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
15834 goto nla_put_failure;
a3b8b056 15835
3b7b72ee 15836 genlmsg_end(msg, hdr);
a3b8b056 15837
68eb5503 15838 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15839 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
15840 return;
15841
15842 nla_put_failure:
a3b8b056
JM
15843 nlmsg_free(msg);
15844}
15845
6bad8766
LR
15846void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
15847 struct ieee80211_channel *channel_before,
15848 struct ieee80211_channel *channel_after)
15849{
15850 struct sk_buff *msg;
15851 void *hdr;
15852 struct nlattr *nl_freq;
15853
fd2120ca 15854 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
15855 if (!msg)
15856 return;
15857
15858 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
15859 if (!hdr) {
15860 nlmsg_free(msg);
15861 return;
15862 }
15863
15864 /*
15865 * Since we are applying the beacon hint to a wiphy we know its
15866 * wiphy_idx is valid
15867 */
9360ffd1
DM
15868 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
15869 goto nla_put_failure;
6bad8766
LR
15870
15871 /* Before */
ae0be8de 15872 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_BEFORE);
6bad8766
LR
15873 if (!nl_freq)
15874 goto nla_put_failure;
50f32718
HD
15875
15876 if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
6bad8766
LR
15877 goto nla_put_failure;
15878 nla_nest_end(msg, nl_freq);
15879
15880 /* After */
ae0be8de 15881 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_AFTER);
6bad8766
LR
15882 if (!nl_freq)
15883 goto nla_put_failure;
50f32718
HD
15884
15885 if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
6bad8766
LR
15886 goto nla_put_failure;
15887 nla_nest_end(msg, nl_freq);
15888
3b7b72ee 15889 genlmsg_end(msg, hdr);
6bad8766 15890
463d0183 15891 rcu_read_lock();
68eb5503 15892 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 15893 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 15894 rcu_read_unlock();
6bad8766
LR
15895
15896 return;
15897
15898nla_put_failure:
6bad8766
LR
15899 nlmsg_free(msg);
15900}
15901
9588bbd5
JM
15902static void nl80211_send_remain_on_chan_event(
15903 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 15904 struct wireless_dev *wdev, u64 cookie,
9588bbd5 15905 struct ieee80211_channel *chan,
9588bbd5
JM
15906 unsigned int duration, gfp_t gfp)
15907{
15908 struct sk_buff *msg;
15909 void *hdr;
15910
15911 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15912 if (!msg)
15913 return;
15914
15915 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
15916 if (!hdr) {
15917 nlmsg_free(msg);
15918 return;
15919 }
15920
9360ffd1 15921 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
15922 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15923 wdev->netdev->ifindex)) ||
2dad624e
ND
15924 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15925 NL80211_ATTR_PAD) ||
9360ffd1 15926 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
15927 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
15928 NL80211_CHAN_NO_HT) ||
2dad624e
ND
15929 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
15930 NL80211_ATTR_PAD))
9360ffd1 15931 goto nla_put_failure;
9588bbd5 15932
9360ffd1
DM
15933 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
15934 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
15935 goto nla_put_failure;
9588bbd5 15936
3b7b72ee 15937 genlmsg_end(msg, hdr);
9588bbd5 15938
68eb5503 15939 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15940 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
15941 return;
15942
15943 nla_put_failure:
9588bbd5
JM
15944 nlmsg_free(msg);
15945}
15946
947add36
JB
15947void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
15948 struct ieee80211_channel *chan,
15949 unsigned int duration, gfp_t gfp)
9588bbd5 15950{
947add36 15951 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15952 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15953
15954 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 15955 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 15956 rdev, wdev, cookie, chan,
42d97a59 15957 duration, gfp);
9588bbd5 15958}
947add36 15959EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 15960
947add36
JB
15961void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
15962 struct ieee80211_channel *chan,
15963 gfp_t gfp)
9588bbd5 15964{
947add36 15965 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15966 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15967
15968 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 15969 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 15970 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 15971}
947add36 15972EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 15973
1c38c7f2
JP
15974void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
15975 struct ieee80211_channel *chan,
15976 gfp_t gfp)
15977{
15978 struct wiphy *wiphy = wdev->wiphy;
15979 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
15980
15981 trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
15982 nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
15983 rdev, wdev, cookie, chan, 0, gfp);
15984}
15985EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
15986
947add36
JB
15987void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
15988 struct station_info *sinfo, gfp_t gfp)
98b62183 15989{
947add36 15990 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 15991 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
15992 struct sk_buff *msg;
15993
947add36
JB
15994 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
15995
58050fce 15996 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
15997 if (!msg)
15998 return;
15999
cf5ead82 16000 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 16001 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
16002 nlmsg_free(msg);
16003 return;
16004 }
16005
68eb5503 16006 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16007 NL80211_MCGRP_MLME, gfp);
98b62183 16008}
947add36 16009EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 16010
cf5ead82
JB
16011void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
16012 struct station_info *sinfo, gfp_t gfp)
ec15e68b 16013{
947add36 16014 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16015 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 16016 struct sk_buff *msg;
73887fd9 16017 struct station_info empty_sinfo = {};
cf5ead82 16018
73887fd9
JB
16019 if (!sinfo)
16020 sinfo = &empty_sinfo;
ec15e68b 16021
947add36
JB
16022 trace_cfg80211_del_sta(dev, mac_addr);
16023
58050fce 16024 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7ea3e110
JB
16025 if (!msg) {
16026 cfg80211_sinfo_release_content(sinfo);
73887fd9 16027 return;
7ea3e110 16028 }
ec15e68b 16029
cf5ead82 16030 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 16031 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b 16032 nlmsg_free(msg);
73887fd9 16033 return;
ec15e68b
JM
16034 }
16035
68eb5503 16036 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16037 NL80211_MCGRP_MLME, gfp);
ec15e68b 16038}
cf5ead82 16039EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 16040
947add36
JB
16041void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
16042 enum nl80211_connect_failed_reason reason,
16043 gfp_t gfp)
ed44a951 16044{
947add36 16045 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16046 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
16047 struct sk_buff *msg;
16048 void *hdr;
16049
16050 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
16051 if (!msg)
16052 return;
16053
16054 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
16055 if (!hdr) {
16056 nlmsg_free(msg);
16057 return;
16058 }
16059
16060 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16061 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
16062 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
16063 goto nla_put_failure;
16064
16065 genlmsg_end(msg, hdr);
16066
68eb5503 16067 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16068 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
16069 return;
16070
16071 nla_put_failure:
ed44a951
PP
16072 nlmsg_free(msg);
16073}
947add36 16074EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 16075
b92ab5d8
JB
16076static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
16077 const u8 *addr, gfp_t gfp)
28946da7
JB
16078{
16079 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16080 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
16081 struct sk_buff *msg;
16082 void *hdr;
6aa7de05 16083 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 16084
15e47304 16085 if (!nlportid)
28946da7
JB
16086 return false;
16087
16088 msg = nlmsg_new(100, gfp);
16089 if (!msg)
16090 return true;
16091
b92ab5d8 16092 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
16093 if (!hdr) {
16094 nlmsg_free(msg);
16095 return true;
16096 }
16097
9360ffd1
DM
16098 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16099 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16100 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
16101 goto nla_put_failure;
28946da7 16102
9c90a9f6 16103 genlmsg_end(msg, hdr);
15e47304 16104 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
16105 return true;
16106
16107 nla_put_failure:
28946da7
JB
16108 nlmsg_free(msg);
16109 return true;
16110}
16111
947add36
JB
16112bool cfg80211_rx_spurious_frame(struct net_device *dev,
16113 const u8 *addr, gfp_t gfp)
b92ab5d8 16114{
947add36
JB
16115 struct wireless_dev *wdev = dev->ieee80211_ptr;
16116 bool ret;
16117
16118 trace_cfg80211_rx_spurious_frame(dev, addr);
16119
16120 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
16121 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
16122 trace_cfg80211_return_bool(false);
16123 return false;
16124 }
16125 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
16126 addr, gfp);
16127 trace_cfg80211_return_bool(ret);
16128 return ret;
b92ab5d8 16129}
947add36 16130EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 16131
947add36
JB
16132bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
16133 const u8 *addr, gfp_t gfp)
b92ab5d8 16134{
947add36
JB
16135 struct wireless_dev *wdev = dev->ieee80211_ptr;
16136 bool ret;
16137
16138 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
16139
16140 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
16141 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
16142 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
16143 trace_cfg80211_return_bool(false);
16144 return false;
16145 }
16146 ret = __nl80211_unexpected_frame(dev,
16147 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
16148 addr, gfp);
16149 trace_cfg80211_return_bool(ret);
16150 return ret;
b92ab5d8 16151}
947add36 16152EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 16153
2e161f78 16154int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 16155 struct wireless_dev *wdev, u32 nlportid,
804483e9 16156 int freq, int sig_dbm,
19504cf5 16157 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 16158{
71bbc994 16159 struct net_device *netdev = wdev->netdev;
026331c4
JM
16160 struct sk_buff *msg;
16161 void *hdr;
026331c4 16162
4ef8c1c9 16163 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
16164 if (!msg)
16165 return -ENOMEM;
16166
2e161f78 16167 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
16168 if (!hdr) {
16169 nlmsg_free(msg);
16170 return -ENOMEM;
16171 }
16172
9360ffd1 16173 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16174 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16175 netdev->ifindex)) ||
2dad624e
ND
16176 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16177 NL80211_ATTR_PAD) ||
9360ffd1
DM
16178 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
16179 (sig_dbm &&
16180 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
16181 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
16182 (flags &&
16183 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 16184 goto nla_put_failure;
026331c4 16185
3b7b72ee 16186 genlmsg_end(msg, hdr);
026331c4 16187
15e47304 16188 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
16189
16190 nla_put_failure:
026331c4
JM
16191 nlmsg_free(msg);
16192 return -ENOBUFS;
16193}
16194
947add36
JB
16195void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
16196 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 16197{
947add36 16198 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16199 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 16200 struct net_device *netdev = wdev->netdev;
026331c4
JM
16201 struct sk_buff *msg;
16202 void *hdr;
16203
947add36
JB
16204 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
16205
4ef8c1c9 16206 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
16207 if (!msg)
16208 return;
16209
2e161f78 16210 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
16211 if (!hdr) {
16212 nlmsg_free(msg);
16213 return;
16214 }
16215
9360ffd1 16216 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16217 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16218 netdev->ifindex)) ||
2dad624e
ND
16219 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16220 NL80211_ATTR_PAD) ||
9360ffd1 16221 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
16222 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
16223 NL80211_ATTR_PAD) ||
9360ffd1
DM
16224 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
16225 goto nla_put_failure;
026331c4 16226
3b7b72ee 16227 genlmsg_end(msg, hdr);
026331c4 16228
68eb5503 16229 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16230 NL80211_MCGRP_MLME, gfp);
026331c4
JM
16231 return;
16232
16233 nla_put_failure:
026331c4
JM
16234 nlmsg_free(msg);
16235}
947add36 16236EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 16237
6a671a50 16238static int __nl80211_rx_control_port(struct net_device *dev,
a948f713 16239 struct sk_buff *skb,
6a671a50
DK
16240 bool unencrypted, gfp_t gfp)
16241{
16242 struct wireless_dev *wdev = dev->ieee80211_ptr;
16243 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
a948f713 16244 struct ethhdr *ehdr = eth_hdr(skb);
8d74a623 16245 const u8 *addr = ehdr->h_source;
a948f713 16246 u16 proto = be16_to_cpu(skb->protocol);
6a671a50
DK
16247 struct sk_buff *msg;
16248 void *hdr;
a948f713
DK
16249 struct nlattr *frame;
16250
6a671a50
DK
16251 u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
16252
16253 if (!nlportid)
16254 return -ENOENT;
16255
a948f713 16256 msg = nlmsg_new(100 + skb->len, gfp);
6a671a50
DK
16257 if (!msg)
16258 return -ENOMEM;
16259
16260 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
16261 if (!hdr) {
16262 nlmsg_free(msg);
16263 return -ENOBUFS;
16264 }
16265
16266 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16267 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16268 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16269 NL80211_ATTR_PAD) ||
8d74a623 16270 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
6a671a50
DK
16271 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
16272 (unencrypted && nla_put_flag(msg,
16273 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
16274 goto nla_put_failure;
16275
a948f713
DK
16276 frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
16277 if (!frame)
16278 goto nla_put_failure;
16279
16280 skb_copy_bits(skb, 0, nla_data(frame), skb->len);
6a671a50
DK
16281 genlmsg_end(msg, hdr);
16282
16283 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
16284
16285 nla_put_failure:
16286 nlmsg_free(msg);
16287 return -ENOBUFS;
16288}
16289
16290bool cfg80211_rx_control_port(struct net_device *dev,
a948f713 16291 struct sk_buff *skb, bool unencrypted)
6a671a50
DK
16292{
16293 int ret;
16294
a948f713
DK
16295 trace_cfg80211_rx_control_port(dev, skb, unencrypted);
16296 ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC);
6a671a50
DK
16297 trace_cfg80211_return_bool(ret == 0);
16298 return ret == 0;
16299}
16300EXPORT_SYMBOL(cfg80211_rx_control_port);
16301
5b97f49d
JB
16302static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
16303 const char *mac, gfp_t gfp)
d6dc1a38 16304{
947add36 16305 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
16306 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
16307 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16308 void **cb;
947add36 16309
d6dc1a38 16310 if (!msg)
5b97f49d 16311 return NULL;
d6dc1a38 16312
5b97f49d
JB
16313 cb = (void **)msg->cb;
16314
16315 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
16316 if (!cb[0]) {
d6dc1a38 16317 nlmsg_free(msg);
5b97f49d 16318 return NULL;
d6dc1a38
JO
16319 }
16320
9360ffd1 16321 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 16322 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 16323 goto nla_put_failure;
d6dc1a38 16324
5b97f49d 16325 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
16326 goto nla_put_failure;
16327
ae0be8de 16328 cb[1] = nla_nest_start_noflag(msg, NL80211_ATTR_CQM);
5b97f49d 16329 if (!cb[1])
9360ffd1 16330 goto nla_put_failure;
d6dc1a38 16331
5b97f49d 16332 cb[2] = rdev;
d6dc1a38 16333
5b97f49d
JB
16334 return msg;
16335 nla_put_failure:
16336 nlmsg_free(msg);
16337 return NULL;
16338}
16339
16340static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
16341{
16342 void **cb = (void **)msg->cb;
16343 struct cfg80211_registered_device *rdev = cb[2];
16344
16345 nla_nest_end(msg, cb[1]);
16346 genlmsg_end(msg, cb[0]);
16347
16348 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 16349
68eb5503 16350 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16351 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
16352}
16353
16354void cfg80211_cqm_rssi_notify(struct net_device *dev,
16355 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 16356 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
16357{
16358 struct sk_buff *msg;
4a4b8169
AZ
16359 struct wireless_dev *wdev = dev->ieee80211_ptr;
16360 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 16361
bee427b8 16362 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 16363
98f03342
JB
16364 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
16365 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
16366 return;
16367
4a4b8169
AZ
16368 if (wdev->cqm_config) {
16369 wdev->cqm_config->last_rssi_event_value = rssi_level;
16370
16371 cfg80211_cqm_rssi_update(rdev, dev);
16372
16373 if (rssi_level == 0)
16374 rssi_level = wdev->cqm_config->last_rssi_event_value;
16375 }
16376
5b97f49d
JB
16377 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
16378 if (!msg)
16379 return;
16380
16381 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
16382 rssi_event))
16383 goto nla_put_failure;
16384
bee427b8
AZ
16385 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
16386 rssi_level))
16387 goto nla_put_failure;
16388
5b97f49d
JB
16389 cfg80211_send_cqm(msg, gfp);
16390
d6dc1a38
JO
16391 return;
16392
16393 nla_put_failure:
d6dc1a38
JO
16394 nlmsg_free(msg);
16395}
947add36 16396EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 16397
5b97f49d
JB
16398void cfg80211_cqm_txe_notify(struct net_device *dev,
16399 const u8 *peer, u32 num_packets,
16400 u32 rate, u32 intvl, gfp_t gfp)
16401{
16402 struct sk_buff *msg;
16403
16404 msg = cfg80211_prepare_cqm(dev, peer, gfp);
16405 if (!msg)
16406 return;
16407
16408 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
16409 goto nla_put_failure;
16410
16411 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
16412 goto nla_put_failure;
16413
16414 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
16415 goto nla_put_failure;
16416
16417 cfg80211_send_cqm(msg, gfp);
16418 return;
16419
16420 nla_put_failure:
16421 nlmsg_free(msg);
16422}
16423EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
16424
16425void cfg80211_cqm_pktloss_notify(struct net_device *dev,
16426 const u8 *peer, u32 num_packets, gfp_t gfp)
16427{
16428 struct sk_buff *msg;
16429
16430 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
16431
16432 msg = cfg80211_prepare_cqm(dev, peer, gfp);
16433 if (!msg)
16434 return;
16435
16436 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
16437 goto nla_put_failure;
16438
16439 cfg80211_send_cqm(msg, gfp);
16440 return;
16441
16442 nla_put_failure:
16443 nlmsg_free(msg);
16444}
16445EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
16446
98f03342
JB
16447void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
16448{
16449 struct sk_buff *msg;
16450
16451 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
16452 if (!msg)
16453 return;
16454
16455 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
16456 goto nla_put_failure;
16457
16458 cfg80211_send_cqm(msg, gfp);
16459 return;
16460
16461 nla_put_failure:
16462 nlmsg_free(msg);
16463}
16464EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
16465
947add36
JB
16466static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
16467 struct net_device *netdev, const u8 *bssid,
16468 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
16469{
16470 struct sk_buff *msg;
16471 struct nlattr *rekey_attr;
16472 void *hdr;
16473
58050fce 16474 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
16475 if (!msg)
16476 return;
16477
16478 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
16479 if (!hdr) {
16480 nlmsg_free(msg);
16481 return;
16482 }
16483
9360ffd1
DM
16484 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16485 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16486 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
16487 goto nla_put_failure;
e5497d76 16488
ae0be8de 16489 rekey_attr = nla_nest_start_noflag(msg, NL80211_ATTR_REKEY_DATA);
e5497d76
JB
16490 if (!rekey_attr)
16491 goto nla_put_failure;
16492
9360ffd1
DM
16493 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
16494 NL80211_REPLAY_CTR_LEN, replay_ctr))
16495 goto nla_put_failure;
e5497d76
JB
16496
16497 nla_nest_end(msg, rekey_attr);
16498
3b7b72ee 16499 genlmsg_end(msg, hdr);
e5497d76 16500
68eb5503 16501 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16502 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
16503 return;
16504
16505 nla_put_failure:
e5497d76
JB
16506 nlmsg_free(msg);
16507}
16508
947add36
JB
16509void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
16510 const u8 *replay_ctr, gfp_t gfp)
16511{
16512 struct wireless_dev *wdev = dev->ieee80211_ptr;
16513 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16514 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
16515
16516 trace_cfg80211_gtk_rekey_notify(dev, bssid);
16517 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
16518}
16519EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
16520
16521static void
16522nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
16523 struct net_device *netdev, int index,
16524 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
16525{
16526 struct sk_buff *msg;
16527 struct nlattr *attr;
16528 void *hdr;
16529
58050fce 16530 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
16531 if (!msg)
16532 return;
16533
16534 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
16535 if (!hdr) {
16536 nlmsg_free(msg);
16537 return;
16538 }
16539
9360ffd1
DM
16540 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16541 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
16542 goto nla_put_failure;
c9df56b4 16543
ae0be8de 16544 attr = nla_nest_start_noflag(msg, NL80211_ATTR_PMKSA_CANDIDATE);
c9df56b4
JM
16545 if (!attr)
16546 goto nla_put_failure;
16547
9360ffd1
DM
16548 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
16549 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
16550 (preauth &&
16551 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
16552 goto nla_put_failure;
c9df56b4
JM
16553
16554 nla_nest_end(msg, attr);
16555
3b7b72ee 16556 genlmsg_end(msg, hdr);
c9df56b4 16557
68eb5503 16558 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16559 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
16560 return;
16561
16562 nla_put_failure:
c9df56b4
JM
16563 nlmsg_free(msg);
16564}
16565
947add36
JB
16566void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
16567 const u8 *bssid, bool preauth, gfp_t gfp)
16568{
16569 struct wireless_dev *wdev = dev->ieee80211_ptr;
16570 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16571 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
16572
16573 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
16574 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
16575}
16576EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
16577
16578static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
16579 struct net_device *netdev,
16580 struct cfg80211_chan_def *chandef,
f8d7552e
LC
16581 gfp_t gfp,
16582 enum nl80211_commands notif,
16583 u8 count)
5314526b
TP
16584{
16585 struct sk_buff *msg;
16586 void *hdr;
16587
58050fce 16588 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
16589 if (!msg)
16590 return;
16591
f8d7552e 16592 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
16593 if (!hdr) {
16594 nlmsg_free(msg);
16595 return;
16596 }
16597
683b6d3b
JB
16598 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
16599 goto nla_put_failure;
16600
16601 if (nl80211_send_chandef(msg, chandef))
7eab0f64 16602 goto nla_put_failure;
5314526b 16603
f8d7552e
LC
16604 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
16605 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
16606 goto nla_put_failure;
16607
5314526b
TP
16608 genlmsg_end(msg, hdr);
16609
68eb5503 16610 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16611 NL80211_MCGRP_MLME, gfp);
5314526b
TP
16612 return;
16613
16614 nla_put_failure:
5314526b
TP
16615 nlmsg_free(msg);
16616}
16617
947add36
JB
16618void cfg80211_ch_switch_notify(struct net_device *dev,
16619 struct cfg80211_chan_def *chandef)
84f10708 16620{
947add36
JB
16621 struct wireless_dev *wdev = dev->ieee80211_ptr;
16622 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16623 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 16624
e487eaeb 16625 ASSERT_WDEV_LOCK(wdev);
947add36 16626
e487eaeb 16627 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 16628
9e0e2961 16629 wdev->chandef = *chandef;
96f55f12 16630 wdev->preset_chandef = *chandef;
5dc8cdce
SM
16631
16632 if (wdev->iftype == NL80211_IFTYPE_STATION &&
16633 !WARN_ON(!wdev->current_bss))
0afd425b 16634 cfg80211_update_assoc_bss_entry(wdev, chandef->chan);
5dc8cdce 16635
d34990bb
MV
16636 cfg80211_sched_dfs_chan_update(rdev);
16637
f8d7552e
LC
16638 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
16639 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
16640}
16641EXPORT_SYMBOL(cfg80211_ch_switch_notify);
16642
f8d7552e
LC
16643void cfg80211_ch_switch_started_notify(struct net_device *dev,
16644 struct cfg80211_chan_def *chandef,
16645 u8 count)
16646{
16647 struct wireless_dev *wdev = dev->ieee80211_ptr;
16648 struct wiphy *wiphy = wdev->wiphy;
16649 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
16650
16651 trace_cfg80211_ch_switch_started_notify(dev, chandef);
16652
16653 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
16654 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
16655}
16656EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
16657
04f39047
SW
16658void
16659nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 16660 const struct cfg80211_chan_def *chandef,
04f39047
SW
16661 enum nl80211_radar_event event,
16662 struct net_device *netdev, gfp_t gfp)
16663{
16664 struct sk_buff *msg;
16665 void *hdr;
16666
16667 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16668 if (!msg)
16669 return;
16670
16671 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
16672 if (!hdr) {
16673 nlmsg_free(msg);
16674 return;
16675 }
16676
16677 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
16678 goto nla_put_failure;
16679
16680 /* NOP and radar events don't need a netdev parameter */
16681 if (netdev) {
16682 struct wireless_dev *wdev = netdev->ieee80211_ptr;
16683
16684 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
16685 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16686 NL80211_ATTR_PAD))
04f39047
SW
16687 goto nla_put_failure;
16688 }
16689
16690 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
16691 goto nla_put_failure;
16692
16693 if (nl80211_send_chandef(msg, chandef))
16694 goto nla_put_failure;
16695
9c90a9f6 16696 genlmsg_end(msg, hdr);
04f39047 16697
68eb5503 16698 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16699 NL80211_MCGRP_MLME, gfp);
04f39047
SW
16700 return;
16701
16702 nla_put_failure:
04f39047
SW
16703 nlmsg_free(msg);
16704}
16705
466b9936 16706void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
16707 struct sta_opmode_info *sta_opmode,
16708 gfp_t gfp)
16709{
16710 struct sk_buff *msg;
16711 struct wireless_dev *wdev = dev->ieee80211_ptr;
16712 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
16713 void *hdr;
16714
16715 if (WARN_ON(!mac))
16716 return;
16717
16718 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16719 if (!msg)
16720 return;
16721
16722 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
16723 if (!hdr) {
16724 nlmsg_free(msg);
16725 return;
16726 }
16727
16728 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
16729 goto nla_put_failure;
16730
16731 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
16732 goto nla_put_failure;
16733
16734 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
16735 goto nla_put_failure;
16736
16737 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
16738 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
16739 goto nla_put_failure;
16740
16741 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
16742 nla_put_u8(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
16743 goto nla_put_failure;
16744
16745 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
16746 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
16747 goto nla_put_failure;
16748
16749 genlmsg_end(msg, hdr);
16750
16751 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16752 NL80211_MCGRP_MLME, gfp);
16753
16754 return;
16755
16756nla_put_failure:
16757 nlmsg_free(msg);
16758}
16759EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
16760
7f6cf311 16761void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
c4b50cd3
VN
16762 u64 cookie, bool acked, s32 ack_signal,
16763 bool is_valid_ack_signal, gfp_t gfp)
7f6cf311
JB
16764{
16765 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16766 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
16767 struct sk_buff *msg;
16768 void *hdr;
7f6cf311 16769
4ee3e063
BL
16770 trace_cfg80211_probe_status(dev, addr, cookie, acked);
16771
58050fce 16772 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 16773
7f6cf311
JB
16774 if (!msg)
16775 return;
16776
16777 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
16778 if (!hdr) {
16779 nlmsg_free(msg);
16780 return;
16781 }
16782
9360ffd1
DM
16783 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16784 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16785 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
16786 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
16787 NL80211_ATTR_PAD) ||
c4b50cd3
VN
16788 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
16789 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
16790 ack_signal)))
9360ffd1 16791 goto nla_put_failure;
7f6cf311 16792
9c90a9f6 16793 genlmsg_end(msg, hdr);
7f6cf311 16794
68eb5503 16795 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16796 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
16797 return;
16798
16799 nla_put_failure:
7f6cf311
JB
16800 nlmsg_free(msg);
16801}
16802EXPORT_SYMBOL(cfg80211_probe_status);
16803
5e760230
JB
16804void cfg80211_report_obss_beacon(struct wiphy *wiphy,
16805 const u8 *frame, size_t len,
37c73b5f 16806 int freq, int sig_dbm)
5e760230 16807{
f26cbf40 16808 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
16809 struct sk_buff *msg;
16810 void *hdr;
37c73b5f 16811 struct cfg80211_beacon_registration *reg;
5e760230 16812
4ee3e063
BL
16813 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
16814
37c73b5f
BG
16815 spin_lock_bh(&rdev->beacon_registrations_lock);
16816 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
16817 msg = nlmsg_new(len + 100, GFP_ATOMIC);
16818 if (!msg) {
16819 spin_unlock_bh(&rdev->beacon_registrations_lock);
16820 return;
16821 }
5e760230 16822
37c73b5f
BG
16823 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
16824 if (!hdr)
16825 goto nla_put_failure;
5e760230 16826
37c73b5f
BG
16827 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16828 (freq &&
16829 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
16830 (sig_dbm &&
16831 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
16832 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
16833 goto nla_put_failure;
5e760230 16834
37c73b5f 16835 genlmsg_end(msg, hdr);
5e760230 16836
37c73b5f
BG
16837 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
16838 }
16839 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
16840 return;
16841
16842 nla_put_failure:
37c73b5f 16843 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
16844 nlmsg_free(msg);
16845}
16846EXPORT_SYMBOL(cfg80211_report_obss_beacon);
16847
cd8f7cb4 16848#ifdef CONFIG_PM
8cd4d456
LC
16849static int cfg80211_net_detect_results(struct sk_buff *msg,
16850 struct cfg80211_wowlan_wakeup *wakeup)
16851{
16852 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
16853 struct nlattr *nl_results, *nl_match, *nl_freqs;
16854 int i, j;
16855
ae0be8de
MK
16856 nl_results = nla_nest_start_noflag(msg,
16857 NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
8cd4d456
LC
16858 if (!nl_results)
16859 return -EMSGSIZE;
16860
16861 for (i = 0; i < nd->n_matches; i++) {
16862 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
16863
ae0be8de 16864 nl_match = nla_nest_start_noflag(msg, i);
8cd4d456
LC
16865 if (!nl_match)
16866 break;
16867
16868 /* The SSID attribute is optional in nl80211, but for
16869 * simplicity reasons it's always present in the
16870 * cfg80211 structure. If a driver can't pass the
16871 * SSID, that needs to be changed. A zero length SSID
16872 * is still a valid SSID (wildcard), so it cannot be
16873 * used for this purpose.
16874 */
16875 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
16876 match->ssid.ssid)) {
16877 nla_nest_cancel(msg, nl_match);
16878 goto out;
16879 }
16880
16881 if (match->n_channels) {
ae0be8de
MK
16882 nl_freqs = nla_nest_start_noflag(msg,
16883 NL80211_ATTR_SCAN_FREQUENCIES);
8cd4d456
LC
16884 if (!nl_freqs) {
16885 nla_nest_cancel(msg, nl_match);
16886 goto out;
16887 }
16888
16889 for (j = 0; j < match->n_channels; j++) {
5528fae8 16890 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
16891 nla_nest_cancel(msg, nl_freqs);
16892 nla_nest_cancel(msg, nl_match);
16893 goto out;
16894 }
16895 }
16896
16897 nla_nest_end(msg, nl_freqs);
16898 }
16899
16900 nla_nest_end(msg, nl_match);
16901 }
16902
16903out:
16904 nla_nest_end(msg, nl_results);
16905 return 0;
16906}
16907
cd8f7cb4
JB
16908void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
16909 struct cfg80211_wowlan_wakeup *wakeup,
16910 gfp_t gfp)
16911{
f26cbf40 16912 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
16913 struct sk_buff *msg;
16914 void *hdr;
9c90a9f6 16915 int size = 200;
cd8f7cb4
JB
16916
16917 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
16918
16919 if (wakeup)
16920 size += wakeup->packet_present_len;
16921
16922 msg = nlmsg_new(size, gfp);
16923 if (!msg)
16924 return;
16925
16926 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
16927 if (!hdr)
16928 goto free_msg;
16929
16930 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
16931 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16932 NL80211_ATTR_PAD))
cd8f7cb4
JB
16933 goto free_msg;
16934
16935 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16936 wdev->netdev->ifindex))
16937 goto free_msg;
16938
16939 if (wakeup) {
16940 struct nlattr *reasons;
16941
ae0be8de
MK
16942 reasons = nla_nest_start_noflag(msg,
16943 NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
16944 if (!reasons)
16945 goto free_msg;
cd8f7cb4
JB
16946
16947 if (wakeup->disconnect &&
16948 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
16949 goto free_msg;
16950 if (wakeup->magic_pkt &&
16951 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
16952 goto free_msg;
16953 if (wakeup->gtk_rekey_failure &&
16954 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
16955 goto free_msg;
16956 if (wakeup->eap_identity_req &&
16957 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
16958 goto free_msg;
16959 if (wakeup->four_way_handshake &&
16960 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
16961 goto free_msg;
16962 if (wakeup->rfkill_release &&
16963 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
16964 goto free_msg;
16965
16966 if (wakeup->pattern_idx >= 0 &&
16967 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
16968 wakeup->pattern_idx))
16969 goto free_msg;
16970
ae917c9f
JB
16971 if (wakeup->tcp_match &&
16972 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
16973 goto free_msg;
2a0e047e 16974
ae917c9f
JB
16975 if (wakeup->tcp_connlost &&
16976 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
16977 goto free_msg;
2a0e047e 16978
ae917c9f
JB
16979 if (wakeup->tcp_nomoretokens &&
16980 nla_put_flag(msg,
16981 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
16982 goto free_msg;
2a0e047e 16983
cd8f7cb4
JB
16984 if (wakeup->packet) {
16985 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
16986 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
16987
16988 if (!wakeup->packet_80211) {
16989 pkt_attr =
16990 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
16991 len_attr =
16992 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
16993 }
16994
16995 if (wakeup->packet_len &&
16996 nla_put_u32(msg, len_attr, wakeup->packet_len))
16997 goto free_msg;
16998
16999 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
17000 wakeup->packet))
17001 goto free_msg;
17002 }
17003
8cd4d456
LC
17004 if (wakeup->net_detect &&
17005 cfg80211_net_detect_results(msg, wakeup))
17006 goto free_msg;
17007
cd8f7cb4
JB
17008 nla_nest_end(msg, reasons);
17009 }
17010
9c90a9f6 17011 genlmsg_end(msg, hdr);
cd8f7cb4 17012
68eb5503 17013 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17014 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
17015 return;
17016
17017 free_msg:
17018 nlmsg_free(msg);
17019}
17020EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
17021#endif
17022
3475b094
JM
17023void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
17024 enum nl80211_tdls_operation oper,
17025 u16 reason_code, gfp_t gfp)
17026{
17027 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 17028 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
17029 struct sk_buff *msg;
17030 void *hdr;
3475b094
JM
17031
17032 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
17033 reason_code);
17034
17035 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17036 if (!msg)
17037 return;
17038
17039 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
17040 if (!hdr) {
17041 nlmsg_free(msg);
17042 return;
17043 }
17044
17045 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17046 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17047 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
17048 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
17049 (reason_code > 0 &&
17050 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
17051 goto nla_put_failure;
17052
9c90a9f6 17053 genlmsg_end(msg, hdr);
3475b094 17054
68eb5503 17055 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17056 NL80211_MCGRP_MLME, gfp);
3475b094
JM
17057 return;
17058
17059 nla_put_failure:
3475b094
JM
17060 nlmsg_free(msg);
17061}
17062EXPORT_SYMBOL(cfg80211_tdls_oper_request);
17063
026331c4
JM
17064static int nl80211_netlink_notify(struct notifier_block * nb,
17065 unsigned long state,
17066 void *_notify)
17067{
17068 struct netlink_notify *notify = _notify;
17069 struct cfg80211_registered_device *rdev;
17070 struct wireless_dev *wdev;
37c73b5f 17071 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 17072
8f815cdd 17073 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
17074 return NOTIFY_DONE;
17075
17076 rcu_read_lock();
17077
5e760230 17078 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 17079 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 17080
ca986ad9
AVS
17081 list_for_each_entry_rcu(sched_scan_req,
17082 &rdev->sched_scan_req_list,
17083 list) {
17084 if (sched_scan_req->owner_nlportid == notify->portid) {
17085 sched_scan_req->nl_owner_dead = true;
753aacfd 17086 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 17087 }
753aacfd 17088 }
78f22b6a 17089
53873f13 17090 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 17091 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 17092
ab81007a
JB
17093 if (wdev->owner_nlportid == notify->portid) {
17094 wdev->nl_owner_dead = true;
17095 schedule_work(&rdev->destroy_work);
17096 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 17097 schedule_work(&wdev->disconnect_wk);
ab81007a 17098 }
9bb7e0f2
JB
17099
17100 cfg80211_release_pmsr(wdev, notify->portid);
78f22b6a
JB
17101 }
17102
37c73b5f
BG
17103 spin_lock_bh(&rdev->beacon_registrations_lock);
17104 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
17105 list) {
17106 if (reg->nlportid == notify->portid) {
17107 list_del(&reg->list);
17108 kfree(reg);
17109 break;
17110 }
17111 }
17112 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 17113 }
026331c4
JM
17114
17115 rcu_read_unlock();
17116
05050753
I
17117 /*
17118 * It is possible that the user space process that is controlling the
17119 * indoor setting disappeared, so notify the regulatory core.
17120 */
17121 regulatory_netlink_notify(notify->portid);
6784c7db 17122 return NOTIFY_OK;
026331c4
JM
17123}
17124
17125static struct notifier_block nl80211_netlink_notifier = {
17126 .notifier_call = nl80211_netlink_notify,
17127};
17128
355199e0
JM
17129void cfg80211_ft_event(struct net_device *netdev,
17130 struct cfg80211_ft_event_params *ft_event)
17131{
17132 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 17133 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
17134 struct sk_buff *msg;
17135 void *hdr;
355199e0
JM
17136
17137 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
17138
17139 if (!ft_event->target_ap)
17140 return;
17141
1039d081
DL
17142 msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
17143 GFP_KERNEL);
355199e0
JM
17144 if (!msg)
17145 return;
17146
17147 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
17148 if (!hdr)
17149 goto out;
355199e0 17150
ae917c9f
JB
17151 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17152 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17153 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
17154 goto out;
355199e0 17155
ae917c9f
JB
17156 if (ft_event->ies &&
17157 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
17158 goto out;
17159 if (ft_event->ric_ies &&
17160 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
17161 ft_event->ric_ies))
17162 goto out;
355199e0 17163
9c90a9f6 17164 genlmsg_end(msg, hdr);
355199e0 17165
68eb5503 17166 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17167 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
17168 return;
17169 out:
17170 nlmsg_free(msg);
355199e0
JM
17171}
17172EXPORT_SYMBOL(cfg80211_ft_event);
17173
5de17984
AS
17174void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
17175{
17176 struct cfg80211_registered_device *rdev;
17177 struct sk_buff *msg;
17178 void *hdr;
17179 u32 nlportid;
17180
f26cbf40 17181 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
17182 if (!rdev->crit_proto_nlportid)
17183 return;
17184
17185 nlportid = rdev->crit_proto_nlportid;
17186 rdev->crit_proto_nlportid = 0;
17187
17188 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17189 if (!msg)
17190 return;
17191
17192 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
17193 if (!hdr)
17194 goto nla_put_failure;
17195
17196 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
17197 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17198 NL80211_ATTR_PAD))
5de17984
AS
17199 goto nla_put_failure;
17200
17201 genlmsg_end(msg, hdr);
17202
17203 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
17204 return;
17205
17206 nla_put_failure:
5de17984 17207 nlmsg_free(msg);
5de17984
AS
17208}
17209EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
17210
348baf0e
JB
17211void nl80211_send_ap_stopped(struct wireless_dev *wdev)
17212{
17213 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17214 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
17215 struct sk_buff *msg;
17216 void *hdr;
17217
17218 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17219 if (!msg)
17220 return;
17221
17222 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
17223 if (!hdr)
17224 goto out;
17225
17226 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17227 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
17228 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17229 NL80211_ATTR_PAD))
348baf0e
JB
17230 goto out;
17231
17232 genlmsg_end(msg, hdr);
17233
17234 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
17235 NL80211_MCGRP_MLME, GFP_KERNEL);
17236 return;
17237 out:
17238 nlmsg_free(msg);
17239}
17240
40cbfa90
SD
17241int cfg80211_external_auth_request(struct net_device *dev,
17242 struct cfg80211_external_auth_params *params,
17243 gfp_t gfp)
17244{
17245 struct wireless_dev *wdev = dev->ieee80211_ptr;
17246 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
17247 struct sk_buff *msg;
17248 void *hdr;
17249
17250 if (!wdev->conn_owner_nlportid)
17251 return -EINVAL;
17252
17253 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17254 if (!msg)
17255 return -ENOMEM;
17256
17257 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
17258 if (!hdr)
17259 goto nla_put_failure;
17260
17261 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17262 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17263 nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
17264 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
17265 params->action) ||
17266 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
17267 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
17268 params->ssid.ssid))
17269 goto nla_put_failure;
17270
17271 genlmsg_end(msg, hdr);
17272 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
17273 wdev->conn_owner_nlportid);
17274 return 0;
17275
17276 nla_put_failure:
17277 nlmsg_free(msg);
17278 return -ENOBUFS;
17279}
17280EXPORT_SYMBOL(cfg80211_external_auth_request);
17281
cb74e977
SD
17282void cfg80211_update_owe_info_event(struct net_device *netdev,
17283 struct cfg80211_update_owe_info *owe_info,
17284 gfp_t gfp)
17285{
17286 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
17287 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
17288 struct sk_buff *msg;
17289 void *hdr;
17290
17291 trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
17292
17293 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17294 if (!msg)
17295 return;
17296
17297 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
17298 if (!hdr)
17299 goto nla_put_failure;
17300
17301 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17302 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17303 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
17304 goto nla_put_failure;
17305
17306 if (!owe_info->ie_len ||
17307 nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
17308 goto nla_put_failure;
17309
17310 genlmsg_end(msg, hdr);
17311
17312 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17313 NL80211_MCGRP_MLME, gfp);
17314 return;
17315
17316nla_put_failure:
17317 genlmsg_cancel(msg, hdr);
17318 nlmsg_free(msg);
17319}
17320EXPORT_SYMBOL(cfg80211_update_owe_info_event);
17321
55682965
JB
17322/* initialisation/exit functions */
17323
56989f6d 17324int __init nl80211_init(void)
55682965 17325{
0d63cbb5 17326 int err;
55682965 17327
489111e5 17328 err = genl_register_family(&nl80211_fam);
55682965
JB
17329 if (err)
17330 return err;
17331
026331c4
JM
17332 err = netlink_register_notifier(&nl80211_netlink_notifier);
17333 if (err)
17334 goto err_out;
17335
55682965
JB
17336 return 0;
17337 err_out:
17338 genl_unregister_family(&nl80211_fam);
17339 return err;
17340}
17341
17342void nl80211_exit(void)
17343{
026331c4 17344 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
17345 genl_unregister_family(&nl80211_fam);
17346}