mac80211: add STBC encoding to ieee80211_parse_tx_radiotap
[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
7e8d6f12 8 * Copyright (C) 2018-2020 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>
e3ae39ed 23#include <linux/if_vlan.h>
463d0183 24#include <net/net_namespace.h>
55682965
JB
25#include <net/genetlink.h>
26#include <net/cfg80211.h>
463d0183 27#include <net/sock.h>
2a0e047e 28#include <net/inet_connection_sock.h>
55682965
JB
29#include "core.h"
30#include "nl80211.h"
b2e1b302 31#include "reg.h"
e35e4d28 32#include "rdev-ops.h"
55682965 33
5fb628e9
JM
34static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
35 struct genl_info *info,
36 struct cfg80211_crypto_settings *settings,
37 int cipher_limit);
38
55682965 39/* the netlink family */
489111e5 40static struct genl_family nl80211_fam;
55682965 41
2a94fe48
JB
42/* multicast groups */
43enum nl80211_multicast_groups {
44 NL80211_MCGRP_CONFIG,
45 NL80211_MCGRP_SCAN,
46 NL80211_MCGRP_REGULATORY,
47 NL80211_MCGRP_MLME,
567ffc35 48 NL80211_MCGRP_VENDOR,
50bcd31d 49 NL80211_MCGRP_NAN,
2a94fe48
JB
50 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
51};
52
53static const struct genl_multicast_group nl80211_mcgrps[] = {
71b836ec
JB
54 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
55 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
56 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
57 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
58 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
50bcd31d 59 [NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
2a94fe48 60#ifdef CONFIG_NL80211_TESTMODE
71b836ec 61 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
2a94fe48
JB
62#endif
63};
64
89a54e48
JB
65/* returns ERR_PTR values */
66static struct wireless_dev *
a05829a7
JB
67__cfg80211_wdev_from_attrs(struct cfg80211_registered_device *rdev,
68 struct net *netns, struct nlattr **attrs)
55682965 69{
89a54e48
JB
70 struct wireless_dev *result = NULL;
71 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
72 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
73 u64 wdev_id;
74 int wiphy_idx = -1;
75 int ifidx = -1;
55682965 76
89a54e48
JB
77 if (!have_ifidx && !have_wdev_id)
78 return ERR_PTR(-EINVAL);
55682965 79
89a54e48
JB
80 if (have_ifidx)
81 ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
82 if (have_wdev_id) {
83 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
84 wiphy_idx = wdev_id >> 32;
55682965
JB
85 }
86
a05829a7
JB
87 if (rdev) {
88 struct wireless_dev *wdev;
89
90 lockdep_assert_held(&rdev->wiphy.mtx);
91
92 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
93 if (have_ifidx && wdev->netdev &&
94 wdev->netdev->ifindex == ifidx) {
95 result = wdev;
96 break;
97 }
98 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
99 result = wdev;
100 break;
101 }
102 }
103
104 return result ?: ERR_PTR(-ENODEV);
105 }
106
107 ASSERT_RTNL();
108
89a54e48
JB
109 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
110 struct wireless_dev *wdev;
111
112 if (wiphy_net(&rdev->wiphy) != netns)
113 continue;
114
115 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
116 continue;
117
53873f13 118 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
89a54e48
JB
119 if (have_ifidx && wdev->netdev &&
120 wdev->netdev->ifindex == ifidx) {
121 result = wdev;
122 break;
123 }
124 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
125 result = wdev;
126 break;
127 }
128 }
89a54e48
JB
129
130 if (result)
131 break;
132 }
133
134 if (result)
135 return result;
136 return ERR_PTR(-ENODEV);
55682965
JB
137}
138
a9455408 139static struct cfg80211_registered_device *
878d9ec7 140__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 141{
7fee4778
JB
142 struct cfg80211_registered_device *rdev = NULL, *tmp;
143 struct net_device *netdev;
a9455408 144
5fe231e8 145 ASSERT_RTNL();
a9455408 146
878d9ec7 147 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
148 !attrs[NL80211_ATTR_IFINDEX] &&
149 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
150 return ERR_PTR(-EINVAL);
151
878d9ec7 152 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 153 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 154 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 155
89a54e48
JB
156 if (attrs[NL80211_ATTR_WDEV]) {
157 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
158 struct wireless_dev *wdev;
159 bool found = false;
160
161 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
162 if (tmp) {
163 /* make sure wdev exists */
53873f13 164 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
89a54e48
JB
165 if (wdev->identifier != (u32)wdev_id)
166 continue;
167 found = true;
168 break;
169 }
89a54e48
JB
170
171 if (!found)
172 tmp = NULL;
173
174 if (rdev && tmp != rdev)
175 return ERR_PTR(-EINVAL);
176 rdev = tmp;
177 }
178 }
179
878d9ec7
JB
180 if (attrs[NL80211_ATTR_IFINDEX]) {
181 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7a087e74 182
7f2b8562 183 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
184 if (netdev) {
185 if (netdev->ieee80211_ptr)
f26cbf40
ZG
186 tmp = wiphy_to_rdev(
187 netdev->ieee80211_ptr->wiphy);
7fee4778
JB
188 else
189 tmp = NULL;
190
7fee4778
JB
191 /* not wireless device -- return error */
192 if (!tmp)
193 return ERR_PTR(-EINVAL);
194
195 /* mismatch -- return error */
196 if (rdev && tmp != rdev)
197 return ERR_PTR(-EINVAL);
198
199 rdev = tmp;
a9455408 200 }
a9455408 201 }
a9455408 202
4f7eff10
JB
203 if (!rdev)
204 return ERR_PTR(-ENODEV);
a9455408 205
4f7eff10
JB
206 if (netns != wiphy_net(&rdev->wiphy))
207 return ERR_PTR(-ENODEV);
208
209 return rdev;
a9455408
JB
210}
211
212/*
213 * This function returns a pointer to the driver
214 * that the genl_info item that is passed refers to.
a9455408
JB
215 *
216 * The result of this can be a PTR_ERR and hence must
217 * be checked with IS_ERR() for errors.
218 */
219static struct cfg80211_registered_device *
4f7eff10 220cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 221{
5fe231e8 222 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
223}
224
f88eb7c0
JB
225static int validate_beacon_head(const struct nlattr *attr,
226 struct netlink_ext_ack *extack)
227{
228 const u8 *data = nla_data(attr);
229 unsigned int len = nla_len(attr);
230 const struct element *elem;
231 const struct ieee80211_mgmt *mgmt = (void *)data;
1d47f119
TP
232 bool s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
233 unsigned int fixedlen, hdrlen;
234
235 if (s1g_bcn) {
236 fixedlen = offsetof(struct ieee80211_ext,
237 u.s1g_beacon.variable);
238 hdrlen = offsetof(struct ieee80211_ext, u.s1g_beacon);
239 } else {
240 fixedlen = offsetof(struct ieee80211_mgmt,
241 u.beacon.variable);
242 hdrlen = offsetof(struct ieee80211_mgmt, u.beacon);
243 }
f88eb7c0
JB
244
245 if (len < fixedlen)
246 goto err;
247
1d47f119 248 if (ieee80211_hdrlen(mgmt->frame_control) != hdrlen)
f88eb7c0
JB
249 goto err;
250
251 data += fixedlen;
252 len -= fixedlen;
253
254 for_each_element(elem, data, len) {
255 /* nothing */
256 }
257
258 if (for_each_element_completed(elem, data, len))
259 return 0;
260
261err:
262 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
263 return -EINVAL;
264}
265
3d7af878
JB
266static int validate_ie_attr(const struct nlattr *attr,
267 struct netlink_ext_ack *extack)
268{
9f308616
JB
269 const u8 *data = nla_data(attr);
270 unsigned int len = nla_len(attr);
7388afe0 271 const struct element *elem;
3d7af878 272
9f308616
JB
273 for_each_element(elem, data, len) {
274 /* nothing */
3d7af878
JB
275 }
276
9f308616
JB
277 if (for_each_element_completed(elem, data, len))
278 return 0;
279
3d7af878
JB
280 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed information elements");
281 return -EINVAL;
282}
283
55682965 284/* policy for the attributes */
d15da2a2
JB
285static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
286
81e54d08
PKC
287static const struct nla_policy
288nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
289 [NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
290 [NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
291 .len = U8_MAX },
292 [NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
293 .len = U8_MAX },
294};
295
9bb7e0f2
JB
296static const struct nla_policy
297nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
298 [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
299 [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
300 [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
301 NLA_POLICY_MAX(NLA_U8, 15),
302 [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
303 [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
304 NLA_POLICY_MAX(NLA_U8, 15),
305 [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
ea18709a 306 NLA_POLICY_MAX(NLA_U8, 31),
9bb7e0f2
JB
307 [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
308 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
309 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
efb5520d
AS
310 [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG },
311 [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG },
9bb7e0f2
JB
312};
313
314static const struct nla_policy
315nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
316 [NL80211_PMSR_TYPE_FTM] =
23323289 317 NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
9bb7e0f2
JB
318};
319
320static const struct nla_policy
321nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
322 [NL80211_PMSR_REQ_ATTR_DATA] =
23323289 323 NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
9bb7e0f2
JB
324 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
325};
326
327static const struct nla_policy
328nl80211_psmr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
329 [NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
d15da2a2 330 [NL80211_PMSR_PEER_ATTR_CHAN] = NLA_POLICY_NESTED(nl80211_policy),
9bb7e0f2 331 [NL80211_PMSR_PEER_ATTR_REQ] =
23323289 332 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
9bb7e0f2
JB
333 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
334};
335
336static const struct nla_policy
337nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
338 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
339 [NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
340 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
341 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
342 [NL80211_PMSR_ATTR_PEERS] =
23323289 343 NLA_POLICY_NESTED_ARRAY(nl80211_psmr_peer_attr_policy),
9bb7e0f2
JB
344};
345
796e90f4
JC
346static const struct nla_policy
347he_obss_pd_policy[NL80211_HE_OBSS_PD_ATTR_MAX + 1] = {
348 [NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] =
349 NLA_POLICY_RANGE(NLA_U8, 1, 20),
350 [NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET] =
351 NLA_POLICY_RANGE(NLA_U8, 1, 20),
f5bec330
RM
352 [NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET] =
353 NLA_POLICY_RANGE(NLA_U8, 1, 20),
354 [NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP] =
355 NLA_POLICY_EXACT_LEN(8),
356 [NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP] =
357 NLA_POLICY_EXACT_LEN(8),
358 [NL80211_HE_OBSS_PD_ATTR_SR_CTRL] = { .type = NLA_U8 },
796e90f4
JC
359};
360
5c5e52d1
JC
361static const struct nla_policy
362he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
363 [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63),
364 [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG },
365 [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
366};
367
9a5f6488
TC
368static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
369 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
370 .len = NL80211_MAX_SUPP_RATES },
371 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
372 .len = NL80211_MAX_SUPP_HT_RATES },
373 [NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)),
374 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
eb89a6a6
MH
375 [NL80211_TXRATE_HE] = NLA_POLICY_EXACT_LEN(sizeof(struct nl80211_txrate_he)),
376 [NL80211_TXRATE_HE_GI] = NLA_POLICY_RANGE(NLA_U8,
377 NL80211_RATE_INFO_HE_GI_0_8,
378 NL80211_RATE_INFO_HE_GI_3_2),
379 [NL80211_TXRATE_HE_LTF] = NLA_POLICY_RANGE(NLA_U8,
380 NL80211_RATE_INFO_HE_1XLTF,
381 NL80211_RATE_INFO_HE_4XLTF),
9a5f6488
TC
382};
383
77f576de
T
384static const struct nla_policy
385nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
3710a8a6
JB
386 [NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
387 [NL80211_TID_CONFIG_ATTR_PEER_SUPP] = { .type = NLA_U64 },
77f576de 388 [NL80211_TID_CONFIG_ATTR_OVERRIDE] = { .type = NLA_FLAG },
3710a8a6 389 [NL80211_TID_CONFIG_ATTR_TIDS] = NLA_POLICY_RANGE(NLA_U16, 1, 0xff),
77f576de
T
390 [NL80211_TID_CONFIG_ATTR_NOACK] =
391 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
6a21d16c
T
392 [NL80211_TID_CONFIG_ATTR_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
393 [NL80211_TID_CONFIG_ATTR_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
ade274b2
T
394 [NL80211_TID_CONFIG_ATTR_AMPDU_CTRL] =
395 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
04f7d142
T
396 [NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] =
397 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
33462e68
SM
398 [NL80211_TID_CONFIG_ATTR_AMSDU_CTRL] =
399 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
9a5f6488
TC
400 [NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE] =
401 NLA_POLICY_MAX(NLA_U8, NL80211_TX_RATE_FIXED),
402 [NL80211_TID_CONFIG_ATTR_TX_RATE] =
403 NLA_POLICY_NESTED(nl80211_txattr_policy),
77f576de
T
404};
405
291c49de
AD
406static const struct nla_policy
407nl80211_fils_discovery_policy[NL80211_FILS_DISCOVERY_ATTR_MAX + 1] = {
408 [NL80211_FILS_DISCOVERY_ATTR_INT_MIN] = NLA_POLICY_MAX(NLA_U32, 10000),
409 [NL80211_FILS_DISCOVERY_ATTR_INT_MAX] = NLA_POLICY_MAX(NLA_U32, 10000),
410 NLA_POLICY_RANGE(NLA_BINARY,
411 NL80211_FILS_DISCOVERY_TMPL_MIN_LEN,
412 IEEE80211_MAX_DATA_LEN),
413};
414
7443dcd1
AD
415static const struct nla_policy
416nl80211_unsol_bcast_probe_resp_policy[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1] = {
417 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] = NLA_POLICY_MAX(NLA_U32, 20),
418 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL] = { .type = NLA_BINARY,
419 .len = IEEE80211_MAX_DATA_LEN }
420};
421
6bdb68ce
CH
422static const struct nla_policy
423sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
424 [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
425 [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
426};
427
428static const struct nla_policy
429sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
430 [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
431 [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
432};
433
d15da2a2 434static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
6d4dd4ef 435 [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
55682965
JB
436 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
437 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 438 .len = 20-1 },
31888487 439 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 440
72bdcf34 441 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 442 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
2a38075c
AAL
443 [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
444 NL80211_EDMG_CHANNELS_MIN,
445 NL80211_EDMG_CHANNELS_MAX),
446 [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
447 NL80211_EDMG_BW_CONFIG_MIN,
448 NL80211_EDMG_BW_CONFIG_MAX),
449
3d9d1d66
JB
450 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
451 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
942ba88b 452 [NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
3d9d1d66
JB
453 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
454
ab0d76f6
JB
455 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
456 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
b9a5f8ca
JM
457 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
458 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 459 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 460 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965 461
ab0d76f6 462 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
55682965
JB
463 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
464 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 465
c7721c05
JB
466 [NL80211_ATTR_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
467 [NL80211_ATTR_PREV_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
41ade00f 468
b9454e83 469 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
470 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
471 .len = WLAN_MAX_KEY_LEN },
56be393f 472 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
41ade00f
JB
473 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
474 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 475 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
ab0d76f6
JB
476 [NL80211_ATTR_KEY_TYPE] =
477 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
ed1b6cc7
JB
478
479 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
480 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
f88eb7c0
JB
481 [NL80211_ATTR_BEACON_HEAD] =
482 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
483 IEEE80211_MAX_DATA_LEN),
3d7af878
JB
484 [NL80211_ATTR_BEACON_TAIL] =
485 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
486 IEEE80211_MAX_DATA_LEN),
ab0d76f6
JB
487 [NL80211_ATTR_STA_AID] =
488 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
5727ef1b
JB
489 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
490 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
491 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
492 .len = NL80211_MAX_SUPP_RATES },
ab0d76f6
JB
493 [NL80211_ATTR_STA_PLINK_ACTION] =
494 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
e96d1cd2
ARN
495 [NL80211_ATTR_STA_TX_POWER_SETTING] =
496 NLA_POLICY_RANGE(NLA_U8,
497 NL80211_TX_POWER_AUTOMATIC,
498 NL80211_TX_POWER_FIXED),
499 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
5727ef1b 500 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 501 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 502 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 503 .len = IEEE80211_MAX_MESH_ID_LEN },
1fab1b89 504 [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
9f1ba906 505
b2e1b302
LR
506 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
507 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
508
9f1ba906
JM
509 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
510 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
511 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
512 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
513 .len = NL80211_MAX_SUPP_RATES },
50b12f59 514 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 515
24bdd9f4 516 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 517 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 518
c7721c05 519 [NL80211_ATTR_HT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_HT_CAPABILITY_LEN),
9aed3cc1
JM
520
521 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
3d7af878
JB
522 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
523 validate_ie_attr,
524 IEEE80211_MAX_DATA_LEN),
2a519311
JB
525 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
526 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
527
528 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
529 .len = IEEE80211_MAX_SSID_LEN },
530 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
531 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 532 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 533 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
ab0d76f6
JB
534 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
535 NL80211_MFP_NO,
536 NL80211_MFP_OPTIONAL),
eccb8e8f
JB
537 [NL80211_ATTR_STA_FLAGS2] = {
538 .len = sizeof(struct nl80211_sta_flag_update),
539 },
3f77316c 540 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
541 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
542 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
64bf3d4b 543 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
b23aa676 544 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
ea750801 545 [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
b23aa676
SO
546 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
547 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 548 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 549 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
c7721c05 550 [NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
9588bbd5
JM
551 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
552 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 553 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
554 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
555 .len = IEEE80211_MAX_DATA_LEN },
556 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ab0d76f6
JB
557 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
558 NL80211_PS_DISABLED,
559 NL80211_PS_ENABLED),
d6dc1a38 560 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 561 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 562 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
563 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
564 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 565 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
566 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
567 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 568 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 569 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 570 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 571 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
ab0d76f6
JB
572 [NL80211_ATTR_STA_PLINK_STATE] =
573 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
056e9375
JK
574 [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
575 [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
ab0d76f6
JB
576 [NL80211_ATTR_MESH_PEER_AID] =
577 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
bbe6ad6d 578 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 579 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 580 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
ab0d76f6
JB
581 [NL80211_ATTR_HIDDEN_SSID] =
582 NLA_POLICY_RANGE(NLA_U32,
583 NL80211_HIDDEN_SSID_NOT_IN_USE,
584 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
3d7af878
JB
585 [NL80211_ATTR_IE_PROBE_RESP] =
586 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
587 IEEE80211_MAX_DATA_LEN),
588 [NL80211_ATTR_IE_ASSOC_RESP] =
589 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
590 IEEE80211_MAX_DATA_LEN),
f4b34b55 591 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 592 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 593 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
594 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
595 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
596 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
597 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
598 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 599 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 600 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
601 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
602 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 603 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
604 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
605 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
606 .len = NL80211_HT_CAPABILITY_LEN
607 },
1d9d9213 608 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 609 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 610 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 611 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 612 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
cb9abd48
JB
613
614 /* need to include at least Auth Transaction and Status Code */
615 [NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
616
c7721c05 617 [NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
ed473771 618 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
ab0d76f6
JB
619 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
620 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
621 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
622 NLA_POLICY_RANGE(NLA_U32,
623 NL80211_MESH_POWER_UNKNOWN + 1,
624 NL80211_MESH_POWER_MAX),
77765eaf
VT
625 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
626 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
627 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
628 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 629 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
630 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
631 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
632 .len = NL80211_VHT_CAPABILITY_LEN,
633 },
355199e0
JM
634 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
635 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
636 .len = IEEE80211_MAX_DATA_LEN },
0e1a1d85 637 [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
cb9abd48
JB
638 [NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
639 NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
ab0d76f6
JB
640 [NL80211_ATTR_PEER_AID] =
641 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
16ef1fe2
SW
642 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
643 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
644 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
00c207ed
JC
645 [NL80211_ATTR_CNTDWN_OFFS_BEACON] = { .type = NLA_BINARY },
646 [NL80211_ATTR_CNTDWN_OFFS_PRESP] = { .type = NLA_BINARY },
cb9abd48 647 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
c8b82802
JB
648 /*
649 * The value of the Length field of the Supported Operating
650 * Classes element is between 2 and 253.
651 */
652 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] =
653 NLA_POLICY_RANGE(NLA_BINARY, 2, 253),
5336fa88 654 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 655 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
656 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
657 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
658 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
c8b82802
JB
659 [NL80211_ATTR_QOS_MAP] = NLA_POLICY_RANGE(NLA_BINARY,
660 IEEE80211_QOS_MAP_LEN_MIN,
661 IEEE80211_QOS_MAP_LEN_MAX),
c7721c05 662 [NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
1df4a510 663 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 664 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 665 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 666 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 667 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
ab0d76f6
JB
668 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
669 [NL80211_ATTR_USER_PRIO] =
670 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
960d01ac 671 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 672 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
5cde05c6 673 [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
c7721c05 674 [NL80211_ATTR_MAC_MASK] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
1bdd716c 675 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 676 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 677 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 678 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 679 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 680 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
ab0d76f6
JB
681 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
682 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
c6e6a0c8
AE
683 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
684 .len = VHT_MUMIMO_GROUPS_DATA_LEN
685 },
c7721c05 686 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
ab0d76f6 687 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
8585989d 688 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
a442b761 689 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
348bd456
JM
690 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
691 .len = FILS_MAX_KEK_LEN },
c7721c05 692 [NL80211_ATTR_FILS_NONCES] = NLA_POLICY_EXACT_LEN_WARN(2 * FILS_NONCE_LEN),
ce0ce13a 693 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
c7721c05 694 [NL80211_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
bf95ecdb 695 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
696 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
697 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
698 },
3093ebbe 699 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
a3caf744
VK
700 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
701 .len = FILS_ERP_MAX_USERNAME_LEN },
702 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
703 .len = FILS_ERP_MAX_REALM_LEN },
704 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
705 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
706 .len = FILS_ERP_MAX_RRK_LEN },
c7721c05 707 [NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
a3caf744 708 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
cb9abd48 709 [NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
ca986ad9 710 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
40cbfa90 711 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
52539ca8
THJ
712
713 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
714 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
715 [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
c8b82802
JB
716 [NL80211_ATTR_HE_CAPABILITY] =
717 NLA_POLICY_RANGE(NLA_BINARY,
718 NL80211_HE_MIN_CAPABILITY_LEN,
719 NL80211_HE_MAX_CAPABILITY_LEN),
0e012b4e
JB
720 [NL80211_ATTR_FTM_RESPONDER] =
721 NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
9bb7e0f2
JB
722 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
723 [NL80211_ATTR_PEER_MEASUREMENTS] =
23323289 724 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
36647055 725 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
26f7044e
CHH
726 [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
727 .len = SAE_PASSWORD_MAX_LEN },
a0de1ca3 728 [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
796e90f4 729 [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
14f34e36 730 [NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
5c5e52d1 731 [NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
77f576de
T
732 [NL80211_ATTR_TID_CONFIG] =
733 NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
5631d96a 734 [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
7fc82af8
VJ
735 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
736 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
9dba48a6 737 [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
942ba88b 738 [NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
2032f3b2 739 [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
8140860c
JB
740 [NL80211_ATTR_HE_6GHZ_CAPABILITY] =
741 NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
291c49de
AD
742 [NL80211_ATTR_FILS_DISCOVERY] =
743 NLA_POLICY_NESTED(nl80211_fils_discovery_policy),
7443dcd1
AD
744 [NL80211_ATTR_UNSOL_BCAST_PROBE_RESP] =
745 NLA_POLICY_NESTED(nl80211_unsol_bcast_probe_resp_policy),
d2b7588a
TP
746 [NL80211_ATTR_S1G_CAPABILITY] =
747 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
748 [NL80211_ATTR_S1G_CAPABILITY_MASK] =
749 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
9f0ffa41
RD
750 [NL80211_ATTR_SAE_PWE] =
751 NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
752 NL80211_SAE_PWE_BOTH),
3bb02143 753 [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
6bdb68ce 754 [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
55682965
JB
755};
756
e31b8213 757/* policy for the key attributes */
b54452b0 758static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 759 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
760 [NL80211_KEY_IDX] = { .type = NLA_U8 },
761 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 762 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
763 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
764 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
ab0d76f6 765 [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
dbd2fd65 766 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
6cdd3979 767 [NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
dbd2fd65
JB
768};
769
770/* policy for the key default flags */
771static const struct nla_policy
772nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
773 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
774 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
775};
776
f83ace3b 777#ifdef CONFIG_PM
ff1b6e69
JB
778/* policy for WoWLAN attributes */
779static const struct nla_policy
780nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
781 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
782 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
783 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
784 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
785 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
786 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
787 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
788 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 789 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 790 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
791};
792
793static const struct nla_policy
794nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
795 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
796 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
c7721c05 797 [NL80211_WOWLAN_TCP_DST_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
2a0e047e
JB
798 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
799 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
bc043585 800 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
2a0e047e
JB
801 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
802 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
803 },
804 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
805 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
806 },
807 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
bc043585
JB
808 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
809 [NL80211_WOWLAN_TCP_WAKE_MASK] = NLA_POLICY_MIN_LEN(1),
ff1b6e69 810};
f83ace3b 811#endif /* CONFIG_PM */
ff1b6e69 812
be29b99a
AK
813/* policy for coalesce rule attributes */
814static const struct nla_policy
815nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
816 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
ab0d76f6
JB
817 [NL80211_ATTR_COALESCE_RULE_CONDITION] =
818 NLA_POLICY_RANGE(NLA_U32,
819 NL80211_COALESCE_CONDITION_MATCH,
820 NL80211_COALESCE_CONDITION_NO_MATCH),
be29b99a
AK
821 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
822};
823
e5497d76
JB
824/* policy for GTK rekey offload attributes */
825static const struct nla_policy
826nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
093a48d2
NE
827 [NL80211_REKEY_DATA_KEK] = {
828 .type = NLA_BINARY,
829 .len = NL80211_KEK_EXT_LEN
830 },
831 [NL80211_REKEY_DATA_KCK] = {
832 .type = NLA_BINARY,
833 .len = NL80211_KCK_EXT_LEN
834 },
cb9abd48 835 [NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN(NL80211_REPLAY_CTR_LEN),
093a48d2 836 [NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
e5497d76
JB
837};
838
1e1b11b6 839static const struct nla_policy
840nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
841 [NL80211_BAND_2GHZ] = { .type = NLA_S32 },
842 [NL80211_BAND_5GHZ] = { .type = NLA_S32 },
e548a1c3 843 [NL80211_BAND_6GHZ] = { .type = NLA_S32 },
1e1b11b6 844 [NL80211_BAND_60GHZ] = { .type = NLA_S32 },
845};
846
a1f1c21c
LC
847static const struct nla_policy
848nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 849 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 850 .len = IEEE80211_MAX_SSID_LEN },
c7721c05 851 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
88e920b4 852 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
1e1b11b6 853 [NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
854 NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
a1f1c21c
LC
855};
856
3b06d277
AS
857static const struct nla_policy
858nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
859 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
860 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
861};
862
38de03d2
AS
863static const struct nla_policy
864nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
865 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
866 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
867 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
868 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
869 },
870};
871
a442b761
AB
872/* policy for NAN function attributes */
873static const struct nla_policy
874nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
cb9abd48
JB
875 [NL80211_NAN_FUNC_TYPE] =
876 NLA_POLICY_MAX(NLA_U8, NL80211_NAN_FUNC_MAX_TYPE),
0a27844c 877 [NL80211_NAN_FUNC_SERVICE_ID] = {
a442b761
AB
878 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
879 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
880 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
881 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
882 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
883 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
c7721c05 884 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
a442b761
AB
885 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
886 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
887 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
888 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
889 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
890 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
891 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
892 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
893 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
894};
895
896/* policy for Service Response Filter attributes */
897static const struct nla_policy
898nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
899 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
900 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
901 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
902 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
903 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
904};
905
ad670233
PX
906/* policy for packet pattern attributes */
907static const struct nla_policy
908nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
909 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
910 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
911 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
912};
913
9bb7e0f2
JB
914int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
915 struct cfg80211_registered_device **rdev,
916 struct wireless_dev **wdev)
a043897a 917{
97990a06 918 int err;
a043897a 919
97990a06 920 if (!cb->args[0]) {
50508d94
JB
921 struct nlattr **attrbuf;
922
923 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
924 GFP_KERNEL);
925 if (!attrbuf)
926 return -ENOMEM;
927
8cb08174
JB
928 err = nlmsg_parse_deprecated(cb->nlh,
929 GENL_HDRLEN + nl80211_fam.hdrsize,
50508d94 930 attrbuf, nl80211_fam.maxattr,
8cb08174 931 nl80211_policy, NULL);
50508d94
JB
932 if (err) {
933 kfree(attrbuf);
ea90e0dc 934 return err;
50508d94 935 }
67748893 936
a05829a7
JB
937 rtnl_lock();
938 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(cb->skb->sk),
50508d94
JB
939 attrbuf);
940 kfree(attrbuf);
a05829a7
JB
941 if (IS_ERR(*wdev)) {
942 rtnl_unlock();
ea90e0dc 943 return PTR_ERR(*wdev);
a05829a7 944 }
f26cbf40 945 *rdev = wiphy_to_rdev((*wdev)->wiphy);
a05829a7
JB
946 mutex_lock(&(*rdev)->wiphy.mtx);
947 rtnl_unlock();
c319d50b
JB
948 /* 0 is the first index - add 1 to parse only once */
949 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
950 cb->args[1] = (*wdev)->identifier;
951 } else {
c319d50b 952 /* subtract the 1 again here */
a05829a7 953 struct wiphy *wiphy;
97990a06 954 struct wireless_dev *tmp;
67748893 955
a05829a7
JB
956 rtnl_lock();
957 wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
958 if (!wiphy) {
959 rtnl_unlock();
ea90e0dc 960 return -ENODEV;
a05829a7 961 }
f26cbf40 962 *rdev = wiphy_to_rdev(wiphy);
97990a06 963 *wdev = NULL;
67748893 964
53873f13 965 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
966 if (tmp->identifier == cb->args[1]) {
967 *wdev = tmp;
968 break;
969 }
970 }
67748893 971
a05829a7
JB
972 if (!*wdev) {
973 rtnl_unlock();
ea90e0dc 974 return -ENODEV;
a05829a7
JB
975 }
976 mutex_lock(&(*rdev)->wiphy.mtx);
977 rtnl_unlock();
67748893
JB
978 }
979
67748893 980 return 0;
67748893
JB
981}
982
55682965 983/* message building helper */
9bb7e0f2
JB
984void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
985 int flags, u8 cmd)
55682965
JB
986{
987 /* since there is no private header just add the generic one */
15e47304 988 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
989}
990
50f32718
HD
991static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
992 const struct ieee80211_reg_rule *rule)
993{
994 int j;
995 struct nlattr *nl_wmm_rules =
ae0be8de 996 nla_nest_start_noflag(msg, NL80211_FREQUENCY_ATTR_WMM);
50f32718
HD
997
998 if (!nl_wmm_rules)
999 goto nla_put_failure;
1000
1001 for (j = 0; j < IEEE80211_NUM_ACS; j++) {
ae0be8de 1002 struct nlattr *nl_wmm_rule = nla_nest_start_noflag(msg, j);
50f32718
HD
1003
1004 if (!nl_wmm_rule)
1005 goto nla_put_failure;
1006
1007 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
38cb87ee 1008 rule->wmm_rule.client[j].cw_min) ||
50f32718 1009 nla_put_u16(msg, NL80211_WMMR_CW_MAX,
38cb87ee 1010 rule->wmm_rule.client[j].cw_max) ||
50f32718 1011 nla_put_u8(msg, NL80211_WMMR_AIFSN,
38cb87ee 1012 rule->wmm_rule.client[j].aifsn) ||
d3c89bbc
HD
1013 nla_put_u16(msg, NL80211_WMMR_TXOP,
1014 rule->wmm_rule.client[j].cot))
50f32718
HD
1015 goto nla_put_failure;
1016
1017 nla_nest_end(msg, nl_wmm_rule);
1018 }
1019 nla_nest_end(msg, nl_wmm_rules);
1020
1021 return 0;
1022
1023nla_put_failure:
1024 return -ENOBUFS;
1025}
1026
1027static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
cdc89b97
JB
1028 struct ieee80211_channel *chan,
1029 bool large)
5dab3b8a 1030{
ea077c1c
RL
1031 /* Some channels must be completely excluded from the
1032 * list to protect old user-space tools from breaking
1033 */
1034 if (!large && chan->flags &
1035 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
1036 return 0;
f8d504ca
JB
1037 if (!large && chan->freq_offset)
1038 return 0;
ea077c1c 1039
9360ffd1
DM
1040 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
1041 chan->center_freq))
1042 goto nla_put_failure;
5dab3b8a 1043
942ba88b
TP
1044 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset))
1045 goto nla_put_failure;
1046
9360ffd1
DM
1047 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
1048 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
1049 goto nla_put_failure;
8fe02e16
LR
1050 if (chan->flags & IEEE80211_CHAN_NO_IR) {
1051 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
1052 goto nla_put_failure;
1053 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
1054 goto nla_put_failure;
1055 }
cdc89b97
JB
1056 if (chan->flags & IEEE80211_CHAN_RADAR) {
1057 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
1058 goto nla_put_failure;
1059 if (large) {
1060 u32 time;
1061
1062 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
1063
1064 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
1065 chan->dfs_state))
1066 goto nla_put_failure;
1067 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
1068 time))
1069 goto nla_put_failure;
089027e5
JD
1070 if (nla_put_u32(msg,
1071 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
1072 chan->dfs_cac_ms))
1073 goto nla_put_failure;
cdc89b97
JB
1074 }
1075 }
5dab3b8a 1076
fe1abafd
JB
1077 if (large) {
1078 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
1079 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
1080 goto nla_put_failure;
1081 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
1082 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
1083 goto nla_put_failure;
1084 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
1085 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
1086 goto nla_put_failure;
1087 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
1088 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
1089 goto nla_put_failure;
570dbde1
DS
1090 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
1091 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
1092 goto nla_put_failure;
06f207fc
AN
1093 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
1094 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 1095 goto nla_put_failure;
ea077c1c
RL
1096 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
1097 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
1098 goto nla_put_failure;
1099 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
1100 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
1101 goto nla_put_failure;
1e61d82c
HD
1102 if ((chan->flags & IEEE80211_CHAN_NO_HE) &&
1103 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE))
1104 goto nla_put_failure;
d65a9770
TP
1105 if ((chan->flags & IEEE80211_CHAN_1MHZ) &&
1106 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_1MHZ))
1107 goto nla_put_failure;
1108 if ((chan->flags & IEEE80211_CHAN_2MHZ) &&
1109 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_2MHZ))
1110 goto nla_put_failure;
1111 if ((chan->flags & IEEE80211_CHAN_4MHZ) &&
1112 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_4MHZ))
1113 goto nla_put_failure;
1114 if ((chan->flags & IEEE80211_CHAN_8MHZ) &&
1115 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_8MHZ))
1116 goto nla_put_failure;
1117 if ((chan->flags & IEEE80211_CHAN_16MHZ) &&
1118 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_16MHZ))
1119 goto nla_put_failure;
fe1abafd
JB
1120 }
1121
9360ffd1
DM
1122 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
1123 DBM_TO_MBM(chan->max_power)))
1124 goto nla_put_failure;
5dab3b8a 1125
50f32718
HD
1126 if (large) {
1127 const struct ieee80211_reg_rule *rule =
b88d26d9 1128 freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
50f32718 1129
38cb87ee 1130 if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
50f32718
HD
1131 if (nl80211_msg_put_wmm_rules(msg, rule))
1132 goto nla_put_failure;
1133 }
1134 }
1135
5dab3b8a
LR
1136 return 0;
1137
1138 nla_put_failure:
1139 return -ENOBUFS;
1140}
1141
52539ca8
THJ
1142static bool nl80211_put_txq_stats(struct sk_buff *msg,
1143 struct cfg80211_txq_stats *txqstats,
1144 int attrtype)
1145{
1146 struct nlattr *txqattr;
1147
1148#define PUT_TXQVAL_U32(attr, memb) do { \
1149 if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) && \
1150 nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
1151 return false; \
1152 } while (0)
1153
ae0be8de 1154 txqattr = nla_nest_start_noflag(msg, attrtype);
52539ca8
THJ
1155 if (!txqattr)
1156 return false;
1157
1158 PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
1159 PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
1160 PUT_TXQVAL_U32(FLOWS, flows);
1161 PUT_TXQVAL_U32(DROPS, drops);
1162 PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
1163 PUT_TXQVAL_U32(OVERLIMIT, overlimit);
1164 PUT_TXQVAL_U32(OVERMEMORY, overmemory);
1165 PUT_TXQVAL_U32(COLLISIONS, collisions);
1166 PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
1167 PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
1168 PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
1169 nla_nest_end(msg, txqattr);
1170
1171#undef PUT_TXQVAL_U32
1172 return true;
1173}
1174
55682965
JB
1175/* netlink command implementations */
1176
b9454e83
JB
1177struct key_parse {
1178 struct key_params p;
1179 int idx;
e31b8213 1180 int type;
56be393f 1181 bool def, defmgmt, defbeacon;
dbd2fd65 1182 bool def_uni, def_multi;
b9454e83
JB
1183};
1184
768075eb
JB
1185static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
1186 struct key_parse *k)
b9454e83
JB
1187{
1188 struct nlattr *tb[NL80211_KEY_MAX + 1];
8cb08174
JB
1189 int err = nla_parse_nested_deprecated(tb, NL80211_KEY_MAX, key,
1190 nl80211_key_policy,
1191 info->extack);
b9454e83
JB
1192 if (err)
1193 return err;
1194
1195 k->def = !!tb[NL80211_KEY_DEFAULT];
1196 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
56be393f 1197 k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
b9454e83 1198
dbd2fd65
JB
1199 if (k->def) {
1200 k->def_uni = true;
1201 k->def_multi = true;
1202 }
56be393f 1203 if (k->defmgmt || k->defbeacon)
dbd2fd65
JB
1204 k->def_multi = true;
1205
b9454e83
JB
1206 if (tb[NL80211_KEY_IDX])
1207 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
1208
1209 if (tb[NL80211_KEY_DATA]) {
1210 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
1211 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
1212 }
1213
1214 if (tb[NL80211_KEY_SEQ]) {
1215 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
1216 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
1217 }
1218
1219 if (tb[NL80211_KEY_CIPHER])
1220 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
1221
ab0d76f6 1222 if (tb[NL80211_KEY_TYPE])
e31b8213 1223 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
e31b8213 1224
dbd2fd65
JB
1225 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
1226 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 1227
8cb08174
JB
1228 err = nla_parse_nested_deprecated(kdt,
1229 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1230 tb[NL80211_KEY_DEFAULT_TYPES],
1231 nl80211_key_default_policy,
1232 info->extack);
dbd2fd65
JB
1233 if (err)
1234 return err;
1235
1236 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1237 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1238 }
1239
6cdd3979
AW
1240 if (tb[NL80211_KEY_MODE])
1241 k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
1242
b9454e83
JB
1243 return 0;
1244}
1245
1246static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
1247{
1248 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
1249 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
1250 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1251 }
1252
1253 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1254 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1255 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1256 }
1257
1258 if (info->attrs[NL80211_ATTR_KEY_IDX])
1259 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1260
1261 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
1262 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1263
1264 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
1265 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
1266
dbd2fd65
JB
1267 if (k->def) {
1268 k->def_uni = true;
1269 k->def_multi = true;
1270 }
1271 if (k->defmgmt)
1272 k->def_multi = true;
1273
ab0d76f6 1274 if (info->attrs[NL80211_ATTR_KEY_TYPE])
e31b8213 1275 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
e31b8213 1276
dbd2fd65
JB
1277 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
1278 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
8cb08174
JB
1279 int err = nla_parse_nested_deprecated(kdt,
1280 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1281 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
1282 nl80211_key_default_policy,
1283 info->extack);
dbd2fd65
JB
1284 if (err)
1285 return err;
1286
1287 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1288 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1289 }
1290
b9454e83
JB
1291 return 0;
1292}
1293
1294static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
1295{
1296 int err;
1297
1298 memset(k, 0, sizeof(*k));
1299 k->idx = -1;
e31b8213 1300 k->type = -1;
b9454e83
JB
1301
1302 if (info->attrs[NL80211_ATTR_KEY])
768075eb 1303 err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
b9454e83
JB
1304 else
1305 err = nl80211_parse_key_old(info, k);
1306
1307 if (err)
1308 return err;
1309
56be393f
JM
1310 if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
1311 (k->defbeacon ? 1 : 0) > 1) {
1312 GENL_SET_ERR_MSG(info,
1313 "key with multiple default flags is invalid");
b9454e83 1314 return -EINVAL;
768075eb 1315 }
b9454e83 1316
56be393f 1317 if (k->defmgmt || k->defbeacon) {
768075eb 1318 if (k->def_uni || !k->def_multi) {
56be393f
JM
1319 GENL_SET_ERR_MSG(info,
1320 "defmgmt/defbeacon key must be mcast");
dbd2fd65 1321 return -EINVAL;
768075eb 1322 }
dbd2fd65
JB
1323 }
1324
b9454e83
JB
1325 if (k->idx != -1) {
1326 if (k->defmgmt) {
768075eb
JB
1327 if (k->idx < 4 || k->idx > 5) {
1328 GENL_SET_ERR_MSG(info,
1329 "defmgmt key idx not 4 or 5");
b9454e83 1330 return -EINVAL;
768075eb 1331 }
56be393f
JM
1332 } else if (k->defbeacon) {
1333 if (k->idx < 6 || k->idx > 7) {
1334 GENL_SET_ERR_MSG(info,
1335 "defbeacon key idx not 6 or 7");
1336 return -EINVAL;
1337 }
b9454e83 1338 } else if (k->def) {
768075eb
JB
1339 if (k->idx < 0 || k->idx > 3) {
1340 GENL_SET_ERR_MSG(info, "def key idx not 0-3");
b9454e83 1341 return -EINVAL;
768075eb 1342 }
b9454e83 1343 } else {
56be393f
JM
1344 if (k->idx < 0 || k->idx > 7) {
1345 GENL_SET_ERR_MSG(info, "key idx not 0-7");
b9454e83 1346 return -EINVAL;
768075eb 1347 }
b9454e83
JB
1348 }
1349 }
1350
1351 return 0;
1352}
1353
fffd0934
JB
1354static struct cfg80211_cached_keys *
1355nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
768075eb 1356 struct genl_info *info, bool *no_ht)
fffd0934 1357{
768075eb 1358 struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
fffd0934
JB
1359 struct key_parse parse;
1360 struct nlattr *key;
1361 struct cfg80211_cached_keys *result;
1362 int rem, err, def = 0;
f1c1f17a
JB
1363 bool have_key = false;
1364
1365 nla_for_each_nested(key, keys, rem) {
1366 have_key = true;
1367 break;
1368 }
1369
1370 if (!have_key)
1371 return NULL;
fffd0934
JB
1372
1373 result = kzalloc(sizeof(*result), GFP_KERNEL);
1374 if (!result)
1375 return ERR_PTR(-ENOMEM);
1376
1377 result->def = -1;
fffd0934
JB
1378
1379 nla_for_each_nested(key, keys, rem) {
1380 memset(&parse, 0, sizeof(parse));
1381 parse.idx = -1;
1382
768075eb 1383 err = nl80211_parse_key_new(info, key, &parse);
fffd0934
JB
1384 if (err)
1385 goto error;
1386 err = -EINVAL;
1387 if (!parse.p.key)
1388 goto error;
768075eb
JB
1389 if (parse.idx < 0 || parse.idx > 3) {
1390 GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
fffd0934 1391 goto error;
768075eb 1392 }
fffd0934 1393 if (parse.def) {
768075eb
JB
1394 if (def) {
1395 GENL_SET_ERR_MSG(info,
1396 "only one key can be default");
fffd0934 1397 goto error;
768075eb 1398 }
fffd0934
JB
1399 def = 1;
1400 result->def = parse.idx;
dbd2fd65
JB
1401 if (!parse.def_uni || !parse.def_multi)
1402 goto error;
fffd0934
JB
1403 } else if (parse.defmgmt)
1404 goto error;
1405 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 1406 parse.idx, false, NULL);
fffd0934
JB
1407 if (err)
1408 goto error;
386b1f27
JB
1409 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1410 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
768075eb 1411 GENL_SET_ERR_MSG(info, "connect key must be WEP");
386b1f27
JB
1412 err = -EINVAL;
1413 goto error;
1414 }
fffd0934
JB
1415 result->params[parse.idx].cipher = parse.p.cipher;
1416 result->params[parse.idx].key_len = parse.p.key_len;
1417 result->params[parse.idx].key = result->data[parse.idx];
1418 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 1419
386b1f27
JB
1420 /* must be WEP key if we got here */
1421 if (no_ht)
1422 *no_ht = true;
fffd0934
JB
1423 }
1424
f1c1f17a
JB
1425 if (result->def < 0) {
1426 err = -EINVAL;
768075eb 1427 GENL_SET_ERR_MSG(info, "need a default/TX key");
f1c1f17a
JB
1428 goto error;
1429 }
1430
fffd0934
JB
1431 return result;
1432 error:
1433 kfree(result);
1434 return ERR_PTR(err);
1435}
1436
1437static int nl80211_key_allowed(struct wireless_dev *wdev)
1438{
1439 ASSERT_WDEV_LOCK(wdev);
1440
fffd0934
JB
1441 switch (wdev->iftype) {
1442 case NL80211_IFTYPE_AP:
1443 case NL80211_IFTYPE_AP_VLAN:
074ac8df 1444 case NL80211_IFTYPE_P2P_GO:
ff973af7 1445 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
1446 break;
1447 case NL80211_IFTYPE_ADHOC:
fffd0934 1448 case NL80211_IFTYPE_STATION:
074ac8df 1449 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 1450 if (!wdev->current_bss)
fffd0934
JB
1451 return -ENOLINK;
1452 break;
de4fcbad 1453 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 1454 case NL80211_IFTYPE_OCB:
de4fcbad 1455 case NL80211_IFTYPE_MONITOR:
cb3b7d87 1456 case NL80211_IFTYPE_NAN:
de4fcbad
JB
1457 case NL80211_IFTYPE_P2P_DEVICE:
1458 case NL80211_IFTYPE_WDS:
1459 case NUM_NL80211_IFTYPES:
fffd0934
JB
1460 return -EINVAL;
1461 }
1462
1463 return 0;
1464}
1465
664834de 1466static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
942ba88b 1467 u32 freq)
664834de
JM
1468{
1469 struct ieee80211_channel *chan;
1470
942ba88b 1471 chan = ieee80211_get_channel_khz(wiphy, freq);
664834de
JM
1472 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1473 return NULL;
1474 return chan;
1475}
1476
7527a782
JB
1477static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1478{
ae0be8de 1479 struct nlattr *nl_modes = nla_nest_start_noflag(msg, attr);
7527a782
JB
1480 int i;
1481
1482 if (!nl_modes)
1483 goto nla_put_failure;
1484
1485 i = 0;
1486 while (ifmodes) {
9360ffd1
DM
1487 if ((ifmodes & 1) && nla_put_flag(msg, i))
1488 goto nla_put_failure;
7527a782
JB
1489 ifmodes >>= 1;
1490 i++;
1491 }
1492
1493 nla_nest_end(msg, nl_modes);
1494 return 0;
1495
1496nla_put_failure:
1497 return -ENOBUFS;
1498}
1499
1500static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1501 struct sk_buff *msg,
1502 bool large)
7527a782
JB
1503{
1504 struct nlattr *nl_combis;
1505 int i, j;
1506
ae0be8de
MK
1507 nl_combis = nla_nest_start_noflag(msg,
1508 NL80211_ATTR_INTERFACE_COMBINATIONS);
7527a782
JB
1509 if (!nl_combis)
1510 goto nla_put_failure;
1511
1512 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1513 const struct ieee80211_iface_combination *c;
1514 struct nlattr *nl_combi, *nl_limits;
1515
1516 c = &wiphy->iface_combinations[i];
1517
ae0be8de 1518 nl_combi = nla_nest_start_noflag(msg, i + 1);
7527a782
JB
1519 if (!nl_combi)
1520 goto nla_put_failure;
1521
ae0be8de
MK
1522 nl_limits = nla_nest_start_noflag(msg,
1523 NL80211_IFACE_COMB_LIMITS);
7527a782
JB
1524 if (!nl_limits)
1525 goto nla_put_failure;
1526
1527 for (j = 0; j < c->n_limits; j++) {
1528 struct nlattr *nl_limit;
1529
ae0be8de 1530 nl_limit = nla_nest_start_noflag(msg, j + 1);
7527a782
JB
1531 if (!nl_limit)
1532 goto nla_put_failure;
9360ffd1
DM
1533 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1534 c->limits[j].max))
1535 goto nla_put_failure;
7527a782
JB
1536 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1537 c->limits[j].types))
1538 goto nla_put_failure;
1539 nla_nest_end(msg, nl_limit);
1540 }
1541
1542 nla_nest_end(msg, nl_limits);
1543
9360ffd1
DM
1544 if (c->beacon_int_infra_match &&
1545 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1546 goto nla_put_failure;
1547 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1548 c->num_different_channels) ||
1549 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1550 c->max_interfaces))
1551 goto nla_put_failure;
cdc89b97 1552 if (large &&
8c48b50a
FF
1553 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1554 c->radar_detect_widths) ||
1555 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1556 c->radar_detect_regions)))
cdc89b97 1557 goto nla_put_failure;
0c317a02
PK
1558 if (c->beacon_int_min_gcd &&
1559 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1560 c->beacon_int_min_gcd))
1561 goto nla_put_failure;
7527a782
JB
1562
1563 nla_nest_end(msg, nl_combi);
1564 }
1565
1566 nla_nest_end(msg, nl_combis);
1567
1568 return 0;
1569nla_put_failure:
1570 return -ENOBUFS;
1571}
1572
3713b4e3 1573#ifdef CONFIG_PM
b56cf720
JB
1574static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1575 struct sk_buff *msg)
1576{
964dc9e2 1577 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1578 struct nlattr *nl_tcp;
1579
1580 if (!tcp)
1581 return 0;
1582
ae0be8de
MK
1583 nl_tcp = nla_nest_start_noflag(msg,
1584 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
b56cf720
JB
1585 if (!nl_tcp)
1586 return -ENOBUFS;
1587
1588 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1589 tcp->data_payload_max))
1590 return -ENOBUFS;
1591
1592 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1593 tcp->data_payload_max))
1594 return -ENOBUFS;
1595
1596 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1597 return -ENOBUFS;
1598
1599 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1600 sizeof(*tcp->tok), tcp->tok))
1601 return -ENOBUFS;
1602
1603 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1604 tcp->data_interval_max))
1605 return -ENOBUFS;
1606
1607 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1608 tcp->wake_payload_max))
1609 return -ENOBUFS;
1610
1611 nla_nest_end(msg, nl_tcp);
1612 return 0;
1613}
1614
3713b4e3 1615static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1616 struct cfg80211_registered_device *rdev,
b56cf720 1617 bool large)
55682965 1618{
3713b4e3 1619 struct nlattr *nl_wowlan;
55682965 1620
1b8ec87a 1621 if (!rdev->wiphy.wowlan)
3713b4e3 1622 return 0;
55682965 1623
ae0be8de
MK
1624 nl_wowlan = nla_nest_start_noflag(msg,
1625 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
3713b4e3
JB
1626 if (!nl_wowlan)
1627 return -ENOBUFS;
9360ffd1 1628
1b8ec87a 1629 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1630 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1631 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1632 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1633 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1634 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1635 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1636 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1637 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1638 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1639 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1640 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1641 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1642 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1643 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1644 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1645 return -ENOBUFS;
9360ffd1 1646
1b8ec87a 1647 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1648 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1649 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1650 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1651 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1652 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1653 };
9360ffd1 1654
3713b4e3
JB
1655 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1656 sizeof(pat), &pat))
1657 return -ENOBUFS;
1658 }
9360ffd1 1659
75453ccb
LC
1660 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1661 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1662 rdev->wiphy.wowlan->max_nd_match_sets))
1663 return -ENOBUFS;
1664
1b8ec87a 1665 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1666 return -ENOBUFS;
1667
3713b4e3 1668 nla_nest_end(msg, nl_wowlan);
9360ffd1 1669
3713b4e3
JB
1670 return 0;
1671}
1672#endif
9360ffd1 1673
be29b99a 1674static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1675 struct cfg80211_registered_device *rdev)
be29b99a
AK
1676{
1677 struct nl80211_coalesce_rule_support rule;
1678
1b8ec87a 1679 if (!rdev->wiphy.coalesce)
be29b99a
AK
1680 return 0;
1681
1b8ec87a
ZG
1682 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1683 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1684 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1685 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1686 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1687 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1688
1689 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1690 return -ENOBUFS;
1691
1692 return 0;
1693}
1694
c4cbaf79
LC
1695static int
1696nl80211_send_iftype_data(struct sk_buff *msg,
22395217 1697 const struct ieee80211_supported_band *sband,
c4cbaf79
LC
1698 const struct ieee80211_sband_iftype_data *iftdata)
1699{
1700 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
1701
1702 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
1703 iftdata->types_mask))
1704 return -ENOBUFS;
1705
1706 if (he_cap->has_he) {
1707 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
1708 sizeof(he_cap->he_cap_elem.mac_cap_info),
1709 he_cap->he_cap_elem.mac_cap_info) ||
1710 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
1711 sizeof(he_cap->he_cap_elem.phy_cap_info),
1712 he_cap->he_cap_elem.phy_cap_info) ||
1713 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
1714 sizeof(he_cap->he_mcs_nss_supp),
1715 &he_cap->he_mcs_nss_supp) ||
1716 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
1717 sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
1718 return -ENOBUFS;
1719 }
1720
22395217
JB
1721 if (sband->band == NL80211_BAND_6GHZ &&
1722 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
1723 sizeof(iftdata->he_6ghz_capa),
1724 &iftdata->he_6ghz_capa))
1725 return -ENOBUFS;
1726
c4cbaf79
LC
1727 return 0;
1728}
1729
3713b4e3 1730static int nl80211_send_band_rateinfo(struct sk_buff *msg,
f8d504ca
JB
1731 struct ieee80211_supported_band *sband,
1732 bool large)
3713b4e3
JB
1733{
1734 struct nlattr *nl_rates, *nl_rate;
1735 struct ieee80211_rate *rate;
1736 int i;
87bbbe22 1737
3713b4e3
JB
1738 /* add HT info */
1739 if (sband->ht_cap.ht_supported &&
1740 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1741 sizeof(sband->ht_cap.mcs),
1742 &sband->ht_cap.mcs) ||
1743 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1744 sband->ht_cap.cap) ||
1745 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1746 sband->ht_cap.ampdu_factor) ||
1747 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1748 sband->ht_cap.ampdu_density)))
1749 return -ENOBUFS;
afe0cbf8 1750
3713b4e3
JB
1751 /* add VHT info */
1752 if (sband->vht_cap.vht_supported &&
1753 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1754 sizeof(sband->vht_cap.vht_mcs),
1755 &sband->vht_cap.vht_mcs) ||
1756 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1757 sband->vht_cap.cap)))
1758 return -ENOBUFS;
f59ac048 1759
f8d504ca 1760 if (large && sband->n_iftype_data) {
c4cbaf79 1761 struct nlattr *nl_iftype_data =
ae0be8de
MK
1762 nla_nest_start_noflag(msg,
1763 NL80211_BAND_ATTR_IFTYPE_DATA);
c4cbaf79
LC
1764 int err;
1765
1766 if (!nl_iftype_data)
1767 return -ENOBUFS;
1768
1769 for (i = 0; i < sband->n_iftype_data; i++) {
1770 struct nlattr *iftdata;
1771
ae0be8de 1772 iftdata = nla_nest_start_noflag(msg, i + 1);
c4cbaf79
LC
1773 if (!iftdata)
1774 return -ENOBUFS;
1775
22395217 1776 err = nl80211_send_iftype_data(msg, sband,
c4cbaf79
LC
1777 &sband->iftype_data[i]);
1778 if (err)
1779 return err;
1780
1781 nla_nest_end(msg, iftdata);
1782 }
1783
1784 nla_nest_end(msg, nl_iftype_data);
1785 }
1786
2a38075c 1787 /* add EDMG info */
f8d504ca 1788 if (large && sband->edmg_cap.channels &&
2a38075c
AAL
1789 (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
1790 sband->edmg_cap.channels) ||
1791 nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
1792 sband->edmg_cap.bw_config)))
1793
1794 return -ENOBUFS;
1795
3713b4e3 1796 /* add bitrates */
ae0be8de 1797 nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
3713b4e3
JB
1798 if (!nl_rates)
1799 return -ENOBUFS;
ee688b00 1800
3713b4e3 1801 for (i = 0; i < sband->n_bitrates; i++) {
ae0be8de 1802 nl_rate = nla_nest_start_noflag(msg, i);
3713b4e3
JB
1803 if (!nl_rate)
1804 return -ENOBUFS;
ee688b00 1805
3713b4e3
JB
1806 rate = &sband->bitrates[i];
1807 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1808 rate->bitrate))
1809 return -ENOBUFS;
1810 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1811 nla_put_flag(msg,
1812 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1813 return -ENOBUFS;
ee688b00 1814
3713b4e3
JB
1815 nla_nest_end(msg, nl_rate);
1816 }
d51626df 1817
3713b4e3 1818 nla_nest_end(msg, nl_rates);
bf0c111e 1819
3713b4e3
JB
1820 return 0;
1821}
ee688b00 1822
3713b4e3
JB
1823static int
1824nl80211_send_mgmt_stypes(struct sk_buff *msg,
1825 const struct ieee80211_txrx_stypes *mgmt_stypes)
1826{
1827 u16 stypes;
1828 struct nlattr *nl_ftypes, *nl_ifs;
1829 enum nl80211_iftype ift;
1830 int i;
ee688b00 1831
3713b4e3
JB
1832 if (!mgmt_stypes)
1833 return 0;
5dab3b8a 1834
ae0be8de 1835 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_TX_FRAME_TYPES);
3713b4e3
JB
1836 if (!nl_ifs)
1837 return -ENOBUFS;
e2f367f2 1838
3713b4e3 1839 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1840 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1841 if (!nl_ftypes)
1842 return -ENOBUFS;
1843 i = 0;
1844 stypes = mgmt_stypes[ift].tx;
1845 while (stypes) {
1846 if ((stypes & 1) &&
1847 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1848 (i << 4) | IEEE80211_FTYPE_MGMT))
1849 return -ENOBUFS;
1850 stypes >>= 1;
1851 i++;
ee688b00 1852 }
3713b4e3
JB
1853 nla_nest_end(msg, nl_ftypes);
1854 }
ee688b00 1855
3713b4e3 1856 nla_nest_end(msg, nl_ifs);
ee688b00 1857
ae0be8de 1858 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_RX_FRAME_TYPES);
3713b4e3
JB
1859 if (!nl_ifs)
1860 return -ENOBUFS;
ee688b00 1861
3713b4e3 1862 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1863 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1864 if (!nl_ftypes)
1865 return -ENOBUFS;
1866 i = 0;
1867 stypes = mgmt_stypes[ift].rx;
1868 while (stypes) {
1869 if ((stypes & 1) &&
1870 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1871 (i << 4) | IEEE80211_FTYPE_MGMT))
1872 return -ENOBUFS;
1873 stypes >>= 1;
1874 i++;
1875 }
1876 nla_nest_end(msg, nl_ftypes);
1877 }
1878 nla_nest_end(msg, nl_ifs);
ee688b00 1879
3713b4e3
JB
1880 return 0;
1881}
ee688b00 1882
1794899e
JB
1883#define CMD(op, n) \
1884 do { \
1885 if (rdev->ops->op) { \
1886 i++; \
1887 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1888 goto nla_put_failure; \
1889 } \
1890 } while (0)
1891
1892static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1893 struct sk_buff *msg)
1894{
1895 int i = 0;
1896
1897 /*
1898 * do *NOT* add anything into this function, new things need to be
1899 * advertised only to new versions of userspace that can deal with
1900 * the split (and they can't possibly care about new features...
1901 */
1902 CMD(add_virtual_intf, NEW_INTERFACE);
1903 CMD(change_virtual_intf, SET_INTERFACE);
1904 CMD(add_key, NEW_KEY);
1905 CMD(start_ap, START_AP);
1906 CMD(add_station, NEW_STATION);
1907 CMD(add_mpath, NEW_MPATH);
1908 CMD(update_mesh_config, SET_MESH_CONFIG);
1909 CMD(change_bss, SET_BSS);
1910 CMD(auth, AUTHENTICATE);
1911 CMD(assoc, ASSOCIATE);
1912 CMD(deauth, DEAUTHENTICATE);
1913 CMD(disassoc, DISASSOCIATE);
1914 CMD(join_ibss, JOIN_IBSS);
1915 CMD(join_mesh, JOIN_MESH);
1916 CMD(set_pmksa, SET_PMKSA);
1917 CMD(del_pmksa, DEL_PMKSA);
1918 CMD(flush_pmksa, FLUSH_PMKSA);
1919 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1920 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1921 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1922 CMD(mgmt_tx, FRAME);
1923 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1924 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1925 i++;
1926 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1927 goto nla_put_failure;
1928 }
1929 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1930 rdev->ops->join_mesh) {
1931 i++;
1932 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1933 goto nla_put_failure;
1934 }
1794899e
JB
1935 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1936 CMD(tdls_mgmt, TDLS_MGMT);
1937 CMD(tdls_oper, TDLS_OPER);
1938 }
ca986ad9 1939 if (rdev->wiphy.max_sched_scan_reqs)
1794899e
JB
1940 CMD(sched_scan_start, START_SCHED_SCAN);
1941 CMD(probe_client, PROBE_CLIENT);
1942 CMD(set_noack_map, SET_NOACK_MAP);
1943 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1944 i++;
1945 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1946 goto nla_put_failure;
1947 }
1948 CMD(start_p2p_device, START_P2P_DEVICE);
1949 CMD(set_mcast_rate, SET_MCAST_RATE);
1950#ifdef CONFIG_NL80211_TESTMODE
1951 CMD(testmode_cmd, TESTMODE);
1952#endif
1953
1954 if (rdev->ops->connect || rdev->ops->auth) {
1955 i++;
1956 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1957 goto nla_put_failure;
1958 }
1959
1960 if (rdev->ops->disconnect || rdev->ops->deauth) {
1961 i++;
1962 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1963 goto nla_put_failure;
1964 }
1965
1966 return i;
1967 nla_put_failure:
1968 return -ENOBUFS;
1969}
1970
9bb7e0f2
JB
1971static int
1972nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
1973 struct sk_buff *msg)
1974{
1975 struct nlattr *ftm;
1976
1977 if (!cap->ftm.supported)
1978 return 0;
1979
ae0be8de 1980 ftm = nla_nest_start_noflag(msg, NL80211_PMSR_TYPE_FTM);
9bb7e0f2
JB
1981 if (!ftm)
1982 return -ENOBUFS;
1983
1984 if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
1985 return -ENOBUFS;
1986 if (cap->ftm.non_asap &&
1987 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
1988 return -ENOBUFS;
1989 if (cap->ftm.request_lci &&
1990 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
1991 return -ENOBUFS;
1992 if (cap->ftm.request_civicloc &&
1993 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
1994 return -ENOBUFS;
1995 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
1996 cap->ftm.preambles))
1997 return -ENOBUFS;
1998 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
1999 cap->ftm.bandwidths))
2000 return -ENOBUFS;
2001 if (cap->ftm.max_bursts_exponent >= 0 &&
2002 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
2003 cap->ftm.max_bursts_exponent))
2004 return -ENOBUFS;
2005 if (cap->ftm.max_ftms_per_burst &&
2006 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
2007 cap->ftm.max_ftms_per_burst))
2008 return -ENOBUFS;
efb5520d
AS
2009 if (cap->ftm.trigger_based &&
2010 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED))
2011 return -ENOBUFS;
2012 if (cap->ftm.non_trigger_based &&
2013 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED))
2014 return -ENOBUFS;
9bb7e0f2
JB
2015
2016 nla_nest_end(msg, ftm);
2017 return 0;
2018}
2019
2020static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
2021 struct sk_buff *msg)
2022{
2023 const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
2024 struct nlattr *pmsr, *caps;
2025
2026 if (!cap)
2027 return 0;
2028
2029 /*
2030 * we don't need to clean up anything here since the caller
2031 * will genlmsg_cancel() if we fail
2032 */
2033
ae0be8de 2034 pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
9bb7e0f2
JB
2035 if (!pmsr)
2036 return -ENOBUFS;
2037
2038 if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
2039 return -ENOBUFS;
2040
2041 if (cap->report_ap_tsf &&
2042 nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
2043 return -ENOBUFS;
2044
2045 if (cap->randomize_mac_addr &&
2046 nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
2047 return -ENOBUFS;
2048
ae0be8de 2049 caps = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
9bb7e0f2
JB
2050 if (!caps)
2051 return -ENOBUFS;
2052
2053 if (nl80211_send_pmsr_ftm_capa(cap, msg))
2054 return -ENOBUFS;
2055
2056 nla_nest_end(msg, caps);
2057 nla_nest_end(msg, pmsr);
2058
2059 return 0;
2060}
2061
d6039a34
VJ
2062static int
2063nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
2064 struct sk_buff *msg)
2065{
2066 int i;
2067 struct nlattr *nested, *nested_akms;
2068 const struct wiphy_iftype_akm_suites *iftype_akms;
2069
2070 if (!rdev->wiphy.num_iftype_akm_suites ||
2071 !rdev->wiphy.iftype_akm_suites)
2072 return 0;
2073
2074 nested = nla_nest_start(msg, NL80211_ATTR_IFTYPE_AKM_SUITES);
2075 if (!nested)
2076 return -ENOBUFS;
2077
2078 for (i = 0; i < rdev->wiphy.num_iftype_akm_suites; i++) {
2079 nested_akms = nla_nest_start(msg, i + 1);
2080 if (!nested_akms)
2081 return -ENOBUFS;
2082
2083 iftype_akms = &rdev->wiphy.iftype_akm_suites[i];
2084
2085 if (nl80211_put_iftypes(msg, NL80211_IFTYPE_AKM_ATTR_IFTYPES,
2086 iftype_akms->iftypes_mask))
2087 return -ENOBUFS;
2088
2089 if (nla_put(msg, NL80211_IFTYPE_AKM_ATTR_SUITES,
2090 sizeof(u32) * iftype_akms->n_akm_suites,
2091 iftype_akms->akm_suites)) {
2092 return -ENOBUFS;
2093 }
2094 nla_nest_end(msg, nested_akms);
2095 }
2096
2097 nla_nest_end(msg, nested);
2098
2099 return 0;
2100}
2101
3710a8a6
JB
2102static int
2103nl80211_put_tid_config_support(struct cfg80211_registered_device *rdev,
2104 struct sk_buff *msg)
2105{
2106 struct nlattr *supp;
2107
2108 if (!rdev->wiphy.tid_config_support.vif &&
2109 !rdev->wiphy.tid_config_support.peer)
2110 return 0;
2111
2112 supp = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
2113 if (!supp)
2114 return -ENOSPC;
2115
2116 if (rdev->wiphy.tid_config_support.vif &&
2117 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_VIF_SUPP,
2118 rdev->wiphy.tid_config_support.vif,
2119 NL80211_TID_CONFIG_ATTR_PAD))
2120 goto fail;
2121
2122 if (rdev->wiphy.tid_config_support.peer &&
2123 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_PEER_SUPP,
2124 rdev->wiphy.tid_config_support.peer,
2125 NL80211_TID_CONFIG_ATTR_PAD))
2126 goto fail;
2127
6a21d16c
T
2128 /* for now we just use the same value ... makes more sense */
2129 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
2130 rdev->wiphy.tid_config_support.max_retry))
2131 goto fail;
2132 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG,
2133 rdev->wiphy.tid_config_support.max_retry))
2134 goto fail;
2135
3710a8a6
JB
2136 nla_nest_end(msg, supp);
2137
2138 return 0;
2139fail:
2140 nla_nest_cancel(msg, supp);
2141 return -ENOBUFS;
2142}
2143
6bdb68ce
CH
2144static int
2145nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
2146 struct sk_buff *msg)
2147{
2148 struct nlattr *sar_capa, *specs, *sub_freq_range;
2149 u8 num_freq_ranges;
2150 int i;
2151
2152 if (!rdev->wiphy.sar_capa)
2153 return 0;
2154
2155 num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
2156
2157 sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
2158 if (!sar_capa)
2159 return -ENOSPC;
2160
2161 if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
2162 goto fail;
2163
2164 specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
2165 if (!specs)
2166 goto fail;
2167
2168 /* report supported freq_ranges */
2169 for (i = 0; i < num_freq_ranges; i++) {
2170 sub_freq_range = nla_nest_start(msg, i + 1);
2171 if (!sub_freq_range)
2172 goto fail;
2173
2174 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
2175 rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
2176 goto fail;
2177
2178 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
2179 rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
2180 goto fail;
2181
2182 nla_nest_end(msg, sub_freq_range);
2183 }
2184
2185 nla_nest_end(msg, specs);
2186 nla_nest_end(msg, sar_capa);
2187
2188 return 0;
2189fail:
2190 nla_nest_cancel(msg, sar_capa);
2191 return -ENOBUFS;
2192}
2193
86e8cf98
JB
2194struct nl80211_dump_wiphy_state {
2195 s64 filter_wiphy;
2196 long start;
019ae3a9 2197 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
2198 bool split;
2199};
2200
1b8ec87a 2201static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 2202 enum nl80211_commands cmd,
3713b4e3 2203 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 2204 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
2205{
2206 void *hdr;
2207 struct nlattr *nl_bands, *nl_band;
2208 struct nlattr *nl_freqs, *nl_freq;
2209 struct nlattr *nl_cmds;
57fbcce3 2210 enum nl80211_band band;
3713b4e3
JB
2211 struct ieee80211_channel *chan;
2212 int i;
2213 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 2214 rdev->wiphy.mgmt_stypes;
fe1abafd 2215 u32 features;
ee688b00 2216
3bb20556 2217 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
2218 if (!hdr)
2219 return -ENOBUFS;
ee688b00 2220
86e8cf98
JB
2221 if (WARN_ON(!state))
2222 return -EINVAL;
ee688b00 2223
1b8ec87a 2224 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 2225 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 2226 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
2227 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2228 cfg80211_rdev_list_generation))
8fdc621d
JB
2229 goto nla_put_failure;
2230
3bb20556
JB
2231 if (cmd != NL80211_CMD_NEW_WIPHY)
2232 goto finish;
2233
86e8cf98 2234 switch (state->split_start) {
3713b4e3
JB
2235 case 0:
2236 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 2237 rdev->wiphy.retry_short) ||
3713b4e3 2238 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 2239 rdev->wiphy.retry_long) ||
3713b4e3 2240 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 2241 rdev->wiphy.frag_threshold) ||
3713b4e3 2242 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 2243 rdev->wiphy.rts_threshold) ||
3713b4e3 2244 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 2245 rdev->wiphy.coverage_class) ||
3713b4e3 2246 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 2247 rdev->wiphy.max_scan_ssids) ||
3713b4e3 2248 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 2249 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 2250 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 2251 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 2252 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 2253 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 2254 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
f8d504ca 2255 rdev->wiphy.max_match_sets))
9360ffd1 2256 goto nla_put_failure;
3713b4e3 2257
1b8ec87a 2258 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 2259 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 2260 goto nla_put_failure;
1b8ec87a 2261 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
2262 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
2263 goto nla_put_failure;
1b8ec87a 2264 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
2265 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
2266 goto nla_put_failure;
1b8ec87a 2267 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
2268 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
2269 goto nla_put_failure;
1b8ec87a 2270 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
2271 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
2272 goto nla_put_failure;
1b8ec87a 2273 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 2274 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 2275 goto nla_put_failure;
86e8cf98
JB
2276 state->split_start++;
2277 if (state->split)
3713b4e3 2278 break;
7b506ff6 2279 fallthrough;
3713b4e3
JB
2280 case 1:
2281 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
2282 sizeof(u32) * rdev->wiphy.n_cipher_suites,
2283 rdev->wiphy.cipher_suites))
3713b4e3 2284 goto nla_put_failure;
4745fc09 2285
3713b4e3 2286 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 2287 rdev->wiphy.max_num_pmkids))
3713b4e3 2288 goto nla_put_failure;
b23aa676 2289
1b8ec87a 2290 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 2291 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 2292 goto nla_put_failure;
b23aa676 2293
3713b4e3 2294 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 2295 rdev->wiphy.available_antennas_tx) ||
3713b4e3 2296 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 2297 rdev->wiphy.available_antennas_rx))
9360ffd1 2298 goto nla_put_failure;
b23aa676 2299
1b8ec87a 2300 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 2301 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 2302 rdev->wiphy.probe_resp_offload))
3713b4e3 2303 goto nla_put_failure;
8fdc621d 2304
1b8ec87a
ZG
2305 if ((rdev->wiphy.available_antennas_tx ||
2306 rdev->wiphy.available_antennas_rx) &&
2307 rdev->ops->get_antenna) {
3713b4e3
JB
2308 u32 tx_ant = 0, rx_ant = 0;
2309 int res;
7a087e74 2310
1b8ec87a 2311 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
2312 if (!res) {
2313 if (nla_put_u32(msg,
2314 NL80211_ATTR_WIPHY_ANTENNA_TX,
2315 tx_ant) ||
2316 nla_put_u32(msg,
2317 NL80211_ATTR_WIPHY_ANTENNA_RX,
2318 rx_ant))
2319 goto nla_put_failure;
2320 }
2321 }
a293911d 2322
86e8cf98
JB
2323 state->split_start++;
2324 if (state->split)
3713b4e3 2325 break;
7b506ff6 2326 fallthrough;
3713b4e3
JB
2327 case 2:
2328 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 2329 rdev->wiphy.interface_modes))
3713b4e3 2330 goto nla_put_failure;
86e8cf98
JB
2331 state->split_start++;
2332 if (state->split)
3713b4e3 2333 break;
7b506ff6 2334 fallthrough;
3713b4e3 2335 case 3:
ae0be8de
MK
2336 nl_bands = nla_nest_start_noflag(msg,
2337 NL80211_ATTR_WIPHY_BANDS);
3713b4e3
JB
2338 if (!nl_bands)
2339 goto nla_put_failure;
f7ca38df 2340
86e8cf98 2341 for (band = state->band_start;
57fbcce3 2342 band < NUM_NL80211_BANDS; band++) {
3713b4e3 2343 struct ieee80211_supported_band *sband;
2e161f78 2344
f8d504ca
JB
2345 /* omit higher bands for ancient software */
2346 if (band > NL80211_BAND_5GHZ && !state->split)
2347 break;
2348
1b8ec87a 2349 sband = rdev->wiphy.bands[band];
2e161f78 2350
3713b4e3
JB
2351 if (!sband)
2352 continue;
2353
ae0be8de 2354 nl_band = nla_nest_start_noflag(msg, band);
3713b4e3 2355 if (!nl_band)
2e161f78 2356 goto nla_put_failure;
3713b4e3 2357
86e8cf98 2358 switch (state->chan_start) {
3713b4e3 2359 case 0:
f8d504ca
JB
2360 if (nl80211_send_band_rateinfo(msg, sband,
2361 state->split))
9360ffd1 2362 goto nla_put_failure;
86e8cf98
JB
2363 state->chan_start++;
2364 if (state->split)
3713b4e3 2365 break;
7b506ff6 2366 fallthrough;
3713b4e3
JB
2367 default:
2368 /* add frequencies */
ae0be8de
MK
2369 nl_freqs = nla_nest_start_noflag(msg,
2370 NL80211_BAND_ATTR_FREQS);
3713b4e3
JB
2371 if (!nl_freqs)
2372 goto nla_put_failure;
2373
86e8cf98 2374 for (i = state->chan_start - 1;
3713b4e3
JB
2375 i < sband->n_channels;
2376 i++) {
ae0be8de
MK
2377 nl_freq = nla_nest_start_noflag(msg,
2378 i);
3713b4e3
JB
2379 if (!nl_freq)
2380 goto nla_put_failure;
2381
2382 chan = &sband->channels[i];
2383
86e8cf98 2384 if (nl80211_msg_put_channel(
50f32718 2385 msg, &rdev->wiphy, chan,
86e8cf98 2386 state->split))
3713b4e3
JB
2387 goto nla_put_failure;
2388
2389 nla_nest_end(msg, nl_freq);
86e8cf98 2390 if (state->split)
3713b4e3
JB
2391 break;
2392 }
2393 if (i < sband->n_channels)
86e8cf98 2394 state->chan_start = i + 2;
3713b4e3 2395 else
86e8cf98 2396 state->chan_start = 0;
3713b4e3
JB
2397 nla_nest_end(msg, nl_freqs);
2398 }
2399
2400 nla_nest_end(msg, nl_band);
2401
86e8cf98 2402 if (state->split) {
3713b4e3 2403 /* start again here */
86e8cf98 2404 if (state->chan_start)
3713b4e3
JB
2405 band--;
2406 break;
2e161f78 2407 }
2e161f78 2408 }
3713b4e3 2409 nla_nest_end(msg, nl_bands);
2e161f78 2410
57fbcce3 2411 if (band < NUM_NL80211_BANDS)
86e8cf98 2412 state->band_start = band + 1;
3713b4e3 2413 else
86e8cf98 2414 state->band_start = 0;
74b70a4e 2415
3713b4e3 2416 /* if bands & channels are done, continue outside */
86e8cf98
JB
2417 if (state->band_start == 0 && state->chan_start == 0)
2418 state->split_start++;
2419 if (state->split)
3713b4e3 2420 break;
7b506ff6 2421 fallthrough;
3713b4e3 2422 case 4:
ae0be8de
MK
2423 nl_cmds = nla_nest_start_noflag(msg,
2424 NL80211_ATTR_SUPPORTED_COMMANDS);
3713b4e3 2425 if (!nl_cmds)
2e161f78
JB
2426 goto nla_put_failure;
2427
1794899e
JB
2428 i = nl80211_add_commands_unsplit(rdev, msg);
2429 if (i < 0)
2430 goto nla_put_failure;
86e8cf98 2431 if (state->split) {
5de17984
AS
2432 CMD(crit_proto_start, CRIT_PROTOCOL_START);
2433 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 2434 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 2435 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 2436 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
2437 if (rdev->wiphy.features &
2438 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 2439 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 2440 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 2441 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
7010998c 2442 CMD(update_ft_ies, UPDATE_FT_IES);
6bdb68ce
CH
2443 if (rdev->wiphy.sar_capa)
2444 CMD(set_sar_specs, SET_SAR_SPECS);
5de17984 2445 }
3713b4e3 2446#undef CMD
ff1b6e69 2447
3713b4e3 2448 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
2449 state->split_start++;
2450 if (state->split)
3713b4e3 2451 break;
7b506ff6 2452 fallthrough;
3713b4e3 2453 case 5:
1b8ec87a
ZG
2454 if (rdev->ops->remain_on_channel &&
2455 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
2456 nla_put_u32(msg,
2457 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 2458 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
2459 goto nla_put_failure;
2460
1b8ec87a 2461 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
2462 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
2463 goto nla_put_failure;
2464
86e8cf98
JB
2465 state->split_start++;
2466 if (state->split)
3713b4e3 2467 break;
7b506ff6 2468 fallthrough;
3713b4e3
JB
2469 case 6:
2470#ifdef CONFIG_PM
1b8ec87a 2471 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 2472 goto nla_put_failure;
86e8cf98
JB
2473 state->split_start++;
2474 if (state->split)
3713b4e3
JB
2475 break;
2476#else
86e8cf98 2477 state->split_start++;
dfb89c56 2478#endif
7b506ff6 2479 fallthrough;
3713b4e3
JB
2480 case 7:
2481 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 2482 rdev->wiphy.software_iftypes))
3713b4e3 2483 goto nla_put_failure;
ff1b6e69 2484
1b8ec87a 2485 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 2486 state->split))
3713b4e3 2487 goto nla_put_failure;
7527a782 2488
86e8cf98
JB
2489 state->split_start++;
2490 if (state->split)
3713b4e3 2491 break;
7b506ff6 2492 fallthrough;
3713b4e3 2493 case 8:
1b8ec87a 2494 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 2495 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 2496 rdev->wiphy.ap_sme_capa))
3713b4e3 2497 goto nla_put_failure;
7527a782 2498
1b8ec87a 2499 features = rdev->wiphy.features;
fe1abafd
JB
2500 /*
2501 * We can only add the per-channel limit information if the
2502 * dump is split, otherwise it makes it too big. Therefore
2503 * only advertise it in that case.
2504 */
86e8cf98 2505 if (state->split)
fe1abafd
JB
2506 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
2507 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 2508 goto nla_put_failure;
562a7480 2509
1b8ec87a 2510 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 2511 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
2512 sizeof(*rdev->wiphy.ht_capa_mod_mask),
2513 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 2514 goto nla_put_failure;
1f074bd8 2515
1b8ec87a
ZG
2516 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
2517 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 2518 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 2519 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 2520 goto nla_put_failure;
7e7c8926 2521
3713b4e3
JB
2522 /*
2523 * Any information below this point is only available to
2524 * applications that can deal with it being split. This
2525 * helps ensure that newly added capabilities don't break
2526 * older tools by overrunning their buffers.
2527 *
2528 * We still increment split_start so that in the split
2529 * case we'll continue with more data in the next round,
2530 * but break unconditionally so unsplit data stops here.
2531 */
ab10c22b
JB
2532 if (state->split)
2533 state->split_start++;
2534 else
2535 state->split_start = 0;
3713b4e3
JB
2536 break;
2537 case 9:
f8d504ca
JB
2538 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
2539 goto nla_put_failure;
2540
2541 if (nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
2542 rdev->wiphy.max_sched_scan_plans) ||
2543 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
2544 rdev->wiphy.max_sched_scan_plan_interval) ||
2545 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
2546 rdev->wiphy.max_sched_scan_plan_iterations))
2547 goto nla_put_failure;
2548
1b8ec87a 2549 if (rdev->wiphy.extended_capabilities &&
fe1abafd 2550 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
2551 rdev->wiphy.extended_capabilities_len,
2552 rdev->wiphy.extended_capabilities) ||
fe1abafd 2553 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
2554 rdev->wiphy.extended_capabilities_len,
2555 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 2556 goto nla_put_failure;
a50df0c4 2557
1b8ec87a 2558 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 2559 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
2560 sizeof(*rdev->wiphy.vht_capa_mod_mask),
2561 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
2562 goto nla_put_failure;
2563
ae6fa4d5
DK
2564 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
2565 rdev->wiphy.perm_addr))
2566 goto nla_put_failure;
2567
2568 if (!is_zero_ether_addr(rdev->wiphy.addr_mask) &&
2569 nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
2570 rdev->wiphy.addr_mask))
2571 goto nla_put_failure;
2572
2573 if (rdev->wiphy.n_addresses > 1) {
2574 void *attr;
2575
2576 attr = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
2577 if (!attr)
2578 goto nla_put_failure;
2579
2580 for (i = 0; i < rdev->wiphy.n_addresses; i++)
2581 if (nla_put(msg, i + 1, ETH_ALEN,
2582 rdev->wiphy.addresses[i].addr))
2583 goto nla_put_failure;
2584
2585 nla_nest_end(msg, attr);
2586 }
2587
be29b99a
AK
2588 state->split_start++;
2589 break;
2590 case 10:
1b8ec87a 2591 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
2592 goto nla_put_failure;
2593
1b8ec87a 2594 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
2595 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
2596 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
2597 goto nla_put_failure;
b43504cf 2598
1b8ec87a 2599 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 2600 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 2601 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
2602 goto nla_put_failure;
2603
ad7e718c
JB
2604 state->split_start++;
2605 break;
2606 case 11:
1b8ec87a 2607 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
2608 const struct nl80211_vendor_cmd_info *info;
2609 struct nlattr *nested;
2610
ae0be8de
MK
2611 nested = nla_nest_start_noflag(msg,
2612 NL80211_ATTR_VENDOR_DATA);
567ffc35
JB
2613 if (!nested)
2614 goto nla_put_failure;
2615
1b8ec87a
ZG
2616 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
2617 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
2618 if (nla_put(msg, i + 1, sizeof(*info), info))
2619 goto nla_put_failure;
2620 }
2621 nla_nest_end(msg, nested);
2622 }
2623
1b8ec87a 2624 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
2625 const struct nl80211_vendor_cmd_info *info;
2626 struct nlattr *nested;
ad7e718c 2627
ae0be8de
MK
2628 nested = nla_nest_start_noflag(msg,
2629 NL80211_ATTR_VENDOR_EVENTS);
567ffc35 2630 if (!nested)
ad7e718c 2631 goto nla_put_failure;
567ffc35 2632
1b8ec87a
ZG
2633 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
2634 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
2635 if (nla_put(msg, i + 1, sizeof(*info), info))
2636 goto nla_put_failure;
2637 }
2638 nla_nest_end(msg, nested);
2639 }
9a774c78
AO
2640 state->split_start++;
2641 break;
2642 case 12:
2643 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
2644 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
2645 rdev->wiphy.max_num_csa_counters))
2646 goto nla_put_failure;
01e0daa4 2647
1bdd716c
AN
2648 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2649 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
2650 goto nla_put_failure;
2651
ca986ad9
AVS
2652 if (rdev->wiphy.max_sched_scan_reqs &&
2653 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
2654 rdev->wiphy.max_sched_scan_reqs))
2655 goto nla_put_failure;
2656
d75bb06b
GKS
2657 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
2658 sizeof(rdev->wiphy.ext_features),
2659 rdev->wiphy.ext_features))
2660 goto nla_put_failure;
2661
38de03d2
AS
2662 if (rdev->wiphy.bss_select_support) {
2663 struct nlattr *nested;
2664 u32 bss_select_support = rdev->wiphy.bss_select_support;
2665
ae0be8de
MK
2666 nested = nla_nest_start_noflag(msg,
2667 NL80211_ATTR_BSS_SELECT);
38de03d2
AS
2668 if (!nested)
2669 goto nla_put_failure;
2670
2671 i = 0;
2672 while (bss_select_support) {
2673 if ((bss_select_support & 1) &&
2674 nla_put_flag(msg, i))
2675 goto nla_put_failure;
2676 i++;
2677 bss_select_support >>= 1;
2678 }
2679 nla_nest_end(msg, nested);
2680 }
2681
019ae3a9
KV
2682 state->split_start++;
2683 break;
2684 case 13:
2685 if (rdev->wiphy.num_iftype_ext_capab &&
2686 rdev->wiphy.iftype_ext_capab) {
2687 struct nlattr *nested_ext_capab, *nested;
2688
ae0be8de
MK
2689 nested = nla_nest_start_noflag(msg,
2690 NL80211_ATTR_IFTYPE_EXT_CAPA);
019ae3a9
KV
2691 if (!nested)
2692 goto nla_put_failure;
2693
2694 for (i = state->capa_start;
2695 i < rdev->wiphy.num_iftype_ext_capab; i++) {
2696 const struct wiphy_iftype_ext_capab *capab;
2697
2698 capab = &rdev->wiphy.iftype_ext_capab[i];
2699
ae0be8de
MK
2700 nested_ext_capab = nla_nest_start_noflag(msg,
2701 i);
019ae3a9
KV
2702 if (!nested_ext_capab ||
2703 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
2704 capab->iftype) ||
2705 nla_put(msg, NL80211_ATTR_EXT_CAPA,
2706 capab->extended_capabilities_len,
2707 capab->extended_capabilities) ||
2708 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
2709 capab->extended_capabilities_len,
2710 capab->extended_capabilities_mask))
2711 goto nla_put_failure;
2712
2713 nla_nest_end(msg, nested_ext_capab);
2714 if (state->split)
2715 break;
2716 }
2717 nla_nest_end(msg, nested);
2718 if (i < rdev->wiphy.num_iftype_ext_capab) {
2719 state->capa_start = i + 1;
2720 break;
2721 }
2722 }
2723
8585989d
LC
2724 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
2725 rdev->wiphy.nan_supported_bands))
2726 goto nla_put_failure;
2727
52539ca8
THJ
2728 if (wiphy_ext_feature_isset(&rdev->wiphy,
2729 NL80211_EXT_FEATURE_TXQS)) {
2730 struct cfg80211_txq_stats txqstats = {};
2731 int res;
2732
2733 res = rdev_get_txq_stats(rdev, NULL, &txqstats);
2734 if (!res &&
2735 !nl80211_put_txq_stats(msg, &txqstats,
2736 NL80211_ATTR_TXQ_STATS))
2737 goto nla_put_failure;
2738
2739 if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
2740 rdev->wiphy.txq_limit))
2741 goto nla_put_failure;
2742 if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
2743 rdev->wiphy.txq_memory_limit))
2744 goto nla_put_failure;
2745 if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
2746 rdev->wiphy.txq_quantum))
2747 goto nla_put_failure;
2748 }
2749
9bb7e0f2
JB
2750 state->split_start++;
2751 break;
2752 case 14:
2753 if (nl80211_send_pmsr_capa(rdev, msg))
2754 goto nla_put_failure;
2755
ab4dfa20
VJ
2756 state->split_start++;
2757 break;
2758 case 15:
2759 if (rdev->wiphy.akm_suites &&
2760 nla_put(msg, NL80211_ATTR_AKM_SUITES,
2761 sizeof(u32) * rdev->wiphy.n_akm_suites,
2762 rdev->wiphy.akm_suites))
2763 goto nla_put_failure;
2764
d6039a34
VJ
2765 if (nl80211_put_iftype_akm_suites(rdev, msg))
2766 goto nla_put_failure;
2767
3710a8a6
JB
2768 if (nl80211_put_tid_config_support(rdev, msg))
2769 goto nla_put_failure;
6bdb68ce
CH
2770 state->split_start++;
2771 break;
2772 case 16:
2773 if (nl80211_put_sar_specs(rdev, msg))
2774 goto nla_put_failure;
3710a8a6 2775
3713b4e3 2776 /* done */
86e8cf98 2777 state->split_start = 0;
3713b4e3
JB
2778 break;
2779 }
3bb20556 2780 finish:
053c095a
JB
2781 genlmsg_end(msg, hdr);
2782 return 0;
55682965
JB
2783
2784 nla_put_failure:
bc3ed28c
TG
2785 genlmsg_cancel(msg, hdr);
2786 return -EMSGSIZE;
55682965
JB
2787}
2788
86e8cf98
JB
2789static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
2790 struct netlink_callback *cb,
2791 struct nl80211_dump_wiphy_state *state)
2792{
50508d94
JB
2793 struct nlattr **tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
2794 int ret;
2795
2796 if (!tb)
2797 return -ENOMEM;
2798
2799 ret = nlmsg_parse_deprecated(cb->nlh,
2800 GENL_HDRLEN + nl80211_fam.hdrsize,
2801 tb, nl80211_fam.maxattr,
2802 nl80211_policy, NULL);
86e8cf98 2803 /* ignore parse errors for backward compatibility */
50508d94
JB
2804 if (ret) {
2805 ret = 0;
2806 goto out;
2807 }
86e8cf98
JB
2808
2809 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
2810 if (tb[NL80211_ATTR_WIPHY])
2811 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2812 if (tb[NL80211_ATTR_WDEV])
2813 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
2814 if (tb[NL80211_ATTR_IFINDEX]) {
2815 struct net_device *netdev;
2816 struct cfg80211_registered_device *rdev;
2817 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2818
7f2b8562 2819 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
50508d94
JB
2820 if (!netdev) {
2821 ret = -ENODEV;
2822 goto out;
2823 }
86e8cf98 2824 if (netdev->ieee80211_ptr) {
f26cbf40 2825 rdev = wiphy_to_rdev(
86e8cf98
JB
2826 netdev->ieee80211_ptr->wiphy);
2827 state->filter_wiphy = rdev->wiphy_idx;
2828 }
86e8cf98
JB
2829 }
2830
50508d94
JB
2831 ret = 0;
2832out:
2833 kfree(tb);
2834 return ret;
86e8cf98
JB
2835}
2836
55682965
JB
2837static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
2838{
645e77de 2839 int idx = 0, ret;
86e8cf98 2840 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 2841 struct cfg80211_registered_device *rdev;
3a5a423b 2842
5fe231e8 2843 rtnl_lock();
86e8cf98
JB
2844 if (!state) {
2845 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
2846 if (!state) {
2847 rtnl_unlock();
86e8cf98 2848 return -ENOMEM;
3713b4e3 2849 }
86e8cf98
JB
2850 state->filter_wiphy = -1;
2851 ret = nl80211_dump_wiphy_parse(skb, cb, state);
2852 if (ret) {
2853 kfree(state);
2854 rtnl_unlock();
2855 return ret;
3713b4e3 2856 }
86e8cf98 2857 cb->args[0] = (long)state;
3713b4e3
JB
2858 }
2859
1b8ec87a
ZG
2860 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2861 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2862 continue;
86e8cf98 2863 if (++idx <= state->start)
55682965 2864 continue;
86e8cf98 2865 if (state->filter_wiphy != -1 &&
1b8ec87a 2866 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
2867 continue;
2868 /* attempt to fit multiple wiphy data chunks into the skb */
2869 do {
3bb20556
JB
2870 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
2871 skb,
3713b4e3
JB
2872 NETLINK_CB(cb->skb).portid,
2873 cb->nlh->nlmsg_seq,
86e8cf98 2874 NLM_F_MULTI, state);
3713b4e3
JB
2875 if (ret < 0) {
2876 /*
2877 * If sending the wiphy data didn't fit (ENOBUFS
2878 * or EMSGSIZE returned), this SKB is still
2879 * empty (so it's not too big because another
2880 * wiphy dataset is already in the skb) and
2881 * we've not tried to adjust the dump allocation
2882 * yet ... then adjust the alloc size to be
2883 * bigger, and return 1 but with the empty skb.
2884 * This results in an empty message being RX'ed
2885 * in userspace, but that is ignored.
2886 *
2887 * We can then retry with the larger buffer.
2888 */
2889 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 2890 !skb->len && !state->split &&
3713b4e3
JB
2891 cb->min_dump_alloc < 4096) {
2892 cb->min_dump_alloc = 4096;
f12cb289 2893 state->split_start = 0;
d98cae64 2894 rtnl_unlock();
3713b4e3
JB
2895 return 1;
2896 }
2897 idx--;
2898 break;
645e77de 2899 }
86e8cf98 2900 } while (state->split_start > 0);
3713b4e3 2901 break;
55682965 2902 }
5fe231e8 2903 rtnl_unlock();
55682965 2904
86e8cf98 2905 state->start = idx;
55682965
JB
2906
2907 return skb->len;
2908}
2909
86e8cf98
JB
2910static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
2911{
2912 kfree((void *)cb->args[0]);
2913 return 0;
2914}
2915
55682965
JB
2916static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
2917{
2918 struct sk_buff *msg;
1b8ec87a 2919 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2920 struct nl80211_dump_wiphy_state state = {};
55682965 2921
645e77de 2922 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2923 if (!msg)
4c476991 2924 return -ENOMEM;
55682965 2925
3bb20556
JB
2926 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2927 info->snd_portid, info->snd_seq, 0,
86e8cf98 2928 &state) < 0) {
4c476991
JB
2929 nlmsg_free(msg);
2930 return -ENOBUFS;
2931 }
55682965 2932
134e6375 2933 return genlmsg_reply(msg, info);
55682965
JB
2934}
2935
31888487
JM
2936static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2937 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2938 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2939 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2940 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2941 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2942};
2943
2944static int parse_txq_params(struct nlattr *tb[],
2945 struct ieee80211_txq_params *txq_params)
2946{
259d8c1e
DW
2947 u8 ac;
2948
a3304b0a 2949 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2950 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2951 !tb[NL80211_TXQ_ATTR_AIFS])
2952 return -EINVAL;
2953
259d8c1e 2954 ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2955 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2956 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2957 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2958 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2959
259d8c1e 2960 if (ac >= NL80211_NUM_ACS)
a3304b0a 2961 return -EINVAL;
259d8c1e 2962 txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
31888487
JM
2963 return 0;
2964}
2965
f444de05
JB
2966static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2967{
2968 /*
e7e0517c
JB
2969 * You can only set the channel explicitly for some interfaces,
2970 * most have their channel managed via their respective
cc1d2806
JB
2971 * "establish a connection" command (connect, join, ...)
2972 *
2973 * For AP/GO and mesh mode, the channel can be set with the
2974 * channel userspace API, but is only stored and passed to the
2975 * low-level driver when the AP starts or the mesh is joined.
2976 * This is for backward compatibility, userspace can also give
2977 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2978 *
2979 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2980 * whatever else is going on, so they have their own special
2981 * operation to set the monitor channel if possible.
f444de05
JB
2982 */
2983 return !wdev ||
2984 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2985 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2986 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2987 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2988}
2989
9bb7e0f2
JB
2990int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2991 struct genl_info *info,
2992 struct cfg80211_chan_def *chandef)
683b6d3b 2993{
49f9cf0e
JB
2994 struct netlink_ext_ack *extack = info->extack;
2995 struct nlattr **attrs = info->attrs;
dbeca2ea 2996 u32 control_freq;
683b6d3b 2997
49f9cf0e 2998 if (!attrs[NL80211_ATTR_WIPHY_FREQ])
683b6d3b
JB
2999 return -EINVAL;
3000
942ba88b
TP
3001 control_freq = MHZ_TO_KHZ(
3002 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3003 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
3004 control_freq +=
3005 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
683b6d3b 3006
f43e5210 3007 memset(chandef, 0, sizeof(*chandef));
942ba88b 3008 chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
3d9d1d66 3009 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
942ba88b
TP
3010 chandef->center_freq1 = KHZ_TO_MHZ(control_freq);
3011 chandef->freq1_offset = control_freq % 1000;
3d9d1d66 3012 chandef->center_freq2 = 0;
683b6d3b
JB
3013
3014 /* Primary channel not allowed */
49f9cf0e
JB
3015 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) {
3016 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
3017 "Channel is disabled");
683b6d3b 3018 return -EINVAL;
49f9cf0e 3019 }
683b6d3b 3020
49f9cf0e 3021 if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
3d9d1d66
JB
3022 enum nl80211_channel_type chantype;
3023
49f9cf0e 3024 chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
3d9d1d66
JB
3025
3026 switch (chantype) {
3027 case NL80211_CHAN_NO_HT:
3028 case NL80211_CHAN_HT20:
3029 case NL80211_CHAN_HT40PLUS:
3030 case NL80211_CHAN_HT40MINUS:
3031 cfg80211_chandef_create(chandef, chandef->chan,
3032 chantype);
ffa4629e 3033 /* user input for center_freq is incorrect */
49f9cf0e
JB
3034 if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
3035 chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
3036 NL_SET_ERR_MSG_ATTR(extack,
3037 attrs[NL80211_ATTR_CENTER_FREQ1],
3038 "bad center frequency 1");
ffa4629e 3039 return -EINVAL;
49f9cf0e 3040 }
ffa4629e 3041 /* center_freq2 must be zero */
49f9cf0e
JB
3042 if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
3043 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
3044 NL_SET_ERR_MSG_ATTR(extack,
3045 attrs[NL80211_ATTR_CENTER_FREQ2],
3046 "center frequency 2 can't be used");
ffa4629e 3047 return -EINVAL;
49f9cf0e 3048 }
3d9d1d66
JB
3049 break;
3050 default:
49f9cf0e
JB
3051 NL_SET_ERR_MSG_ATTR(extack,
3052 attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3053 "invalid channel type");
3d9d1d66
JB
3054 return -EINVAL;
3055 }
49f9cf0e 3056 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
3d9d1d66 3057 chandef->width =
49f9cf0e 3058 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
942ba88b 3059 if (attrs[NL80211_ATTR_CENTER_FREQ1]) {
3d9d1d66 3060 chandef->center_freq1 =
49f9cf0e 3061 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
942ba88b
TP
3062 if (attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET])
3063 chandef->freq1_offset = nla_get_u32(
3064 attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET]);
3065 else
3066 chandef->freq1_offset = 0;
3067 }
49f9cf0e 3068 if (attrs[NL80211_ATTR_CENTER_FREQ2])
3d9d1d66 3069 chandef->center_freq2 =
49f9cf0e 3070 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
3d9d1d66
JB
3071 }
3072
2a38075c
AAL
3073 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
3074 chandef->edmg.channels =
3075 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
3076
3077 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
3078 chandef->edmg.bw_config =
3079 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
3080 } else {
3081 chandef->edmg.bw_config = 0;
3082 chandef->edmg.channels = 0;
3083 }
3084
49f9cf0e
JB
3085 if (!cfg80211_chandef_valid(chandef)) {
3086 NL_SET_ERR_MSG(extack, "invalid channel definition");
3d9d1d66 3087 return -EINVAL;
49f9cf0e 3088 }
3d9d1d66 3089
9f5e8f6e 3090 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
49f9cf0e
JB
3091 IEEE80211_CHAN_DISABLED)) {
3092 NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
3d9d1d66 3093 return -EINVAL;
49f9cf0e 3094 }
3d9d1d66 3095
2f301ab2
SW
3096 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
3097 chandef->width == NL80211_CHAN_WIDTH_10) &&
49f9cf0e
JB
3098 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
3099 NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
2f301ab2 3100 return -EINVAL;
49f9cf0e 3101 }
2f301ab2 3102
683b6d3b
JB
3103 return 0;
3104}
3105
f444de05 3106static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 3107 struct net_device *dev,
f444de05
JB
3108 struct genl_info *info)
3109{
683b6d3b 3110 struct cfg80211_chan_def chandef;
f444de05 3111 int result;
e8c9bd5b 3112 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 3113 struct wireless_dev *wdev = NULL;
e8c9bd5b 3114
e16821bc
JM
3115 if (dev)
3116 wdev = dev->ieee80211_ptr;
f444de05
JB
3117 if (!nl80211_can_set_dev_channel(wdev))
3118 return -EOPNOTSUPP;
e16821bc
JM
3119 if (wdev)
3120 iftype = wdev->iftype;
f444de05 3121
683b6d3b
JB
3122 result = nl80211_parse_chandef(rdev, info, &chandef);
3123 if (result)
3124 return result;
f444de05 3125
e8c9bd5b 3126 switch (iftype) {
aa430da4
JB
3127 case NL80211_IFTYPE_AP:
3128 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
3129 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
3130 iftype)) {
aa430da4
JB
3131 result = -EINVAL;
3132 break;
3133 }
e16821bc
JM
3134 if (wdev->beacon_interval) {
3135 if (!dev || !rdev->ops->set_ap_chanwidth ||
3136 !(rdev->wiphy.features &
3137 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
3138 result = -EBUSY;
3139 break;
3140 }
3141
3142 /* Only allow dynamic channel width changes */
3143 if (chandef.chan != wdev->preset_chandef.chan) {
3144 result = -EBUSY;
3145 break;
3146 }
3147 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
3148 if (result)
3149 break;
3150 }
683b6d3b 3151 wdev->preset_chandef = chandef;
aa430da4
JB
3152 result = 0;
3153 break;
cc1d2806 3154 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 3155 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 3156 break;
e8c9bd5b 3157 case NL80211_IFTYPE_MONITOR:
683b6d3b 3158 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 3159 break;
aa430da4 3160 default:
e8c9bd5b 3161 result = -EINVAL;
f444de05 3162 }
f444de05
JB
3163
3164 return result;
3165}
3166
3167static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
3168{
4c476991
JB
3169 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3170 struct net_device *netdev = info->user_ptr[1];
f444de05 3171
e16821bc 3172 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
3173}
3174
55682965
JB
3175static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
3176{
a05829a7 3177 struct cfg80211_registered_device *rdev = NULL;
f444de05
JB
3178 struct net_device *netdev = NULL;
3179 struct wireless_dev *wdev;
a1e567c8 3180 int result = 0, rem_txq_params = 0;
31888487 3181 struct nlattr *nl_txq_params;
b9a5f8ca
JM
3182 u32 changed;
3183 u8 retry_short = 0, retry_long = 0;
3184 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 3185 u8 coverage_class = 0;
52539ca8 3186 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
55682965 3187
a05829a7 3188 rtnl_lock();
f444de05
JB
3189 /*
3190 * Try to find the wiphy and netdev. Normally this
3191 * function shouldn't need the netdev, but this is
3192 * done for backward compatibility -- previously
3193 * setting the channel was done per wiphy, but now
3194 * it is per netdev. Previous userland like hostapd
3195 * also passed a netdev to set_wiphy, so that it is
3196 * possible to let that go to the right netdev!
3197 */
4bbf4d56 3198
f444de05
JB
3199 if (info->attrs[NL80211_ATTR_IFINDEX]) {
3200 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
3201
7f2b8562 3202 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 3203 if (netdev && netdev->ieee80211_ptr)
f26cbf40 3204 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 3205 else
f444de05 3206 netdev = NULL;
4bbf4d56
JB
3207 }
3208
f444de05 3209 if (!netdev) {
878d9ec7
JB
3210 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
3211 info->attrs);
a05829a7
JB
3212 if (IS_ERR(rdev)) {
3213 rtnl_unlock();
4c476991 3214 return PTR_ERR(rdev);
a05829a7 3215 }
f444de05
JB
3216 wdev = NULL;
3217 netdev = NULL;
3218 result = 0;
71fe96bf 3219 } else
f444de05 3220 wdev = netdev->ieee80211_ptr;
f444de05 3221
a05829a7 3222 wiphy_lock(&rdev->wiphy);
a05829a7 3223
f444de05
JB
3224 /*
3225 * end workaround code, by now the rdev is available
3226 * and locked, and wdev may or may not be NULL.
3227 */
4bbf4d56
JB
3228
3229 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
3230 result = cfg80211_dev_rename(
3231 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
0391a45c 3232 rtnl_unlock();
4bbf4d56 3233
4bbf4d56 3234 if (result)
a05829a7 3235 goto out;
31888487
JM
3236
3237 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
3238 struct ieee80211_txq_params txq_params;
3239 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
3240
a05829a7
JB
3241 if (!rdev->ops->set_txq_params) {
3242 result = -EOPNOTSUPP;
3243 goto out;
3244 }
31888487 3245
a05829a7
JB
3246 if (!netdev) {
3247 result = -EINVAL;
3248 goto out;
3249 }
f70f01c2 3250
133a3ff2 3251 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
a05829a7
JB
3252 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
3253 result = -EINVAL;
3254 goto out;
3255 }
133a3ff2 3256
a05829a7
JB
3257 if (!netif_running(netdev)) {
3258 result = -ENETDOWN;
3259 goto out;
3260 }
2b5f8b0b 3261
31888487
JM
3262 nla_for_each_nested(nl_txq_params,
3263 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
3264 rem_txq_params) {
8cb08174
JB
3265 result = nla_parse_nested_deprecated(tb,
3266 NL80211_TXQ_ATTR_MAX,
3267 nl_txq_params,
3268 txq_params_policy,
3269 info->extack);
ae811e21 3270 if (result)
a05829a7 3271 goto out;
31888487
JM
3272 result = parse_txq_params(tb, &txq_params);
3273 if (result)
a05829a7 3274 goto out;
31888487 3275
e35e4d28
HG
3276 result = rdev_set_txq_params(rdev, netdev,
3277 &txq_params);
31888487 3278 if (result)
a05829a7 3279 goto out;
31888487
JM
3280 }
3281 }
55682965 3282
72bdcf34 3283 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
3284 result = __nl80211_set_channel(
3285 rdev,
3286 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
3287 info);
72bdcf34 3288 if (result)
a05829a7 3289 goto out;
72bdcf34
JM
3290 }
3291
98d2ff8b 3292 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 3293 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
3294 enum nl80211_tx_power_setting type;
3295 int idx, mbm = 0;
3296
c8442118
JB
3297 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
3298 txp_wdev = NULL;
3299
a05829a7
JB
3300 if (!rdev->ops->set_tx_power) {
3301 result = -EOPNOTSUPP;
3302 goto out;
3303 }
98d2ff8b
JO
3304
3305 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
3306 type = nla_get_u32(info->attrs[idx]);
3307
3308 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
a05829a7
JB
3309 (type != NL80211_TX_POWER_AUTOMATIC)) {
3310 result = -EINVAL;
3311 goto out;
3312 }
98d2ff8b
JO
3313
3314 if (type != NL80211_TX_POWER_AUTOMATIC) {
3315 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
3316 mbm = nla_get_u32(info->attrs[idx]);
3317 }
3318
c8442118 3319 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 3320 if (result)
a05829a7 3321 goto out;
98d2ff8b
JO
3322 }
3323
afe0cbf8
BR
3324 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
3325 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
3326 u32 tx_ant, rx_ant;
7a087e74 3327
7f531e03
BR
3328 if ((!rdev->wiphy.available_antennas_tx &&
3329 !rdev->wiphy.available_antennas_rx) ||
a05829a7
JB
3330 !rdev->ops->set_antenna) {
3331 result = -EOPNOTSUPP;
3332 goto out;
3333 }
afe0cbf8
BR
3334
3335 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
3336 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
3337
a7ffac95 3338 /* reject antenna configurations which don't match the
7f531e03
BR
3339 * available antenna masks, except for the "all" mask */
3340 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
a05829a7
JB
3341 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
3342 result = -EINVAL;
3343 goto out;
3344 }
a7ffac95 3345
7f531e03
BR
3346 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
3347 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 3348
e35e4d28 3349 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 3350 if (result)
a05829a7 3351 goto out;
afe0cbf8
BR
3352 }
3353
b9a5f8ca
JM
3354 changed = 0;
3355
3356 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
3357 retry_short = nla_get_u8(
3358 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562 3359
b9a5f8ca
JM
3360 changed |= WIPHY_PARAM_RETRY_SHORT;
3361 }
3362
3363 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
3364 retry_long = nla_get_u8(
3365 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562 3366
b9a5f8ca
JM
3367 changed |= WIPHY_PARAM_RETRY_LONG;
3368 }
3369
3370 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
3371 frag_threshold = nla_get_u32(
3372 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
a05829a7
JB
3373 if (frag_threshold < 256) {
3374 result = -EINVAL;
3375 goto out;
3376 }
7f2b8562 3377
b9a5f8ca
JM
3378 if (frag_threshold != (u32) -1) {
3379 /*
3380 * Fragments (apart from the last one) are required to
3381 * have even length. Make the fragmentation code
3382 * simpler by stripping LSB should someone try to use
3383 * odd threshold value.
3384 */
3385 frag_threshold &= ~0x1;
3386 }
3387 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
3388 }
3389
3390 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
3391 rts_threshold = nla_get_u32(
3392 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
3393 changed |= WIPHY_PARAM_RTS_THRESHOLD;
3394 }
3395
81077e82 3396 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
a05829a7
JB
3397 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
3398 result = -EINVAL;
3399 goto out;
3400 }
3057dbfd 3401
81077e82
LT
3402 coverage_class = nla_get_u8(
3403 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
3404 changed |= WIPHY_PARAM_COVERAGE_CLASS;
3405 }
3406
3057dbfd 3407 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
a05829a7
JB
3408 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION)) {
3409 result = -EOPNOTSUPP;
3410 goto out;
3411 }
3057dbfd
LB
3412
3413 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
3414 }
3415
52539ca8
THJ
3416 if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
3417 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3418 NL80211_EXT_FEATURE_TXQS)) {
3419 result = -EOPNOTSUPP;
3420 goto out;
3421 }
52539ca8
THJ
3422 txq_limit = nla_get_u32(
3423 info->attrs[NL80211_ATTR_TXQ_LIMIT]);
3424 changed |= WIPHY_PARAM_TXQ_LIMIT;
3425 }
3426
3427 if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
3428 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3429 NL80211_EXT_FEATURE_TXQS)) {
3430 result = -EOPNOTSUPP;
3431 goto out;
3432 }
52539ca8
THJ
3433 txq_memory_limit = nla_get_u32(
3434 info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
3435 changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
3436 }
3437
3438 if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
3439 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3440 NL80211_EXT_FEATURE_TXQS)) {
3441 result = -EOPNOTSUPP;
3442 goto out;
3443 }
52539ca8
THJ
3444 txq_quantum = nla_get_u32(
3445 info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
3446 changed |= WIPHY_PARAM_TXQ_QUANTUM;
3447 }
3448
b9a5f8ca
JM
3449 if (changed) {
3450 u8 old_retry_short, old_retry_long;
3451 u32 old_frag_threshold, old_rts_threshold;
81077e82 3452 u8 old_coverage_class;
52539ca8 3453 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
b9a5f8ca 3454
a05829a7
JB
3455 if (!rdev->ops->set_wiphy_params) {
3456 result = -EOPNOTSUPP;
3457 goto out;
3458 }
b9a5f8ca
JM
3459
3460 old_retry_short = rdev->wiphy.retry_short;
3461 old_retry_long = rdev->wiphy.retry_long;
3462 old_frag_threshold = rdev->wiphy.frag_threshold;
3463 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 3464 old_coverage_class = rdev->wiphy.coverage_class;
52539ca8
THJ
3465 old_txq_limit = rdev->wiphy.txq_limit;
3466 old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
3467 old_txq_quantum = rdev->wiphy.txq_quantum;
b9a5f8ca
JM
3468
3469 if (changed & WIPHY_PARAM_RETRY_SHORT)
3470 rdev->wiphy.retry_short = retry_short;
3471 if (changed & WIPHY_PARAM_RETRY_LONG)
3472 rdev->wiphy.retry_long = retry_long;
3473 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
3474 rdev->wiphy.frag_threshold = frag_threshold;
3475 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
3476 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
3477 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
3478 rdev->wiphy.coverage_class = coverage_class;
52539ca8
THJ
3479 if (changed & WIPHY_PARAM_TXQ_LIMIT)
3480 rdev->wiphy.txq_limit = txq_limit;
3481 if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
3482 rdev->wiphy.txq_memory_limit = txq_memory_limit;
3483 if (changed & WIPHY_PARAM_TXQ_QUANTUM)
3484 rdev->wiphy.txq_quantum = txq_quantum;
b9a5f8ca 3485
e35e4d28 3486 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
3487 if (result) {
3488 rdev->wiphy.retry_short = old_retry_short;
3489 rdev->wiphy.retry_long = old_retry_long;
3490 rdev->wiphy.frag_threshold = old_frag_threshold;
3491 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 3492 rdev->wiphy.coverage_class = old_coverage_class;
52539ca8
THJ
3493 rdev->wiphy.txq_limit = old_txq_limit;
3494 rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
3495 rdev->wiphy.txq_quantum = old_txq_quantum;
a05829a7 3496 goto out;
b9a5f8ca
JM
3497 }
3498 }
a05829a7
JB
3499
3500 result = 0;
3501
3502out:
3503 wiphy_unlock(&rdev->wiphy);
3504 return result;
55682965
JB
3505}
3506
683b6d3b 3507static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 3508 const struct cfg80211_chan_def *chandef)
683b6d3b 3509{
601555cd
JB
3510 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
3511 return -EINVAL;
3d9d1d66 3512
683b6d3b
JB
3513 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
3514 chandef->chan->center_freq))
3515 return -ENOBUFS;
942ba88b
TP
3516 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
3517 chandef->chan->freq_offset))
3518 return -ENOBUFS;
3d9d1d66
JB
3519 switch (chandef->width) {
3520 case NL80211_CHAN_WIDTH_20_NOHT:
3521 case NL80211_CHAN_WIDTH_20:
3522 case NL80211_CHAN_WIDTH_40:
3523 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3524 cfg80211_get_chandef_type(chandef)))
3525 return -ENOBUFS;
3526 break;
3527 default:
3528 break;
3529 }
3530 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
3531 return -ENOBUFS;
3532 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
3533 return -ENOBUFS;
3534 if (chandef->center_freq2 &&
3535 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
3536 return -ENOBUFS;
3537 return 0;
3538}
3539
15e47304 3540static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 3541 struct cfg80211_registered_device *rdev,
3d1a5bbf
AZ
3542 struct wireless_dev *wdev,
3543 enum nl80211_commands cmd)
55682965 3544{
72fb2abc 3545 struct net_device *dev = wdev->netdev;
55682965
JB
3546 void *hdr;
3547
3d1a5bbf
AZ
3548 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
3549 cmd != NL80211_CMD_DEL_INTERFACE &&
3550 cmd != NL80211_CMD_SET_INTERFACE);
8f894be2
TB
3551
3552 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
3553 if (!hdr)
3554 return -1;
3555
72fb2abc
JB
3556 if (dev &&
3557 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 3558 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
3559 goto nla_put_failure;
3560
3561 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3562 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
3563 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
3564 NL80211_ATTR_PAD) ||
98104fde 3565 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
3566 nla_put_u32(msg, NL80211_ATTR_GENERATION,
3567 rdev->devlist_generation ^
446faa15
AQ
3568 (cfg80211_rdev_list_generation << 2)) ||
3569 nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
9360ffd1 3570 goto nla_put_failure;
f5ea9120 3571
5b7ccaf3 3572 if (rdev->ops->get_channel) {
683b6d3b 3573 int ret;
f43e5210 3574 struct cfg80211_chan_def chandef = {};
683b6d3b
JB
3575
3576 ret = rdev_get_channel(rdev, wdev, &chandef);
3577 if (ret == 0) {
3578 if (nl80211_send_chandef(msg, &chandef))
3579 goto nla_put_failure;
3580 }
d91df0e3
PF
3581 }
3582
d55d0d59
RM
3583 if (rdev->ops->get_tx_power) {
3584 int dbm, ret;
3585
3586 ret = rdev_get_tx_power(rdev, wdev, &dbm);
3587 if (ret == 0 &&
3588 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
3589 DBM_TO_MBM(dbm)))
3590 goto nla_put_failure;
3591 }
3592
44905265
JB
3593 wdev_lock(wdev);
3594 switch (wdev->iftype) {
3595 case NL80211_IFTYPE_AP:
3596 if (wdev->ssid_len &&
3597 nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
4564b187 3598 goto nla_put_failure_locked;
44905265
JB
3599 break;
3600 case NL80211_IFTYPE_STATION:
3601 case NL80211_IFTYPE_P2P_CLIENT:
3602 case NL80211_IFTYPE_ADHOC: {
3603 const u8 *ssid_ie;
3604 if (!wdev->current_bss)
3605 break;
7a94b8c2 3606 rcu_read_lock();
44905265
JB
3607 ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
3608 WLAN_EID_SSID);
7a94b8c2
DB
3609 if (ssid_ie &&
3610 nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2))
3611 goto nla_put_failure_rcu_locked;
3612 rcu_read_unlock();
44905265
JB
3613 break;
3614 }
3615 default:
3616 /* nothing */
3617 break;
b84e7a05 3618 }
44905265 3619 wdev_unlock(wdev);
b84e7a05 3620
52539ca8
THJ
3621 if (rdev->ops->get_txq_stats) {
3622 struct cfg80211_txq_stats txqstats = {};
3623 int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
3624
3625 if (ret == 0 &&
3626 !nl80211_put_txq_stats(msg, &txqstats,
3627 NL80211_ATTR_TXQ_STATS))
3628 goto nla_put_failure;
3629 }
3630
053c095a
JB
3631 genlmsg_end(msg, hdr);
3632 return 0;
55682965 3633
7a94b8c2
DB
3634 nla_put_failure_rcu_locked:
3635 rcu_read_unlock();
4564b187
JB
3636 nla_put_failure_locked:
3637 wdev_unlock(wdev);
55682965 3638 nla_put_failure:
bc3ed28c
TG
3639 genlmsg_cancel(msg, hdr);
3640 return -EMSGSIZE;
55682965
JB
3641}
3642
3643static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
3644{
3645 int wp_idx = 0;
3646 int if_idx = 0;
3647 int wp_start = cb->args[0];
3648 int if_start = cb->args[1];
b7fb44da 3649 int filter_wiphy = -1;
f5ea9120 3650 struct cfg80211_registered_device *rdev;
55682965 3651 struct wireless_dev *wdev;
ea90e0dc 3652 int ret;
55682965 3653
5fe231e8 3654 rtnl_lock();
b7fb44da
DK
3655 if (!cb->args[2]) {
3656 struct nl80211_dump_wiphy_state state = {
3657 .filter_wiphy = -1,
3658 };
b7fb44da
DK
3659
3660 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
3661 if (ret)
ea90e0dc 3662 goto out_unlock;
b7fb44da
DK
3663
3664 filter_wiphy = state.filter_wiphy;
3665
3666 /*
3667 * if filtering, set cb->args[2] to +1 since 0 is the default
3668 * value needed to determine that parsing is necessary.
3669 */
3670 if (filter_wiphy >= 0)
3671 cb->args[2] = filter_wiphy + 1;
3672 else
3673 cb->args[2] = -1;
3674 } else if (cb->args[2] > 0) {
3675 filter_wiphy = cb->args[2] - 1;
3676 }
3677
f5ea9120
JB
3678 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
3679 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 3680 continue;
bba95fef
JB
3681 if (wp_idx < wp_start) {
3682 wp_idx++;
55682965 3683 continue;
bba95fef 3684 }
b7fb44da
DK
3685
3686 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
3687 continue;
3688
55682965
JB
3689 if_idx = 0;
3690
53873f13 3691 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
3692 if (if_idx < if_start) {
3693 if_idx++;
55682965 3694 continue;
bba95fef 3695 }
15e47304 3696 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 3697 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3d1a5bbf
AZ
3698 rdev, wdev,
3699 NL80211_CMD_NEW_INTERFACE) < 0) {
bba95fef
JB
3700 goto out;
3701 }
3702 if_idx++;
55682965 3703 }
bba95fef
JB
3704
3705 wp_idx++;
55682965 3706 }
bba95fef 3707 out:
55682965
JB
3708 cb->args[0] = wp_idx;
3709 cb->args[1] = if_idx;
3710
ea90e0dc
JB
3711 ret = skb->len;
3712 out_unlock:
3713 rtnl_unlock();
3714
3715 return ret;
55682965
JB
3716}
3717
3718static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
3719{
3720 struct sk_buff *msg;
1b8ec87a 3721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 3722 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3723
fd2120ca 3724 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 3725 if (!msg)
4c476991 3726 return -ENOMEM;
55682965 3727
15e47304 3728 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 3729 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
4c476991
JB
3730 nlmsg_free(msg);
3731 return -ENOBUFS;
3732 }
55682965 3733
134e6375 3734 return genlmsg_reply(msg, info);
55682965
JB
3735}
3736
66f7ac50
MW
3737static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
3738 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
3739 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
3740 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
3741 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
3742 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 3743 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
3744};
3745
3746static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
3747{
3748 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
3749 int flag;
3750
3751 *mntrflags = 0;
3752
3753 if (!nla)
3754 return -EINVAL;
3755
8cb08174 3756 if (nla_parse_nested_deprecated(flags, NL80211_MNTR_FLAG_MAX, nla, mntr_flags_policy, NULL))
66f7ac50
MW
3757 return -EINVAL;
3758
3759 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
3760 if (flags[flag])
3761 *mntrflags |= (1<<flag);
3762
818a986e
JB
3763 *mntrflags |= MONITOR_FLAG_CHANGED;
3764
66f7ac50
MW
3765 return 0;
3766}
3767
1db77596
JB
3768static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
3769 enum nl80211_iftype type,
3770 struct genl_info *info,
3771 struct vif_params *params)
3772{
3773 bool change = false;
3774 int err;
3775
3776 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
3777 if (type != NL80211_IFTYPE_MONITOR)
3778 return -EINVAL;
3779
3780 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
3781 &params->flags);
3782 if (err)
3783 return err;
3784
3785 change = true;
3786 }
3787
3788 if (params->flags & MONITOR_FLAG_ACTIVE &&
3789 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
3790 return -EOPNOTSUPP;
3791
3792 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
3793 const u8 *mumimo_groups;
3794 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3795
3796 if (type != NL80211_IFTYPE_MONITOR)
3797 return -EINVAL;
3798
3799 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3800 return -EOPNOTSUPP;
3801
3802 mumimo_groups =
3803 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
3804
3805 /* bits 0 and 63 are reserved and must be zero */
4954601f
JB
3806 if ((mumimo_groups[0] & BIT(0)) ||
3807 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
1db77596
JB
3808 return -EINVAL;
3809
3810 params->vht_mumimo_groups = mumimo_groups;
3811 change = true;
3812 }
3813
3814 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
3815 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3816
3817 if (type != NL80211_IFTYPE_MONITOR)
3818 return -EINVAL;
3819
3820 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3821 return -EOPNOTSUPP;
3822
3823 params->vht_mumimo_follow_addr =
3824 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
3825 change = true;
3826 }
3827
3828 return change ? 1 : 0;
3829}
3830
9bc383de 3831static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
3832 struct net_device *netdev, u8 use_4addr,
3833 enum nl80211_iftype iftype)
9bc383de 3834{
ad4bb6f8 3835 if (!use_4addr) {
2e92a2d0 3836 if (netdev && netif_is_bridge_port(netdev))
ad4bb6f8 3837 return -EBUSY;
9bc383de 3838 return 0;
ad4bb6f8 3839 }
9bc383de
JB
3840
3841 switch (iftype) {
3842 case NL80211_IFTYPE_AP_VLAN:
3843 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
3844 return 0;
3845 break;
3846 case NL80211_IFTYPE_STATION:
3847 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
3848 return 0;
3849 break;
3850 default:
3851 break;
3852 }
3853
3854 return -EOPNOTSUPP;
3855}
3856
55682965
JB
3857static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3858{
4c476991 3859 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3860 struct vif_params params;
e36d56b6 3861 int err;
04a773ad 3862 enum nl80211_iftype otype, ntype;
4c476991 3863 struct net_device *dev = info->user_ptr[1];
ac7f9cfa 3864 bool change = false;
55682965 3865
2ec600d6
LCC
3866 memset(&params, 0, sizeof(params));
3867
04a773ad 3868 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 3869
723b038d 3870 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 3871 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 3872 if (otype != ntype)
ac7f9cfa 3873 change = true;
723b038d
JB
3874 }
3875
92ffe055 3876 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
3877 struct wireless_dev *wdev = dev->ieee80211_ptr;
3878
4c476991
JB
3879 if (ntype != NL80211_IFTYPE_MESH_POINT)
3880 return -EINVAL;
29cbe68c
JB
3881 if (netif_running(dev))
3882 return -EBUSY;
3883
3884 wdev_lock(wdev);
3885 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3886 IEEE80211_MAX_MESH_ID_LEN);
3887 wdev->mesh_id_up_len =
3888 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3889 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3890 wdev->mesh_id_up_len);
3891 wdev_unlock(wdev);
2ec600d6
LCC
3892 }
3893
8b787643
FF
3894 if (info->attrs[NL80211_ATTR_4ADDR]) {
3895 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
3896 change = true;
ad4bb6f8 3897 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 3898 if (err)
4c476991 3899 return err;
8b787643
FF
3900 } else {
3901 params.use_4addr = -1;
3902 }
3903
1db77596
JB
3904 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
3905 if (err < 0)
3906 return err;
3907 if (err > 0)
c6e6a0c8 3908 change = true;
e057d3c3 3909
ac7f9cfa 3910 if (change)
818a986e 3911 err = cfg80211_change_iface(rdev, dev, ntype, &params);
ac7f9cfa
JB
3912 else
3913 err = 0;
60719ffd 3914
9bc383de
JB
3915 if (!err && params.use_4addr != -1)
3916 dev->ieee80211_ptr->use_4addr = params.use_4addr;
3917
3d1a5bbf
AZ
3918 if (change && !err) {
3919 struct wireless_dev *wdev = dev->ieee80211_ptr;
3920
3921 nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
3922 }
3923
55682965
JB
3924 return err;
3925}
3926
3927static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
3928{
4c476991 3929 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3930 struct vif_params params;
84efbb84 3931 struct wireless_dev *wdev;
896ff063 3932 struct sk_buff *msg;
55682965
JB
3933 int err;
3934 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
3935
78f22b6a
JB
3936 /* to avoid failing a new interface creation due to pending removal */
3937 cfg80211_destroy_ifaces(rdev);
3938
2ec600d6
LCC
3939 memset(&params, 0, sizeof(params));
3940
55682965
JB
3941 if (!info->attrs[NL80211_ATTR_IFNAME])
3942 return -EINVAL;
3943
ab0d76f6 3944 if (info->attrs[NL80211_ATTR_IFTYPE])
55682965 3945 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
55682965 3946
33d915d9 3947 if (!rdev->ops->add_virtual_intf)
4c476991 3948 return -EOPNOTSUPP;
55682965 3949
cb3b7d87 3950 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
3951 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
3952 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
3953 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
3954 ETH_ALEN);
3955 if (!is_valid_ether_addr(params.macaddr))
3956 return -EADDRNOTAVAIL;
3957 }
3958
9bc383de 3959 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 3960 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 3961 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 3962 if (err)
4c476991 3963 return err;
9bc383de 3964 }
8b787643 3965
e6f40511 3966 if (!cfg80211_iftype_allowed(&rdev->wiphy, type, params.use_4addr, 0))
33d915d9
MP
3967 return -EOPNOTSUPP;
3968
1db77596
JB
3969 err = nl80211_parse_mon_options(rdev, type, info, &params);
3970 if (err < 0)
3971 return err;
e057d3c3 3972
a18c7192
JB
3973 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3974 if (!msg)
3975 return -ENOMEM;
3976
e35e4d28
HG
3977 wdev = rdev_add_virtual_intf(rdev,
3978 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
818a986e 3979 NET_NAME_USER, type, &params);
d687cbb7
RM
3980 if (WARN_ON(!wdev)) {
3981 nlmsg_free(msg);
3982 return -EPROTO;
3983 } else if (IS_ERR(wdev)) {
1c90f9d4 3984 nlmsg_free(msg);
84efbb84 3985 return PTR_ERR(wdev);
1c90f9d4 3986 }
2ec600d6 3987
18e5ca65 3988 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
3989 wdev->owner_nlportid = info->snd_portid;
3990
98104fde
JB
3991 switch (type) {
3992 case NL80211_IFTYPE_MESH_POINT:
3993 if (!info->attrs[NL80211_ATTR_MESH_ID])
3994 break;
29cbe68c
JB
3995 wdev_lock(wdev);
3996 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3997 IEEE80211_MAX_MESH_ID_LEN);
3998 wdev->mesh_id_up_len =
3999 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4000 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
4001 wdev->mesh_id_up_len);
4002 wdev_unlock(wdev);
98104fde 4003 break;
cb3b7d87 4004 case NL80211_IFTYPE_NAN:
98104fde
JB
4005 case NL80211_IFTYPE_P2P_DEVICE:
4006 /*
cb3b7d87 4007 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
4008 * through the netdev notifier and must be added here
4009 */
9bdaf3b9
JB
4010 cfg80211_init_wdev(wdev);
4011 cfg80211_register_wdev(rdev, wdev);
98104fde
JB
4012 break;
4013 default:
4014 break;
29cbe68c
JB
4015 }
4016
15e47304 4017 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 4018 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
1c90f9d4
JB
4019 nlmsg_free(msg);
4020 return -ENOBUFS;
4021 }
4022
4023 return genlmsg_reply(msg, info);
55682965
JB
4024}
4025
4026static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
4027{
4c476991 4028 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 4029 struct wireless_dev *wdev = info->user_ptr[1];
55682965 4030
4c476991
JB
4031 if (!rdev->ops->del_virtual_intf)
4032 return -EOPNOTSUPP;
55682965 4033
a05829a7
JB
4034 /*
4035 * We hold RTNL, so this is safe, without RTNL opencount cannot
4036 * reach 0, and thus the rdev cannot be deleted.
4037 *
4038 * We need to do it for the dev_close(), since that will call
4039 * the netdev notifiers, and we need to acquire the mutex there
4040 * but don't know if we get there from here or from some other
4041 * place (e.g. "ip link set ... down").
4042 */
4043 mutex_unlock(&rdev->wiphy.mtx);
4044
84efbb84
JB
4045 /*
4046 * If we remove a wireless device without a netdev then clear
4047 * user_ptr[1] so that nl80211_post_doit won't dereference it
4048 * to check if it needs to do dev_put(). Otherwise it crashes
4049 * since the wdev has been freed, unlike with a netdev where
4050 * we need the dev_put() for the netdev to really be freed.
4051 */
4052 if (!wdev->netdev)
4053 info->user_ptr[1] = NULL;
a05829a7
JB
4054 else
4055 dev_close(wdev->netdev);
4056
4057 mutex_lock(&rdev->wiphy.mtx);
84efbb84 4058
7f8ed01e 4059 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
4060}
4061
1d9d9213
SW
4062static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
4063{
4064 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4065 struct net_device *dev = info->user_ptr[1];
4066 u16 noack_map;
4067
4068 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
4069 return -EINVAL;
4070
4071 if (!rdev->ops->set_noack_map)
4072 return -EOPNOTSUPP;
4073
4074 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
4075
e35e4d28 4076 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
4077}
4078
41ade00f
JB
4079struct get_key_cookie {
4080 struct sk_buff *msg;
4081 int error;
b9454e83 4082 int idx;
41ade00f
JB
4083};
4084
4085static void get_key_callback(void *c, struct key_params *params)
4086{
b9454e83 4087 struct nlattr *key;
41ade00f
JB
4088 struct get_key_cookie *cookie = c;
4089
9360ffd1
DM
4090 if ((params->key &&
4091 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
4092 params->key_len, params->key)) ||
4093 (params->seq &&
4094 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
4095 params->seq_len, params->seq)) ||
4096 (params->cipher &&
4097 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
4098 params->cipher)))
4099 goto nla_put_failure;
41ade00f 4100
ae0be8de 4101 key = nla_nest_start_noflag(cookie->msg, NL80211_ATTR_KEY);
b9454e83
JB
4102 if (!key)
4103 goto nla_put_failure;
4104
9360ffd1
DM
4105 if ((params->key &&
4106 nla_put(cookie->msg, NL80211_KEY_DATA,
4107 params->key_len, params->key)) ||
4108 (params->seq &&
4109 nla_put(cookie->msg, NL80211_KEY_SEQ,
4110 params->seq_len, params->seq)) ||
4111 (params->cipher &&
4112 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
4113 params->cipher)))
4114 goto nla_put_failure;
b9454e83 4115
efdfce72 4116 if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
9360ffd1 4117 goto nla_put_failure;
b9454e83
JB
4118
4119 nla_nest_end(cookie->msg, key);
4120
41ade00f
JB
4121 return;
4122 nla_put_failure:
4123 cookie->error = 1;
4124}
4125
4126static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
4127{
4c476991 4128 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 4129 int err;
4c476991 4130 struct net_device *dev = info->user_ptr[1];
41ade00f 4131 u8 key_idx = 0;
e31b8213
JB
4132 const u8 *mac_addr = NULL;
4133 bool pairwise;
41ade00f
JB
4134 struct get_key_cookie cookie = {
4135 .error = 0,
4136 };
4137 void *hdr;
4138 struct sk_buff *msg;
155d7c73
JB
4139 bool bigtk_support = false;
4140
4141 if (wiphy_ext_feature_isset(&rdev->wiphy,
4142 NL80211_EXT_FEATURE_BEACON_PROTECTION))
4143 bigtk_support = true;
4144
4145 if ((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION ||
4146 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
4147 wiphy_ext_feature_isset(&rdev->wiphy,
4148 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
4149 bigtk_support = true;
41ade00f 4150
56be393f 4151 if (info->attrs[NL80211_ATTR_KEY_IDX]) {
41ade00f 4152 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
155d7c73
JB
4153
4154 if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) {
4155 GENL_SET_ERR_MSG(info, "BIGTK not supported");
56be393f 4156 return -EINVAL;
155d7c73 4157 }
56be393f 4158 }
41ade00f 4159
41ade00f
JB
4160 if (info->attrs[NL80211_ATTR_MAC])
4161 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4162
e31b8213
JB
4163 pairwise = !!mac_addr;
4164 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
4165 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 4166
e31b8213
JB
4167 if (kt != NL80211_KEYTYPE_GROUP &&
4168 kt != NL80211_KEYTYPE_PAIRWISE)
4169 return -EINVAL;
4170 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
4171 }
4172
4c476991
JB
4173 if (!rdev->ops->get_key)
4174 return -EOPNOTSUPP;
41ade00f 4175
0fa7b391
JB
4176 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4177 return -ENOENT;
4178
fd2120ca 4179 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
4180 if (!msg)
4181 return -ENOMEM;
41ade00f 4182
15e47304 4183 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 4184 NL80211_CMD_NEW_KEY);
cb35fba3 4185 if (!hdr)
9fe271af 4186 goto nla_put_failure;
41ade00f
JB
4187
4188 cookie.msg = msg;
b9454e83 4189 cookie.idx = key_idx;
41ade00f 4190
9360ffd1
DM
4191 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4192 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
4193 goto nla_put_failure;
4194 if (mac_addr &&
4195 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
4196 goto nla_put_failure;
41ade00f 4197
e35e4d28
HG
4198 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
4199 get_key_callback);
41ade00f
JB
4200
4201 if (err)
6c95e2a2 4202 goto free_msg;
41ade00f
JB
4203
4204 if (cookie.error)
4205 goto nla_put_failure;
4206
4207 genlmsg_end(msg, hdr);
4c476991 4208 return genlmsg_reply(msg, info);
41ade00f
JB
4209
4210 nla_put_failure:
4211 err = -ENOBUFS;
6c95e2a2 4212 free_msg:
41ade00f 4213 nlmsg_free(msg);
41ade00f
JB
4214 return err;
4215}
4216
4217static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
4218{
4c476991 4219 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 4220 struct key_parse key;
41ade00f 4221 int err;
4c476991 4222 struct net_device *dev = info->user_ptr[1];
41ade00f 4223
b9454e83
JB
4224 err = nl80211_parse_key(info, &key);
4225 if (err)
4226 return err;
41ade00f 4227
b9454e83 4228 if (key.idx < 0)
41ade00f
JB
4229 return -EINVAL;
4230
6cdd3979
AW
4231 /* Only support setting default key and
4232 * Extended Key ID action NL80211_KEY_SET_TX.
4233 */
56be393f 4234 if (!key.def && !key.defmgmt && !key.defbeacon &&
6cdd3979 4235 !(key.p.mode == NL80211_KEY_SET_TX))
41ade00f
JB
4236 return -EINVAL;
4237
dbd2fd65 4238 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 4239
dbd2fd65
JB
4240 if (key.def) {
4241 if (!rdev->ops->set_default_key) {
4242 err = -EOPNOTSUPP;
4243 goto out;
4244 }
41ade00f 4245
dbd2fd65
JB
4246 err = nl80211_key_allowed(dev->ieee80211_ptr);
4247 if (err)
4248 goto out;
4249
e35e4d28 4250 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
4251 key.def_uni, key.def_multi);
4252
4253 if (err)
4254 goto out;
fffd0934 4255
3d23e349 4256#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
4257 dev->ieee80211_ptr->wext.default_key = key.idx;
4258#endif
6cdd3979 4259 } else if (key.defmgmt) {
dbd2fd65
JB
4260 if (key.def_uni || !key.def_multi) {
4261 err = -EINVAL;
4262 goto out;
4263 }
4264
4265 if (!rdev->ops->set_default_mgmt_key) {
4266 err = -EOPNOTSUPP;
4267 goto out;
4268 }
4269
4270 err = nl80211_key_allowed(dev->ieee80211_ptr);
4271 if (err)
4272 goto out;
4273
e35e4d28 4274 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
4275 if (err)
4276 goto out;
4277
4278#ifdef CONFIG_CFG80211_WEXT
4279 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 4280#endif
56be393f
JM
4281 } else if (key.defbeacon) {
4282 if (key.def_uni || !key.def_multi) {
4283 err = -EINVAL;
4284 goto out;
4285 }
4286
4287 if (!rdev->ops->set_default_beacon_key) {
4288 err = -EOPNOTSUPP;
4289 goto out;
4290 }
4291
4292 err = nl80211_key_allowed(dev->ieee80211_ptr);
4293 if (err)
4294 goto out;
4295
4296 err = rdev_set_default_beacon_key(rdev, dev, key.idx);
4297 if (err)
4298 goto out;
6cdd3979
AW
4299 } else if (key.p.mode == NL80211_KEY_SET_TX &&
4300 wiphy_ext_feature_isset(&rdev->wiphy,
4301 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
4302 u8 *mac_addr = NULL;
4303
4304 if (info->attrs[NL80211_ATTR_MAC])
4305 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4306
4307 if (!mac_addr || key.idx < 0 || key.idx > 1) {
4308 err = -EINVAL;
4309 goto out;
4310 }
dbd2fd65 4311
6cdd3979
AW
4312 err = rdev_add_key(rdev, dev, key.idx,
4313 NL80211_KEYTYPE_PAIRWISE,
4314 mac_addr, &key.p);
4315 } else {
4316 err = -EINVAL;
4317 }
dbd2fd65 4318 out:
fffd0934 4319 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4320
41ade00f
JB
4321 return err;
4322}
4323
4324static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
4325{
4c476991 4326 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 4327 int err;
4c476991 4328 struct net_device *dev = info->user_ptr[1];
b9454e83 4329 struct key_parse key;
e31b8213 4330 const u8 *mac_addr = NULL;
41ade00f 4331
b9454e83
JB
4332 err = nl80211_parse_key(info, &key);
4333 if (err)
4334 return err;
41ade00f 4335
f8af764b
JM
4336 if (!key.p.key) {
4337 GENL_SET_ERR_MSG(info, "no key");
41ade00f 4338 return -EINVAL;
f8af764b 4339 }
41ade00f 4340
41ade00f
JB
4341 if (info->attrs[NL80211_ATTR_MAC])
4342 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4343
e31b8213
JB
4344 if (key.type == -1) {
4345 if (mac_addr)
4346 key.type = NL80211_KEYTYPE_PAIRWISE;
4347 else
4348 key.type = NL80211_KEYTYPE_GROUP;
4349 }
4350
4351 /* for now */
4352 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
f8af764b
JM
4353 key.type != NL80211_KEYTYPE_GROUP) {
4354 GENL_SET_ERR_MSG(info, "key type not pairwise or group");
e31b8213 4355 return -EINVAL;
f8af764b 4356 }
e31b8213 4357
14f34e36
GG
4358 if (key.type == NL80211_KEYTYPE_GROUP &&
4359 info->attrs[NL80211_ATTR_VLAN_ID])
4360 key.p.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
4361
4c476991
JB
4362 if (!rdev->ops->add_key)
4363 return -EOPNOTSUPP;
25e47c18 4364
e31b8213
JB
4365 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
4366 key.type == NL80211_KEYTYPE_PAIRWISE,
f8af764b
JM
4367 mac_addr)) {
4368 GENL_SET_ERR_MSG(info, "key setting validation failed");
4c476991 4369 return -EINVAL;
f8af764b 4370 }
41ade00f 4371
fffd0934
JB
4372 wdev_lock(dev->ieee80211_ptr);
4373 err = nl80211_key_allowed(dev->ieee80211_ptr);
f8af764b
JM
4374 if (err)
4375 GENL_SET_ERR_MSG(info, "key not allowed");
4376 if (!err) {
e35e4d28
HG
4377 err = rdev_add_key(rdev, dev, key.idx,
4378 key.type == NL80211_KEYTYPE_PAIRWISE,
4379 mac_addr, &key.p);
f8af764b
JM
4380 if (err)
4381 GENL_SET_ERR_MSG(info, "key addition failed");
4382 }
fffd0934 4383 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4384
41ade00f
JB
4385 return err;
4386}
4387
4388static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
4389{
4c476991 4390 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 4391 int err;
4c476991 4392 struct net_device *dev = info->user_ptr[1];
41ade00f 4393 u8 *mac_addr = NULL;
b9454e83 4394 struct key_parse key;
41ade00f 4395
b9454e83
JB
4396 err = nl80211_parse_key(info, &key);
4397 if (err)
4398 return err;
41ade00f
JB
4399
4400 if (info->attrs[NL80211_ATTR_MAC])
4401 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4402
e31b8213
JB
4403 if (key.type == -1) {
4404 if (mac_addr)
4405 key.type = NL80211_KEYTYPE_PAIRWISE;
4406 else
4407 key.type = NL80211_KEYTYPE_GROUP;
4408 }
4409
4410 /* for now */
4411 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
4412 key.type != NL80211_KEYTYPE_GROUP)
4413 return -EINVAL;
4414
2d946308
AT
4415 if (!cfg80211_valid_key_idx(rdev, key.idx,
4416 key.type == NL80211_KEYTYPE_PAIRWISE))
4417 return -EINVAL;
4418
4c476991
JB
4419 if (!rdev->ops->del_key)
4420 return -EOPNOTSUPP;
41ade00f 4421
fffd0934
JB
4422 wdev_lock(dev->ieee80211_ptr);
4423 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 4424
0fa7b391 4425 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
4426 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4427 err = -ENOENT;
4428
fffd0934 4429 if (!err)
e35e4d28
HG
4430 err = rdev_del_key(rdev, dev, key.idx,
4431 key.type == NL80211_KEYTYPE_PAIRWISE,
4432 mac_addr);
41ade00f 4433
3d23e349 4434#ifdef CONFIG_CFG80211_WEXT
08645126 4435 if (!err) {
b9454e83 4436 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 4437 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 4438 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
4439 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
4440 }
4441#endif
fffd0934 4442 wdev_unlock(dev->ieee80211_ptr);
08645126 4443
41ade00f
JB
4444 return err;
4445}
4446
77765eaf
VT
4447/* This function returns an error or the number of nested attributes */
4448static int validate_acl_mac_addrs(struct nlattr *nl_attr)
4449{
4450 struct nlattr *attr;
4451 int n_entries = 0, tmp;
4452
4453 nla_for_each_nested(attr, nl_attr, tmp) {
4454 if (nla_len(attr) != ETH_ALEN)
4455 return -EINVAL;
4456
4457 n_entries++;
4458 }
4459
4460 return n_entries;
4461}
4462
4463/*
4464 * This function parses ACL information and allocates memory for ACL data.
4465 * On successful return, the calling function is responsible to free the
4466 * ACL buffer returned by this function.
4467 */
4468static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
4469 struct genl_info *info)
4470{
4471 enum nl80211_acl_policy acl_policy;
4472 struct nlattr *attr;
4473 struct cfg80211_acl_data *acl;
4474 int i = 0, n_entries, tmp;
4475
4476 if (!wiphy->max_acl_mac_addrs)
4477 return ERR_PTR(-EOPNOTSUPP);
4478
4479 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
4480 return ERR_PTR(-EINVAL);
4481
4482 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
4483 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
4484 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
4485 return ERR_PTR(-EINVAL);
4486
4487 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
4488 return ERR_PTR(-EINVAL);
4489
4490 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
4491 if (n_entries < 0)
4492 return ERR_PTR(n_entries);
4493
4494 if (n_entries > wiphy->max_acl_mac_addrs)
4495 return ERR_PTR(-ENOTSUPP);
4496
391d132c 4497 acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
77765eaf
VT
4498 if (!acl)
4499 return ERR_PTR(-ENOMEM);
4500
4501 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
4502 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
4503 i++;
4504 }
4505
4506 acl->n_acl_entries = n_entries;
4507 acl->acl_policy = acl_policy;
4508
4509 return acl;
4510}
4511
4512static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
4513{
4514 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4515 struct net_device *dev = info->user_ptr[1];
4516 struct cfg80211_acl_data *acl;
4517 int err;
4518
4519 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4520 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4521 return -EOPNOTSUPP;
4522
4523 if (!dev->ieee80211_ptr->beacon_interval)
4524 return -EINVAL;
4525
4526 acl = parse_acl_data(&rdev->wiphy, info);
4527 if (IS_ERR(acl))
4528 return PTR_ERR(acl);
4529
4530 err = rdev_set_mac_acl(rdev, dev, acl);
4531
4532 kfree(acl);
4533
4534 return err;
4535}
4536
a7c7fbff
PK
4537static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
4538 u8 *rates, u8 rates_len)
4539{
4540 u8 i;
4541 u32 mask = 0;
4542
4543 for (i = 0; i < rates_len; i++) {
4544 int rate = (rates[i] & 0x7f) * 5;
4545 int ridx;
4546
4547 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
4548 struct ieee80211_rate *srate =
4549 &sband->bitrates[ridx];
4550 if (rate == srate->bitrate) {
4551 mask |= 1 << ridx;
4552 break;
4553 }
4554 }
4555 if (ridx == sband->n_bitrates)
4556 return 0; /* rate not found */
4557 }
4558
4559 return mask;
4560}
4561
4562static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
4563 u8 *rates, u8 rates_len,
4564 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
4565{
4566 u8 i;
4567
4568 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
4569
4570 for (i = 0; i < rates_len; i++) {
4571 int ridx, rbit;
4572
4573 ridx = rates[i] / 8;
4574 rbit = BIT(rates[i] % 8);
4575
4576 /* check validity */
4577 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
4578 return false;
4579
4580 /* check availability */
30fe6d50 4581 ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
a7c7fbff
PK
4582 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
4583 mcs[ridx] |= rbit;
4584 else
4585 return false;
4586 }
4587
4588 return true;
4589}
4590
4591static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
4592{
4593 u16 mcs_mask = 0;
4594
4595 switch (vht_mcs_map) {
4596 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
4597 break;
4598 case IEEE80211_VHT_MCS_SUPPORT_0_7:
4599 mcs_mask = 0x00FF;
4600 break;
4601 case IEEE80211_VHT_MCS_SUPPORT_0_8:
4602 mcs_mask = 0x01FF;
4603 break;
4604 case IEEE80211_VHT_MCS_SUPPORT_0_9:
4605 mcs_mask = 0x03FF;
4606 break;
4607 default:
4608 break;
4609 }
4610
4611 return mcs_mask;
4612}
4613
4614static void vht_build_mcs_mask(u16 vht_mcs_map,
4615 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
4616{
4617 u8 nss;
4618
4619 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
4620 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
4621 vht_mcs_map >>= 2;
4622 }
4623}
4624
4625static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
4626 struct nl80211_txrate_vht *txrate,
4627 u16 mcs[NL80211_VHT_NSS_MAX])
4628{
4629 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4630 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
4631 u8 i;
4632
4633 if (!sband->vht_cap.vht_supported)
4634 return false;
4635
4636 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
4637
4638 /* Build vht_mcs_mask from VHT capabilities */
4639 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4640
4641 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
4642 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4643 mcs[i] = txrate->mcs[i];
4644 else
4645 return false;
4646 }
4647
4648 return true;
4649}
4650
eb89a6a6
MH
4651static u16 he_mcs_map_to_mcs_mask(u8 he_mcs_map)
4652{
4653 switch (he_mcs_map) {
4654 case IEEE80211_HE_MCS_NOT_SUPPORTED:
4655 return 0;
4656 case IEEE80211_HE_MCS_SUPPORT_0_7:
4657 return 0x00FF;
4658 case IEEE80211_HE_MCS_SUPPORT_0_9:
4659 return 0x03FF;
4660 case IEEE80211_HE_MCS_SUPPORT_0_11:
4661 return 0xFFF;
4662 default:
4663 break;
4664 }
4665 return 0;
4666}
4667
4668static void he_build_mcs_mask(u16 he_mcs_map,
4669 u16 he_mcs_mask[NL80211_HE_NSS_MAX])
4670{
4671 u8 nss;
4672
4673 for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
4674 he_mcs_mask[nss] = he_mcs_map_to_mcs_mask(he_mcs_map & 0x03);
4675 he_mcs_map >>= 2;
4676 }
4677}
4678
4679static u16 he_get_txmcsmap(struct genl_info *info,
4680 const struct ieee80211_sta_he_cap *he_cap)
4681{
4682 struct net_device *dev = info->user_ptr[1];
4683 struct wireless_dev *wdev = dev->ieee80211_ptr;
4684 __le16 tx_mcs;
4685
4686 switch (wdev->chandef.width) {
4687 case NL80211_CHAN_WIDTH_80P80:
4688 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80p80;
4689 break;
4690 case NL80211_CHAN_WIDTH_160:
4691 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_160;
4692 break;
4693 default:
4694 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80;
4695 break;
4696 }
4697 return le16_to_cpu(tx_mcs);
4698}
4699
4700static bool he_set_mcs_mask(struct genl_info *info,
4701 struct wireless_dev *wdev,
4702 struct ieee80211_supported_band *sband,
4703 struct nl80211_txrate_he *txrate,
4704 u16 mcs[NL80211_HE_NSS_MAX])
4705{
4706 const struct ieee80211_sta_he_cap *he_cap;
4707 u16 tx_mcs_mask[NL80211_HE_NSS_MAX] = {};
4708 u16 tx_mcs_map = 0;
4709 u8 i;
4710
4711 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
4712 if (!he_cap)
4713 return false;
4714
4715 memset(mcs, 0, sizeof(u16) * NL80211_HE_NSS_MAX);
4716
4717 tx_mcs_map = he_get_txmcsmap(info, he_cap);
4718
4719 /* Build he_mcs_mask from HE capabilities */
4720 he_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4721
4722 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
4723 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4724 mcs[i] = txrate->mcs[i];
4725 else
4726 return false;
4727 }
4728
4729 return true;
4730}
4731
a7c7fbff 4732static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
9a5f6488
TC
4733 struct nlattr *attrs[],
4734 enum nl80211_attrs attr,
eb89a6a6 4735 struct cfg80211_bitrate_mask *mask,
857b34c4
RM
4736 struct net_device *dev,
4737 bool default_all_enabled)
a7c7fbff
PK
4738{
4739 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4740 struct cfg80211_registered_device *rdev = info->user_ptr[0];
eb89a6a6 4741 struct wireless_dev *wdev = dev->ieee80211_ptr;
a7c7fbff
PK
4742 int rem, i;
4743 struct nlattr *tx_rates;
4744 struct ieee80211_supported_band *sband;
eb89a6a6 4745 u16 vht_tx_mcs_map, he_tx_mcs_map;
a7c7fbff
PK
4746
4747 memset(mask, 0, sizeof(*mask));
4748 /* Default to all rates enabled */
4749 for (i = 0; i < NUM_NL80211_BANDS; i++) {
eb89a6a6
MH
4750 const struct ieee80211_sta_he_cap *he_cap;
4751
857b34c4
RM
4752 if (!default_all_enabled)
4753 break;
4754
a7c7fbff
PK
4755 sband = rdev->wiphy.bands[i];
4756
4757 if (!sband)
4758 continue;
4759
4760 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
4761 memcpy(mask->control[i].ht_mcs,
4762 sband->ht_cap.mcs.rx_mask,
4763 sizeof(mask->control[i].ht_mcs));
4764
4765 if (!sband->vht_cap.vht_supported)
4766 continue;
4767
4768 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4769 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
eb89a6a6
MH
4770
4771 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
4772 if (!he_cap)
4773 continue;
4774
4775 he_tx_mcs_map = he_get_txmcsmap(info, he_cap);
4776 he_build_mcs_mask(he_tx_mcs_map, mask->control[i].he_mcs);
4777
4778 mask->control[i].he_gi = 0xFF;
4779 mask->control[i].he_ltf = 0xFF;
a7c7fbff
PK
4780 }
4781
4782 /* if no rates are given set it back to the defaults */
9a5f6488 4783 if (!attrs[attr])
a7c7fbff
PK
4784 goto out;
4785
4786 /* The nested attribute uses enum nl80211_band as the index. This maps
4787 * directly to the enum nl80211_band values used in cfg80211.
4788 */
4789 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
9a5f6488 4790 nla_for_each_nested(tx_rates, attrs[attr], rem) {
a7c7fbff
PK
4791 enum nl80211_band band = nla_type(tx_rates);
4792 int err;
4793
4794 if (band < 0 || band >= NUM_NL80211_BANDS)
4795 return -EINVAL;
4796 sband = rdev->wiphy.bands[band];
4797 if (sband == NULL)
4798 return -EINVAL;
8cb08174
JB
4799 err = nla_parse_nested_deprecated(tb, NL80211_TXRATE_MAX,
4800 tx_rates,
4801 nl80211_txattr_policy,
4802 info->extack);
a7c7fbff
PK
4803 if (err)
4804 return err;
4805 if (tb[NL80211_TXRATE_LEGACY]) {
4806 mask->control[band].legacy = rateset_to_mask(
4807 sband,
4808 nla_data(tb[NL80211_TXRATE_LEGACY]),
4809 nla_len(tb[NL80211_TXRATE_LEGACY]));
4810 if ((mask->control[band].legacy == 0) &&
4811 nla_len(tb[NL80211_TXRATE_LEGACY]))
4812 return -EINVAL;
4813 }
4814 if (tb[NL80211_TXRATE_HT]) {
4815 if (!ht_rateset_to_mask(
4816 sband,
4817 nla_data(tb[NL80211_TXRATE_HT]),
4818 nla_len(tb[NL80211_TXRATE_HT]),
4819 mask->control[band].ht_mcs))
4820 return -EINVAL;
4821 }
c4a30446 4822
a7c7fbff
PK
4823 if (tb[NL80211_TXRATE_VHT]) {
4824 if (!vht_set_mcs_mask(
4825 sband,
4826 nla_data(tb[NL80211_TXRATE_VHT]),
4827 mask->control[band].vht_mcs))
4828 return -EINVAL;
4829 }
c4a30446 4830
a7c7fbff
PK
4831 if (tb[NL80211_TXRATE_GI]) {
4832 mask->control[band].gi =
4833 nla_get_u8(tb[NL80211_TXRATE_GI]);
4834 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
4835 return -EINVAL;
4836 }
eb89a6a6
MH
4837 if (tb[NL80211_TXRATE_HE] &&
4838 !he_set_mcs_mask(info, wdev, sband,
4839 nla_data(tb[NL80211_TXRATE_HE]),
4840 mask->control[band].he_mcs))
4841 return -EINVAL;
c4a30446 4842
eb89a6a6
MH
4843 if (tb[NL80211_TXRATE_HE_GI])
4844 mask->control[band].he_gi =
4845 nla_get_u8(tb[NL80211_TXRATE_HE_GI]);
4846 if (tb[NL80211_TXRATE_HE_LTF])
4847 mask->control[band].he_ltf =
4848 nla_get_u8(tb[NL80211_TXRATE_HE_LTF]);
a7c7fbff
PK
4849
4850 if (mask->control[band].legacy == 0) {
eb89a6a6 4851 /* don't allow empty legacy rates if HT, VHT or HE
a7c7fbff
PK
4852 * are not even supported.
4853 */
4854 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
eb89a6a6
MH
4855 rdev->wiphy.bands[band]->vht_cap.vht_supported ||
4856 ieee80211_get_he_iftype_cap(sband, wdev->iftype)))
a7c7fbff
PK
4857 return -EINVAL;
4858
4859 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
4860 if (mask->control[band].ht_mcs[i])
4861 goto out;
4862
4863 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
4864 if (mask->control[band].vht_mcs[i])
4865 goto out;
4866
eb89a6a6
MH
4867 for (i = 0; i < NL80211_HE_NSS_MAX; i++)
4868 if (mask->control[band].he_mcs[i])
4869 goto out;
4870
a7c7fbff
PK
4871 /* legacy and mcs rates may not be both empty */
4872 return -EINVAL;
4873 }
4874 }
4875
4876out:
4877 return 0;
4878}
4879
8564e382
JB
4880static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
4881 enum nl80211_band band,
4882 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 4883{
c4a30446 4884 u32 count_ht, count_vht, count_he, i;
8564e382 4885 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
4886
4887 /* Allow only one rate */
4888 if (hweight32(rate) > 1)
4889 return -EINVAL;
4890
4891 count_ht = 0;
4892 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 4893 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 4894 return -EINVAL;
8564e382 4895 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
4896 count_ht++;
4897 if (count_ht > 1)
4898 return -EINVAL;
4899 }
4900 if (count_ht && rate)
4901 return -EINVAL;
4902 }
4903
4904 count_vht = 0;
4905 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 4906 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 4907 return -EINVAL;
8564e382 4908 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
4909 count_vht++;
4910 if (count_vht > 1)
4911 return -EINVAL;
4912 }
4913 if (count_vht && rate)
4914 return -EINVAL;
4915 }
4916
c4a30446
RM
4917 count_he = 0;
4918 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
4919 if (hweight16(beacon_rate->control[band].he_mcs[i]) > 1) {
4920 return -EINVAL;
4921 } else if (beacon_rate->control[band].he_mcs[i]) {
4922 count_he++;
4923 if (count_he > 1)
4924 return -EINVAL;
4925 }
4926 if (count_he && rate)
4927 return -EINVAL;
4928 }
4929
4930 if ((count_ht && count_vht && count_he) ||
4931 (!rate && !count_ht && !count_vht && !count_he))
a7c7fbff
PK
4932 return -EINVAL;
4933
8564e382
JB
4934 if (rate &&
4935 !wiphy_ext_feature_isset(&rdev->wiphy,
4936 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
4937 return -EINVAL;
4938 if (count_ht &&
4939 !wiphy_ext_feature_isset(&rdev->wiphy,
4940 NL80211_EXT_FEATURE_BEACON_RATE_HT))
4941 return -EINVAL;
4942 if (count_vht &&
4943 !wiphy_ext_feature_isset(&rdev->wiphy,
4944 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
4945 return -EINVAL;
c4a30446
RM
4946 if (count_he &&
4947 !wiphy_ext_feature_isset(&rdev->wiphy,
4948 NL80211_EXT_FEATURE_BEACON_RATE_HE))
4949 return -EINVAL;
8564e382 4950
a7c7fbff
PK
4951 return 0;
4952}
4953
81e54d08
PKC
4954static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
4955 struct nlattr *attrs[],
8860020e 4956 struct cfg80211_beacon_data *bcn)
ed1b6cc7 4957{
8860020e 4958 bool haveinfo = false;
81e54d08 4959 int err;
ed1b6cc7 4960
8860020e 4961 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 4962
a1193be8
SW
4963 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
4964 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
4965 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
4966 if (!bcn->head_len)
4967 return -EINVAL;
4968 haveinfo = true;
ed1b6cc7
JB
4969 }
4970
a1193be8
SW
4971 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
4972 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
4973 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 4974 haveinfo = true;
ed1b6cc7
JB
4975 }
4976
4c476991
JB
4977 if (!haveinfo)
4978 return -EINVAL;
3b85875a 4979
a1193be8
SW
4980 if (attrs[NL80211_ATTR_IE]) {
4981 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
4982 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
4983 }
4984
a1193be8 4985 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 4986 bcn->proberesp_ies =
a1193be8 4987 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 4988 bcn->proberesp_ies_len =
a1193be8 4989 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
4990 }
4991
a1193be8 4992 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 4993 bcn->assocresp_ies =
a1193be8 4994 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 4995 bcn->assocresp_ies_len =
a1193be8 4996 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
4997 }
4998
a1193be8
SW
4999 if (attrs[NL80211_ATTR_PROBE_RESP]) {
5000 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
5001 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
5002 }
5003
81e54d08
PKC
5004 if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
5005 struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
5006
8cb08174
JB
5007 err = nla_parse_nested_deprecated(tb,
5008 NL80211_FTM_RESP_ATTR_MAX,
5009 attrs[NL80211_ATTR_FTM_RESPONDER],
5010 NULL, NULL);
81e54d08
PKC
5011 if (err)
5012 return err;
5013
5014 if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
5015 wiphy_ext_feature_isset(&rdev->wiphy,
5016 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
5017 bcn->ftm_responder = 1;
5018 else
5019 return -EOPNOTSUPP;
5020
5021 if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
5022 bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
5023 bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
5024 }
5025
5026 if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
5027 bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5028 bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5029 }
5030 } else {
5031 bcn->ftm_responder = -1;
5032 }
5033
8860020e
JB
5034 return 0;
5035}
5036
796e90f4
JC
5037static int nl80211_parse_he_obss_pd(struct nlattr *attrs,
5038 struct ieee80211_he_obss_pd *he_obss_pd)
5039{
5040 struct nlattr *tb[NL80211_HE_OBSS_PD_ATTR_MAX + 1];
5041 int err;
5042
5043 err = nla_parse_nested(tb, NL80211_HE_OBSS_PD_ATTR_MAX, attrs,
5044 he_obss_pd_policy, NULL);
5045 if (err)
5046 return err;
5047
f5bec330
RM
5048 if (!tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL])
5049 return -EINVAL;
5050
5051 he_obss_pd->sr_ctrl = nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL]);
5052
6c8b6e4a
RM
5053 if (tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET])
5054 he_obss_pd->min_offset =
5055 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
5056 if (tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
5057 he_obss_pd->max_offset =
5058 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
f5bec330
RM
5059 if (tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET])
5060 he_obss_pd->non_srg_max_offset =
5061 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET]);
6c8b6e4a
RM
5062
5063 if (he_obss_pd->min_offset > he_obss_pd->max_offset)
796e90f4
JC
5064 return -EINVAL;
5065
f5bec330
RM
5066 if (tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP])
5067 memcpy(he_obss_pd->bss_color_bitmap,
5068 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP]),
5069 sizeof(he_obss_pd->bss_color_bitmap));
5070
5071 if (tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP])
5072 memcpy(he_obss_pd->partial_bssid_bitmap,
5073 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP]),
5074 sizeof(he_obss_pd->partial_bssid_bitmap));
5075
796e90f4
JC
5076 he_obss_pd->enable = true;
5077
5078 return 0;
5079}
5080
5c5e52d1
JC
5081static int nl80211_parse_he_bss_color(struct nlattr *attrs,
5082 struct cfg80211_he_bss_color *he_bss_color)
5083{
5084 struct nlattr *tb[NL80211_HE_BSS_COLOR_ATTR_MAX + 1];
5085 int err;
5086
5087 err = nla_parse_nested(tb, NL80211_HE_BSS_COLOR_ATTR_MAX, attrs,
5088 he_bss_color_policy, NULL);
5089 if (err)
5090 return err;
5091
5092 if (!tb[NL80211_HE_BSS_COLOR_ATTR_COLOR])
5093 return -EINVAL;
5094
5095 he_bss_color->color =
5096 nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
75e6b594
JB
5097 he_bss_color->enabled =
5098 !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
5c5e52d1
JC
5099 he_bss_color->partial =
5100 nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
5101
5102 return 0;
5103}
5104
291c49de
AD
5105static int nl80211_parse_fils_discovery(struct cfg80211_registered_device *rdev,
5106 struct nlattr *attrs,
5107 struct cfg80211_ap_settings *params)
5108{
5109 struct nlattr *tb[NL80211_FILS_DISCOVERY_ATTR_MAX + 1];
5110 int ret;
5111 struct cfg80211_fils_discovery *fd = &params->fils_discovery;
5112
5113 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5114 NL80211_EXT_FEATURE_FILS_DISCOVERY))
5115 return -EINVAL;
5116
5117 ret = nla_parse_nested(tb, NL80211_FILS_DISCOVERY_ATTR_MAX, attrs,
5118 NULL, NULL);
5119 if (ret)
5120 return ret;
5121
5122 if (!tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN] ||
5123 !tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX] ||
5124 !tb[NL80211_FILS_DISCOVERY_ATTR_TMPL])
5125 return -EINVAL;
5126
5127 fd->tmpl_len = nla_len(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5128 fd->tmpl = nla_data(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5129 fd->min_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN]);
5130 fd->max_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX]);
5131
5132 return 0;
5133}
5134
7443dcd1
AD
5135static int
5136nl80211_parse_unsol_bcast_probe_resp(struct cfg80211_registered_device *rdev,
5137 struct nlattr *attrs,
5138 struct cfg80211_ap_settings *params)
5139{
5140 struct nlattr *tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1];
5141 int ret;
5142 struct cfg80211_unsol_bcast_probe_resp *presp =
5143 &params->unsol_bcast_probe_resp;
5144
5145 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5146 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
5147 return -EINVAL;
5148
5149 ret = nla_parse_nested(tb, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX,
5150 attrs, NULL, NULL);
5151 if (ret)
5152 return ret;
5153
5154 if (!tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] ||
5155 !tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL])
5156 return -EINVAL;
5157
5158 presp->tmpl = nla_data(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5159 presp->tmpl_len = nla_len(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5160 presp->interval = nla_get_u32(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT]);
5161 return 0;
5162}
5163
66cd794e
JB
5164static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
5165 const u8 *rates)
5166{
5167 int i;
5168
5169 if (!rates)
5170 return;
5171
5172 for (i = 0; i < rates[1]; i++) {
5173 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
5174 params->ht_required = true;
5175 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
5176 params->vht_required = true;
2a392596
IP
5177 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HE_PHY)
5178 params->he_required = true;
d6587602
IP
5179 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_SAE_H2E)
5180 params->sae_h2e_required = true;
66cd794e
JB
5181 }
5182}
5183
5184/*
5185 * Since the nl80211 API didn't include, from the beginning, attributes about
5186 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
5187 * benefit of drivers that rebuild IEs in the firmware.
5188 */
5189static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
5190{
5191 const struct cfg80211_beacon_data *bcn = &params->beacon;
ba83bfb1
IM
5192 size_t ies_len = bcn->tail_len;
5193 const u8 *ies = bcn->tail;
66cd794e
JB
5194 const u8 *rates;
5195 const u8 *cap;
5196
5197 rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
5198 nl80211_check_ap_rate_selectors(params, rates);
5199
5200 rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
5201 nl80211_check_ap_rate_selectors(params, rates);
5202
5203 cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
5204 if (cap && cap[1] >= sizeof(*params->ht_cap))
5205 params->ht_cap = (void *)(cap + 2);
5206 cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
5207 if (cap && cap[1] >= sizeof(*params->vht_cap))
5208 params->vht_cap = (void *)(cap + 2);
244eb9ae
ST
5209 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
5210 if (cap && cap[1] >= sizeof(*params->he_cap) + 1)
5211 params->he_cap = (void *)(cap + 3);
7e8d6f12
ST
5212 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
5213 if (cap && cap[1] >= sizeof(*params->he_oper) + 1)
5214 params->he_oper = (void *)(cap + 3);
66cd794e
JB
5215}
5216
46c1dd0c
FF
5217static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
5218 struct cfg80211_ap_settings *params)
5219{
5220 struct wireless_dev *wdev;
5221 bool ret = false;
5222
53873f13 5223 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
5224 if (wdev->iftype != NL80211_IFTYPE_AP &&
5225 wdev->iftype != NL80211_IFTYPE_P2P_GO)
5226 continue;
5227
683b6d3b 5228 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
5229 continue;
5230
683b6d3b 5231 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
5232 ret = true;
5233 break;
5234 }
5235
46c1dd0c
FF
5236 return ret;
5237}
5238
e39e5b5e
JM
5239static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
5240 enum nl80211_auth_type auth_type,
5241 enum nl80211_commands cmd)
5242{
5243 if (auth_type > NL80211_AUTHTYPE_MAX)
5244 return false;
5245
5246 switch (cmd) {
5247 case NL80211_CMD_AUTHENTICATE:
5248 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
5249 auth_type == NL80211_AUTHTYPE_SAE)
5250 return false;
63181060
JM
5251 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5252 NL80211_EXT_FEATURE_FILS_STA) &&
5253 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
5254 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5255 auth_type == NL80211_AUTHTYPE_FILS_PK))
5256 return false;
e39e5b5e
JM
5257 return true;
5258 case NL80211_CMD_CONNECT:
10773a7c 5259 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
26f7044e
CHH
5260 !wiphy_ext_feature_isset(&rdev->wiphy,
5261 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
10773a7c 5262 auth_type == NL80211_AUTHTYPE_SAE)
a3caf744 5263 return false;
10773a7c 5264
a3caf744
VK
5265 /* FILS with SK PFS or PK not supported yet */
5266 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5267 auth_type == NL80211_AUTHTYPE_FILS_PK)
5268 return false;
5269 if (!wiphy_ext_feature_isset(
5270 &rdev->wiphy,
5271 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
5272 auth_type == NL80211_AUTHTYPE_FILS_SK)
5273 return false;
5274 return true;
e39e5b5e 5275 case NL80211_CMD_START_AP:
2831a631
CHH
5276 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5277 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP) &&
5278 auth_type == NL80211_AUTHTYPE_SAE)
e39e5b5e 5279 return false;
63181060
JM
5280 /* FILS not supported yet */
5281 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
5282 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5283 auth_type == NL80211_AUTHTYPE_FILS_PK)
5284 return false;
e39e5b5e
JM
5285 return true;
5286 default:
5287 return false;
5288 }
5289}
5290
8860020e
JB
5291static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
5292{
5293 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5294 struct net_device *dev = info->user_ptr[1];
5295 struct wireless_dev *wdev = dev->ieee80211_ptr;
5296 struct cfg80211_ap_settings params;
5297 int err;
5298
5299 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5300 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5301 return -EOPNOTSUPP;
5302
5303 if (!rdev->ops->start_ap)
5304 return -EOPNOTSUPP;
5305
5306 if (wdev->beacon_interval)
5307 return -EALREADY;
5308
5309 memset(&params, 0, sizeof(params));
5310
5311 /* these are required for START_AP */
5312 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
5313 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
5314 !info->attrs[NL80211_ATTR_BEACON_HEAD])
5315 return -EINVAL;
5316
81e54d08 5317 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon);
8860020e
JB
5318 if (err)
5319 return err;
5320
5321 params.beacon_interval =
5322 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
5323 params.dtim_period =
5324 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
5325
0c317a02
PK
5326 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
5327 params.beacon_interval);
8860020e
JB
5328 if (err)
5329 return err;
5330
5331 /*
5332 * In theory, some of these attributes should be required here
5333 * but since they were not used when the command was originally
5334 * added, keep them optional for old user space programs to let
5335 * them continue to work with drivers that do not need the
5336 * additional information -- drivers must check!
5337 */
5338 if (info->attrs[NL80211_ATTR_SSID]) {
5339 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
5340 params.ssid_len =
5341 nla_len(info->attrs[NL80211_ATTR_SSID]);
cb9abd48 5342 if (params.ssid_len == 0)
8860020e
JB
5343 return -EINVAL;
5344 }
5345
ab0d76f6 5346 if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
8860020e
JB
5347 params.hidden_ssid = nla_get_u32(
5348 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
8860020e
JB
5349
5350 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
5351
5352 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
5353 params.auth_type = nla_get_u32(
5354 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
5355 if (!nl80211_valid_auth_type(rdev, params.auth_type,
5356 NL80211_CMD_START_AP))
8860020e
JB
5357 return -EINVAL;
5358 } else
5359 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
5360
5361 err = nl80211_crypto_settings(rdev, info, &params.crypto,
5362 NL80211_MAX_NR_CIPHER_SUITES);
5363 if (err)
5364 return err;
5365
1b658f11
VT
5366 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
5367 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
5368 return -EOPNOTSUPP;
5369 params.inactivity_timeout = nla_get_u16(
5370 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
5371 }
5372
53cabad7
JB
5373 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
5374 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5375 return -EINVAL;
5376 params.p2p_ctwindow =
5377 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
5378 if (params.p2p_ctwindow != 0 &&
5379 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5380 return -EINVAL;
5381 }
5382
5383 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5384 u8 tmp;
5385
5386 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5387 return -EINVAL;
5388 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
5389 params.p2p_opp_ps = tmp;
5390 if (params.p2p_opp_ps != 0 &&
5391 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
5392 return -EINVAL;
5393 }
5394
aa430da4 5395 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
5396 err = nl80211_parse_chandef(rdev, info, &params.chandef);
5397 if (err)
5398 return err;
5399 } else if (wdev->preset_chandef.chan) {
5400 params.chandef = wdev->preset_chandef;
46c1dd0c 5401 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
5402 return -EINVAL;
5403
923b352f
AN
5404 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
5405 wdev->iftype))
aa430da4
JB
5406 return -EINVAL;
5407
a7c7fbff 5408 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9a5f6488
TC
5409 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
5410 NL80211_ATTR_TX_RATES,
eb89a6a6 5411 &params.beacon_rate,
857b34c4 5412 dev, false);
a7c7fbff
PK
5413 if (err)
5414 return err;
5415
8564e382
JB
5416 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
5417 &params.beacon_rate);
a7c7fbff
PK
5418 if (err)
5419 return err;
5420 }
5421
18998c38
EP
5422 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
5423 params.smps_mode =
5424 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
5425 switch (params.smps_mode) {
5426 case NL80211_SMPS_OFF:
5427 break;
5428 case NL80211_SMPS_STATIC:
5429 if (!(rdev->wiphy.features &
5430 NL80211_FEATURE_STATIC_SMPS))
5431 return -EINVAL;
5432 break;
5433 case NL80211_SMPS_DYNAMIC:
5434 if (!(rdev->wiphy.features &
5435 NL80211_FEATURE_DYNAMIC_SMPS))
5436 return -EINVAL;
5437 break;
5438 default:
5439 return -EINVAL;
5440 }
5441 } else {
5442 params.smps_mode = NL80211_SMPS_OFF;
5443 }
5444
6e8ef842
PK
5445 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
5446 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
5447 return -EOPNOTSUPP;
5448
4baf6bea
OO
5449 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
5450 params.acl = parse_acl_data(&rdev->wiphy, info);
5451 if (IS_ERR(params.acl))
5452 return PTR_ERR(params.acl);
5453 }
5454
a0de1ca3
JC
5455 params.twt_responder =
5456 nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
5457
796e90f4
JC
5458 if (info->attrs[NL80211_ATTR_HE_OBSS_PD]) {
5459 err = nl80211_parse_he_obss_pd(
5460 info->attrs[NL80211_ATTR_HE_OBSS_PD],
5461 &params.he_obss_pd);
bc7a39b4
LC
5462 if (err)
5463 goto out;
796e90f4
JC
5464 }
5465
5c5e52d1
JC
5466 if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
5467 err = nl80211_parse_he_bss_color(
5468 info->attrs[NL80211_ATTR_HE_BSS_COLOR],
5469 &params.he_bss_color);
5470 if (err)
60a0121f 5471 goto out;
5c5e52d1
JC
5472 }
5473
291c49de
AD
5474 if (info->attrs[NL80211_ATTR_FILS_DISCOVERY]) {
5475 err = nl80211_parse_fils_discovery(rdev,
5476 info->attrs[NL80211_ATTR_FILS_DISCOVERY],
5477 &params);
5478 if (err)
5479 goto out;
5480 }
5481
7443dcd1
AD
5482 if (info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP]) {
5483 err = nl80211_parse_unsol_bcast_probe_resp(
5484 rdev, info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP],
5485 &params);
5486 if (err)
5487 return err;
5488 }
5489
66cd794e
JB
5490 nl80211_calculate_ap_params(&params);
5491
fe494370
SD
5492 if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
5493 params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
5494
c56589ed 5495 wdev_lock(wdev);
e35e4d28 5496 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 5497 if (!err) {
683b6d3b 5498 wdev->preset_chandef = params.chandef;
8860020e 5499 wdev->beacon_interval = params.beacon_interval;
9e0e2961 5500 wdev->chandef = params.chandef;
06e191e2
AQ
5501 wdev->ssid_len = params.ssid_len;
5502 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
466a3061
DK
5503
5504 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
5505 wdev->conn_owner_nlportid = info->snd_portid;
46c1dd0c 5506 }
c56589ed 5507 wdev_unlock(wdev);
77765eaf 5508
9951ebfc 5509out:
77765eaf
VT
5510 kfree(params.acl);
5511
56d1893d 5512 return err;
ed1b6cc7
JB
5513}
5514
8860020e
JB
5515static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
5516{
5517 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5518 struct net_device *dev = info->user_ptr[1];
5519 struct wireless_dev *wdev = dev->ieee80211_ptr;
5520 struct cfg80211_beacon_data params;
5521 int err;
5522
5523 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5524 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5525 return -EOPNOTSUPP;
5526
5527 if (!rdev->ops->change_beacon)
5528 return -EOPNOTSUPP;
5529
5530 if (!wdev->beacon_interval)
5531 return -EINVAL;
5532
81e54d08 5533 err = nl80211_parse_beacon(rdev, info->attrs, &params);
8860020e
JB
5534 if (err)
5535 return err;
5536
c56589ed
SW
5537 wdev_lock(wdev);
5538 err = rdev_change_beacon(rdev, dev, &params);
5539 wdev_unlock(wdev);
5540
5541 return err;
8860020e
JB
5542}
5543
5544static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 5545{
4c476991
JB
5546 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5547 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 5548
7c8d5e03 5549 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
5550}
5551
5727ef1b
JB
5552static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
5553 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
5554 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
5555 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 5556 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 5557 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 5558 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
5559};
5560
eccb8e8f 5561static int parse_station_flags(struct genl_info *info,
bdd3ae3d 5562 enum nl80211_iftype iftype,
eccb8e8f 5563 struct station_parameters *params)
5727ef1b
JB
5564{
5565 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 5566 struct nlattr *nla;
5727ef1b
JB
5567 int flag;
5568
eccb8e8f
JB
5569 /*
5570 * Try parsing the new attribute first so userspace
5571 * can specify both for older kernels.
5572 */
5573 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
5574 if (nla) {
5575 struct nl80211_sta_flag_update *sta_flags;
5576
5577 sta_flags = nla_data(nla);
5578 params->sta_flags_mask = sta_flags->mask;
5579 params->sta_flags_set = sta_flags->set;
77ee7c89 5580 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
5581 if ((params->sta_flags_mask |
5582 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
5583 return -EINVAL;
5584 return 0;
5585 }
5586
5587 /* if present, parse the old attribute */
5727ef1b 5588
eccb8e8f 5589 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
5590 if (!nla)
5591 return 0;
5592
8cb08174 5593 if (nla_parse_nested_deprecated(flags, NL80211_STA_FLAG_MAX, nla, sta_flags_policy, info->extack))
5727ef1b
JB
5594 return -EINVAL;
5595
bdd3ae3d
JB
5596 /*
5597 * Only allow certain flags for interface types so that
5598 * other attributes are silently ignored. Remember that
5599 * this is backward compatibility code with old userspace
5600 * and shouldn't be hit in other cases anyway.
5601 */
5602 switch (iftype) {
5603 case NL80211_IFTYPE_AP:
5604 case NL80211_IFTYPE_AP_VLAN:
5605 case NL80211_IFTYPE_P2P_GO:
5606 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5607 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
5608 BIT(NL80211_STA_FLAG_WME) |
5609 BIT(NL80211_STA_FLAG_MFP);
5610 break;
5611 case NL80211_IFTYPE_P2P_CLIENT:
5612 case NL80211_IFTYPE_STATION:
5613 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5614 BIT(NL80211_STA_FLAG_TDLS_PEER);
5615 break;
5616 case NL80211_IFTYPE_MESH_POINT:
5617 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5618 BIT(NL80211_STA_FLAG_MFP) |
5619 BIT(NL80211_STA_FLAG_AUTHORIZED);
5cf3006c 5620 break;
bdd3ae3d
JB
5621 default:
5622 return -EINVAL;
5623 }
5727ef1b 5624
3383b5a6
JB
5625 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
5626 if (flags[flag]) {
eccb8e8f 5627 params->sta_flags_set |= (1<<flag);
5727ef1b 5628
3383b5a6
JB
5629 /* no longer support new API additions in old API */
5630 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
5631 return -EINVAL;
5632 }
5633 }
5634
5727ef1b
JB
5635 return 0;
5636}
5637
9bb7e0f2 5638bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
c8dcfd8a
FF
5639{
5640 struct nlattr *rate;
8eb41c8d
VK
5641 u32 bitrate;
5642 u16 bitrate_compat;
bbf67e45 5643 enum nl80211_rate_info rate_flg;
c8dcfd8a 5644
ae0be8de 5645 rate = nla_nest_start_noflag(msg, attr);
c8dcfd8a 5646 if (!rate)
db9c64cf 5647 return false;
c8dcfd8a
FF
5648
5649 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
5650 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
5651 /* report 16-bit bitrate only if we can */
5652 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
5653 if (bitrate > 0 &&
5654 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
5655 return false;
5656 if (bitrate_compat > 0 &&
5657 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
5658 return false;
5659
b51f3bee
JB
5660 switch (info->bw) {
5661 case RATE_INFO_BW_5:
5662 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
5663 break;
5664 case RATE_INFO_BW_10:
5665 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
5666 break;
5667 default:
5668 WARN_ON(1);
7b506ff6 5669 fallthrough;
b51f3bee
JB
5670 case RATE_INFO_BW_20:
5671 rate_flg = 0;
5672 break;
5673 case RATE_INFO_BW_40:
5674 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
5675 break;
5676 case RATE_INFO_BW_80:
5677 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
5678 break;
5679 case RATE_INFO_BW_160:
5680 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
5681 break;
c4cbaf79
LC
5682 case RATE_INFO_BW_HE_RU:
5683 rate_flg = 0;
5684 WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
b51f3bee
JB
5685 }
5686
5687 if (rate_flg && nla_put_flag(msg, rate_flg))
5688 return false;
5689
db9c64cf
JB
5690 if (info->flags & RATE_INFO_FLAGS_MCS) {
5691 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
5692 return false;
db9c64cf
JB
5693 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5694 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5695 return false;
5696 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
5697 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
5698 return false;
5699 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
5700 return false;
db9c64cf
JB
5701 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5702 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5703 return false;
c4cbaf79
LC
5704 } else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
5705 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
5706 return false;
5707 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
5708 return false;
5709 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
5710 return false;
5711 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
5712 return false;
5713 if (info->bw == RATE_INFO_BW_HE_RU &&
5714 nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
5715 info->he_ru_alloc))
5716 return false;
db9c64cf 5717 }
c8dcfd8a
FF
5718
5719 nla_nest_end(msg, rate);
5720 return true;
c8dcfd8a
FF
5721}
5722
119363c7
FF
5723static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
5724 int id)
5725{
5726 void *attr;
5727 int i = 0;
5728
5729 if (!mask)
5730 return true;
5731
ae0be8de 5732 attr = nla_nest_start_noflag(msg, id);
119363c7
FF
5733 if (!attr)
5734 return false;
5735
5736 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
5737 if (!(mask & BIT(i)))
5738 continue;
5739
5740 if (nla_put_u8(msg, i, signal[i]))
5741 return false;
5742 }
5743
5744 nla_nest_end(msg, attr);
5745
5746 return true;
5747}
5748
cf5ead82
JB
5749static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
5750 u32 seq, int flags,
66266b3a
JL
5751 struct cfg80211_registered_device *rdev,
5752 struct net_device *dev,
98b62183 5753 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
5754{
5755 void *hdr;
f4263c98 5756 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 5757
cf5ead82 5758 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
f77bf486
AS
5759 if (!hdr) {
5760 cfg80211_sinfo_release_content(sinfo);
fd5b74dc 5761 return -1;
f77bf486 5762 }
fd5b74dc 5763
9360ffd1
DM
5764 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5765 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
5766 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
5767 goto nla_put_failure;
f5ea9120 5768
ae0be8de 5769 sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
2ec600d6 5770 if (!sinfoattr)
fd5b74dc 5771 goto nla_put_failure;
319090bf
JB
5772
5773#define PUT_SINFO(attr, memb, type) do { \
d686b920 5774 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
397c657a 5775 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
319090bf
JB
5776 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
5777 sinfo->memb)) \
5778 goto nla_put_failure; \
5779 } while (0)
d686b920 5780#define PUT_SINFO_U64(attr, memb) do { \
397c657a 5781 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
d686b920
JB
5782 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
5783 sinfo->memb, NL80211_STA_INFO_PAD)) \
5784 goto nla_put_failure; \
5785 } while (0)
319090bf
JB
5786
5787 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
5788 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
6c7a0033 5789 PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at);
319090bf 5790
397c657a
OE
5791 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
5792 BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 5793 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 5794 (u32)sinfo->rx_bytes))
9360ffd1 5795 goto nla_put_failure;
319090bf 5796
397c657a
OE
5797 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
5798 BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 5799 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
5800 (u32)sinfo->tx_bytes))
5801 goto nla_put_failure;
319090bf 5802
d686b920
JB
5803 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
5804 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
5805 PUT_SINFO(LLID, llid, u16);
5806 PUT_SINFO(PLID, plid, u16);
5807 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 5808 PUT_SINFO_U64(RX_DURATION, rx_duration);
36647055
THJ
5809 PUT_SINFO_U64(TX_DURATION, tx_duration);
5810
5811 if (wiphy_ext_feature_isset(&rdev->wiphy,
5812 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
5813 PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
319090bf 5814
66266b3a
JL
5815 switch (rdev->wiphy.signal_type) {
5816 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
5817 PUT_SINFO(SIGNAL, signal, u8);
5818 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
5819 break;
5820 default:
5821 break;
5822 }
397c657a 5823 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
5824 if (!nl80211_put_signal(msg, sinfo->chains,
5825 sinfo->chain_signal,
5826 NL80211_STA_INFO_CHAIN_SIGNAL))
5827 goto nla_put_failure;
5828 }
397c657a 5829 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
5830 if (!nl80211_put_signal(msg, sinfo->chains,
5831 sinfo->chain_signal_avg,
5832 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
5833 goto nla_put_failure;
5834 }
397c657a 5835 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
5836 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
5837 NL80211_STA_INFO_TX_BITRATE))
5838 goto nla_put_failure;
5839 }
397c657a 5840 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
5841 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
5842 NL80211_STA_INFO_RX_BITRATE))
420e7fab 5843 goto nla_put_failure;
420e7fab 5844 }
319090bf
JB
5845
5846 PUT_SINFO(RX_PACKETS, rx_packets, u32);
5847 PUT_SINFO(TX_PACKETS, tx_packets, u32);
5848 PUT_SINFO(TX_RETRIES, tx_retries, u32);
5849 PUT_SINFO(TX_FAILED, tx_failed, u32);
5850 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
ab60633c 5851 PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
319090bf
JB
5852 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
5853 PUT_SINFO(LOCAL_PM, local_pm, u32);
5854 PUT_SINFO(PEER_PM, peer_pm, u32);
5855 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
dbdaee7a 5856 PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
1303a51c 5857 PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8);
319090bf 5858
397c657a 5859 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
ae0be8de
MK
5860 bss_param = nla_nest_start_noflag(msg,
5861 NL80211_STA_INFO_BSS_PARAM);
f4263c98
PS
5862 if (!bss_param)
5863 goto nla_put_failure;
5864
9360ffd1
DM
5865 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
5866 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
5867 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
5868 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
5869 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
5870 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
5871 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
5872 sinfo->bss_param.dtim_period) ||
5873 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
5874 sinfo->bss_param.beacon_interval))
5875 goto nla_put_failure;
f4263c98
PS
5876
5877 nla_nest_end(msg, bss_param);
5878 }
397c657a 5879 if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
5880 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
5881 sizeof(struct nl80211_sta_flag_update),
5882 &sinfo->sta_flags))
5883 goto nla_put_failure;
319090bf 5884
d686b920
JB
5885 PUT_SINFO_U64(T_OFFSET, t_offset);
5886 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
5887 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 5888 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
0d4e14a3
AB
5889 PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
5890 PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
81d5439d 5891 if (wiphy_ext_feature_isset(&rdev->wiphy,
9c06602b
BP
5892 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
5893 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
5894 PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
5895 }
319090bf
JB
5896
5897#undef PUT_SINFO
d686b920 5898#undef PUT_SINFO_U64
6de39808 5899
8689c051 5900 if (sinfo->pertid) {
6de39808
JB
5901 struct nlattr *tidsattr;
5902 int tid;
5903
ae0be8de
MK
5904 tidsattr = nla_nest_start_noflag(msg,
5905 NL80211_STA_INFO_TID_STATS);
6de39808
JB
5906 if (!tidsattr)
5907 goto nla_put_failure;
5908
5909 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
5910 struct cfg80211_tid_stats *tidstats;
5911 struct nlattr *tidattr;
5912
5913 tidstats = &sinfo->pertid[tid];
5914
5915 if (!tidstats->filled)
5916 continue;
5917
ae0be8de 5918 tidattr = nla_nest_start_noflag(msg, tid + 1);
6de39808
JB
5919 if (!tidattr)
5920 goto nla_put_failure;
5921
d686b920 5922#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 5923 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
5924 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
5925 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
5926 goto nla_put_failure; \
5927 } while (0)
5928
d686b920
JB
5929 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
5930 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
5931 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
5932 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 5933
d686b920 5934#undef PUT_TIDVAL_U64
52539ca8
THJ
5935 if ((tidstats->filled &
5936 BIT(NL80211_TID_STATS_TXQ_STATS)) &&
5937 !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
5938 NL80211_TID_STATS_TXQ_STATS))
5939 goto nla_put_failure;
5940
6de39808
JB
5941 nla_nest_end(msg, tidattr);
5942 }
5943
5944 nla_nest_end(msg, tidsattr);
5945 }
5946
2ec600d6 5947 nla_nest_end(msg, sinfoattr);
fd5b74dc 5948
319090bf 5949 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
5950 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
5951 sinfo->assoc_req_ies))
5952 goto nla_put_failure;
50d3dfb7 5953
7ea3e110 5954 cfg80211_sinfo_release_content(sinfo);
053c095a
JB
5955 genlmsg_end(msg, hdr);
5956 return 0;
fd5b74dc
JB
5957
5958 nla_put_failure:
7ea3e110 5959 cfg80211_sinfo_release_content(sinfo);
bc3ed28c
TG
5960 genlmsg_cancel(msg, hdr);
5961 return -EMSGSIZE;
fd5b74dc
JB
5962}
5963
2ec600d6 5964static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 5965 struct netlink_callback *cb)
2ec600d6 5966{
73887fd9 5967 struct station_info sinfo;
1b8ec87a 5968 struct cfg80211_registered_device *rdev;
97990a06 5969 struct wireless_dev *wdev;
2ec600d6 5970 u8 mac_addr[ETH_ALEN];
97990a06 5971 int sta_idx = cb->args[2];
2ec600d6 5972 int err;
2ec600d6 5973
5297c65c 5974 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 5975 if (err)
a05829a7
JB
5976 return err;
5977 /* nl80211_prepare_wdev_dump acquired it in the successful case */
5978 __acquire(&rdev->wiphy.mtx);
bba95fef 5979
97990a06
JB
5980 if (!wdev->netdev) {
5981 err = -EINVAL;
5982 goto out_err;
5983 }
5984
1b8ec87a 5985 if (!rdev->ops->dump_station) {
eec60b03 5986 err = -EOPNOTSUPP;
bba95fef
JB
5987 goto out_err;
5988 }
5989
bba95fef 5990 while (1) {
73887fd9 5991 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 5992 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
73887fd9 5993 mac_addr, &sinfo);
bba95fef
JB
5994 if (err == -ENOENT)
5995 break;
5996 if (err)
3b85875a 5997 goto out_err;
bba95fef 5998
cf5ead82 5999 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 6000 NETLINK_CB(cb->skb).portid,
bba95fef 6001 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 6002 rdev, wdev->netdev, mac_addr,
73887fd9 6003 &sinfo) < 0)
bba95fef
JB
6004 goto out;
6005
6006 sta_idx++;
6007 }
6008
bba95fef 6009 out:
97990a06 6010 cb->args[2] = sta_idx;
bba95fef 6011 err = skb->len;
bba95fef 6012 out_err:
a05829a7 6013 wiphy_unlock(&rdev->wiphy);
bba95fef
JB
6014
6015 return err;
2ec600d6 6016}
fd5b74dc 6017
5727ef1b
JB
6018static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
6019{
4c476991
JB
6020 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6021 struct net_device *dev = info->user_ptr[1];
73887fd9 6022 struct station_info sinfo;
fd5b74dc
JB
6023 struct sk_buff *msg;
6024 u8 *mac_addr = NULL;
4c476991 6025 int err;
fd5b74dc 6026
73887fd9 6027 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc 6028
73887fd9
JB
6029 if (!info->attrs[NL80211_ATTR_MAC])
6030 return -EINVAL;
fd5b74dc
JB
6031
6032 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6033
73887fd9
JB
6034 if (!rdev->ops->get_station)
6035 return -EOPNOTSUPP;
3b85875a 6036
73887fd9 6037 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 6038 if (err)
73887fd9 6039 return err;
2ec600d6 6040
fd2120ca 6041 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7ea3e110 6042 if (!msg) {
ba8f566a 6043 cfg80211_sinfo_release_content(&sinfo);
73887fd9 6044 return -ENOMEM;
7ea3e110 6045 }
fd5b74dc 6046
cf5ead82
JB
6047 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
6048 info->snd_portid, info->snd_seq, 0,
73887fd9 6049 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991 6050 nlmsg_free(msg);
73887fd9 6051 return -ENOBUFS;
4c476991 6052 }
3b85875a 6053
73887fd9 6054 return genlmsg_reply(msg, info);
5727ef1b
JB
6055}
6056
77ee7c89
JB
6057int cfg80211_check_station_change(struct wiphy *wiphy,
6058 struct station_parameters *params,
6059 enum cfg80211_station_type statype)
6060{
e4208427
AB
6061 if (params->listen_interval != -1 &&
6062 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 6063 return -EINVAL;
e4208427 6064
17b94247
AB
6065 if (params->support_p2p_ps != -1 &&
6066 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
6067 return -EINVAL;
6068
c72e1140 6069 if (params->aid &&
e4208427
AB
6070 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
6071 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
6072 return -EINVAL;
6073
6074 /* When you run into this, adjust the code below for the new flag */
6075 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
6076
6077 switch (statype) {
eef941e6
TP
6078 case CFG80211_STA_MESH_PEER_KERNEL:
6079 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
6080 /*
6081 * No ignoring the TDLS flag here -- the userspace mesh
6082 * code doesn't have the bug of including TDLS in the
6083 * mask everywhere.
6084 */
6085 if (params->sta_flags_mask &
6086 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6087 BIT(NL80211_STA_FLAG_MFP) |
6088 BIT(NL80211_STA_FLAG_AUTHORIZED)))
6089 return -EINVAL;
6090 break;
6091 case CFG80211_STA_TDLS_PEER_SETUP:
6092 case CFG80211_STA_TDLS_PEER_ACTIVE:
6093 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
6094 return -EINVAL;
6095 /* ignore since it can't change */
6096 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
6097 break;
6098 default:
6099 /* disallow mesh-specific things */
6100 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
6101 return -EINVAL;
6102 if (params->local_pm)
6103 return -EINVAL;
6104 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
6105 return -EINVAL;
6106 }
6107
6108 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
6109 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
6110 /* TDLS can't be set, ... */
6111 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
6112 return -EINVAL;
6113 /*
6114 * ... but don't bother the driver with it. This works around
6115 * a hostapd/wpa_supplicant issue -- it always includes the
6116 * TLDS_PEER flag in the mask even for AP mode.
6117 */
6118 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
6119 }
6120
47edb11b
AB
6121 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
6122 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
6123 /* reject other things that can't change */
6124 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
6125 return -EINVAL;
6126 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
6127 return -EINVAL;
6128 if (params->supported_rates)
6129 return -EINVAL;
c4cbaf79
LC
6130 if (params->ext_capab || params->ht_capa || params->vht_capa ||
6131 params->he_capa)
77ee7c89
JB
6132 return -EINVAL;
6133 }
6134
47edb11b
AB
6135 if (statype != CFG80211_STA_AP_CLIENT &&
6136 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
6137 if (params->vlan)
6138 return -EINVAL;
6139 }
6140
6141 switch (statype) {
6142 case CFG80211_STA_AP_MLME_CLIENT:
6143 /* Use this only for authorizing/unauthorizing a station */
6144 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
6145 return -EOPNOTSUPP;
6146 break;
6147 case CFG80211_STA_AP_CLIENT:
47edb11b 6148 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
6149 /* accept only the listed bits */
6150 if (params->sta_flags_mask &
6151 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
6152 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6153 BIT(NL80211_STA_FLAG_ASSOCIATED) |
6154 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
6155 BIT(NL80211_STA_FLAG_WME) |
6156 BIT(NL80211_STA_FLAG_MFP)))
6157 return -EINVAL;
6158
6159 /* but authenticated/associated only if driver handles it */
6160 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
6161 params->sta_flags_mask &
6162 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6163 BIT(NL80211_STA_FLAG_ASSOCIATED)))
6164 return -EINVAL;
6165 break;
6166 case CFG80211_STA_IBSS:
6167 case CFG80211_STA_AP_STA:
6168 /* reject any changes other than AUTHORIZED */
6169 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
6170 return -EINVAL;
6171 break;
6172 case CFG80211_STA_TDLS_PEER_SETUP:
6173 /* reject any changes other than AUTHORIZED or WME */
6174 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
6175 BIT(NL80211_STA_FLAG_WME)))
6176 return -EINVAL;
6177 /* force (at least) rates when authorizing */
6178 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
6179 !params->supported_rates)
6180 return -EINVAL;
6181 break;
6182 case CFG80211_STA_TDLS_PEER_ACTIVE:
6183 /* reject any changes */
6184 return -EINVAL;
eef941e6 6185 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
6186 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
6187 return -EINVAL;
6188 break;
eef941e6 6189 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
6190 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
6191 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
6192 return -EINVAL;
6193 break;
6194 }
6195
06f7c88c
BL
6196 /*
6197 * Older kernel versions ignored this attribute entirely, so don't
6198 * reject attempts to update it but mark it as unused instead so the
6199 * driver won't look at the data.
6200 */
6201 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
6202 statype != CFG80211_STA_TDLS_PEER_SETUP)
6203 params->opmode_notif_used = false;
6204
77ee7c89
JB
6205 return 0;
6206}
6207EXPORT_SYMBOL(cfg80211_check_station_change);
6208
5727ef1b 6209/*
c258d2de 6210 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 6211 */
80b99899
JB
6212static struct net_device *get_vlan(struct genl_info *info,
6213 struct cfg80211_registered_device *rdev)
5727ef1b 6214{
463d0183 6215 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
6216 struct net_device *v;
6217 int ret;
6218
6219 if (!vlanattr)
6220 return NULL;
6221
6222 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
6223 if (!v)
6224 return ERR_PTR(-ENODEV);
6225
6226 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
6227 ret = -EINVAL;
6228 goto error;
5727ef1b 6229 }
80b99899 6230
77ee7c89
JB
6231 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
6232 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
6233 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
6234 ret = -EINVAL;
6235 goto error;
6236 }
6237
80b99899
JB
6238 if (!netif_running(v)) {
6239 ret = -ENETDOWN;
6240 goto error;
6241 }
6242
6243 return v;
6244 error:
6245 dev_put(v);
6246 return ERR_PTR(ret);
5727ef1b
JB
6247}
6248
94e860f1
JB
6249static const struct nla_policy
6250nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
6251 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
6252 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
6253};
6254
ff276691
JB
6255static int nl80211_parse_sta_wme(struct genl_info *info,
6256 struct station_parameters *params)
df881293 6257{
df881293
JM
6258 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
6259 struct nlattr *nla;
6260 int err;
6261
df881293
JM
6262 /* parse WME attributes if present */
6263 if (!info->attrs[NL80211_ATTR_STA_WME])
6264 return 0;
6265
6266 nla = info->attrs[NL80211_ATTR_STA_WME];
8cb08174
JB
6267 err = nla_parse_nested_deprecated(tb, NL80211_STA_WME_MAX, nla,
6268 nl80211_sta_wme_policy,
6269 info->extack);
df881293
JM
6270 if (err)
6271 return err;
6272
6273 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
6274 params->uapsd_queues = nla_get_u8(
6275 tb[NL80211_STA_WME_UAPSD_QUEUES]);
6276 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
6277 return -EINVAL;
6278
6279 if (tb[NL80211_STA_WME_MAX_SP])
6280 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
6281
6282 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
6283 return -EINVAL;
6284
6285 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
6286
6287 return 0;
6288}
6289
c01fc9ad
SD
6290static int nl80211_parse_sta_channel_info(struct genl_info *info,
6291 struct station_parameters *params)
6292{
6293 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
6294 params->supported_channels =
6295 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
6296 params->supported_channels_len =
6297 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
6298 /*
6299 * Need to include at least one (first channel, number of
cb9abd48
JB
6300 * channels) tuple for each subband (checked in policy),
6301 * and must have proper tuples for the rest of the data as well.
c01fc9ad 6302 */
c01fc9ad
SD
6303 if (params->supported_channels_len % 2)
6304 return -EINVAL;
6305 }
6306
6307 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
6308 params->supported_oper_classes =
6309 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
6310 params->supported_oper_classes_len =
6311 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
c01fc9ad
SD
6312 }
6313 return 0;
6314}
6315
ff276691
JB
6316static int nl80211_set_station_tdls(struct genl_info *info,
6317 struct station_parameters *params)
6318{
c01fc9ad 6319 int err;
ff276691 6320 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
6321 if (info->attrs[NL80211_ATTR_PEER_AID])
6322 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
6323 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
6324 params->ht_capa =
6325 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
6326 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
6327 params->vht_capa =
6328 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
c4cbaf79
LC
6329 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
6330 params->he_capa =
6331 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6332 params->he_capa_len =
6333 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
c4cbaf79 6334 }
ff276691 6335
c01fc9ad
SD
6336 err = nl80211_parse_sta_channel_info(info, params);
6337 if (err)
6338 return err;
6339
ff276691
JB
6340 return nl80211_parse_sta_wme(info, params);
6341}
6342
e96d1cd2
ARN
6343static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
6344 struct station_parameters *params)
6345{
6346 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6347 int idx;
6348
6349 if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
6350 if (!rdev->ops->set_tx_power ||
6351 !wiphy_ext_feature_isset(&rdev->wiphy,
6352 NL80211_EXT_FEATURE_STA_TX_PWR))
6353 return -EOPNOTSUPP;
6354
6355 idx = NL80211_ATTR_STA_TX_POWER_SETTING;
6356 params->txpwr.type = nla_get_u8(info->attrs[idx]);
6357
6358 if (params->txpwr.type == NL80211_TX_POWER_LIMITED) {
6359 idx = NL80211_ATTR_STA_TX_POWER;
6360
6361 if (info->attrs[idx])
6362 params->txpwr.power =
6363 nla_get_s16(info->attrs[idx]);
6364 else
6365 return -EINVAL;
6366 }
6367 params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER;
6368 }
6369
6370 return 0;
6371}
6372
5727ef1b
JB
6373static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
6374{
4c476991 6375 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 6376 struct net_device *dev = info->user_ptr[1];
5727ef1b 6377 struct station_parameters params;
77ee7c89
JB
6378 u8 *mac_addr;
6379 int err;
5727ef1b
JB
6380
6381 memset(&params, 0, sizeof(params));
6382
77ee7c89
JB
6383 if (!rdev->ops->change_station)
6384 return -EOPNOTSUPP;
6385
e4208427
AB
6386 /*
6387 * AID and listen_interval properties can be set only for unassociated
6388 * station. Include these parameters here and will check them in
6389 * cfg80211_check_station_change().
6390 */
a9bc31e4
AB
6391 if (info->attrs[NL80211_ATTR_STA_AID])
6392 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427 6393
14f34e36
GG
6394 if (info->attrs[NL80211_ATTR_VLAN_ID])
6395 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
6396
e4208427
AB
6397 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
6398 params.listen_interval =
6399 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
6400 else
6401 params.listen_interval = -1;
5727ef1b 6402
ab0d76f6
JB
6403 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
6404 params.support_p2p_ps =
6405 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
6406 else
17b94247 6407 params.support_p2p_ps = -1;
17b94247 6408
5727ef1b
JB
6409 if (!info->attrs[NL80211_ATTR_MAC])
6410 return -EINVAL;
6411
6412 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6413
6414 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
6415 params.supported_rates =
6416 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6417 params.supported_rates_len =
6418 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6419 }
6420
9d62a986
JM
6421 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
6422 params.capability =
6423 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
6424 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
6425 }
6426
6427 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
6428 params.ext_capab =
6429 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6430 params.ext_capab_len =
6431 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6432 }
6433
bdd3ae3d 6434 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
6435 return -EINVAL;
6436
ab0d76f6 6437 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2ec600d6 6438 params.plink_action =
f8bacc21 6439 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2ec600d6 6440
f8bacc21 6441 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 6442 params.plink_state =
f8bacc21 6443 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
ab0d76f6 6444 if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
7d27a0ba
MH
6445 params.peer_aid = nla_get_u16(
6446 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
f8bacc21
JB
6447 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
6448 }
9c3990aa 6449
ab0d76f6
JB
6450 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
6451 params.local_pm = nla_get_u32(
3b1c5a53
MP
6452 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
6453
06f7c88c
BL
6454 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
6455 params.opmode_notif_used = true;
6456 params.opmode_notif =
6457 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
6458 }
6459
43e64bf3
RM
6460 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
6461 params.he_6ghz_capa =
fce2ff72 6462 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
43e64bf3 6463
36647055
THJ
6464 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
6465 params.airtime_weight =
6466 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
6467
6468 if (params.airtime_weight &&
6469 !wiphy_ext_feature_isset(&rdev->wiphy,
6470 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6471 return -EOPNOTSUPP;
6472
e96d1cd2
ARN
6473 err = nl80211_parse_sta_txpower_setting(info, &params);
6474 if (err)
6475 return err;
6476
77ee7c89
JB
6477 /* Include parameters for TDLS peer (will check later) */
6478 err = nl80211_set_station_tdls(info, &params);
6479 if (err)
6480 return err;
6481
6482 params.vlan = get_vlan(info, rdev);
6483 if (IS_ERR(params.vlan))
6484 return PTR_ERR(params.vlan);
6485
a97f4424
JB
6486 switch (dev->ieee80211_ptr->iftype) {
6487 case NL80211_IFTYPE_AP:
6488 case NL80211_IFTYPE_AP_VLAN:
074ac8df 6489 case NL80211_IFTYPE_P2P_GO:
074ac8df 6490 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 6491 case NL80211_IFTYPE_STATION:
267335d6 6492 case NL80211_IFTYPE_ADHOC:
a97f4424 6493 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
6494 break;
6495 default:
77ee7c89
JB
6496 err = -EOPNOTSUPP;
6497 goto out_put_vlan;
034d655e
JB
6498 }
6499
77ee7c89 6500 /* driver will call cfg80211_check_station_change() */
e35e4d28 6501 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 6502
77ee7c89 6503 out_put_vlan:
5727ef1b
JB
6504 if (params.vlan)
6505 dev_put(params.vlan);
3b85875a 6506
5727ef1b
JB
6507 return err;
6508}
6509
6510static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
6511{
4c476991 6512 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 6513 int err;
4c476991 6514 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
6515 struct station_parameters params;
6516 u8 *mac_addr = NULL;
bda95eb1
JB
6517 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6518 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
6519
6520 memset(&params, 0, sizeof(params));
6521
984c311b
JB
6522 if (!rdev->ops->add_station)
6523 return -EOPNOTSUPP;
6524
5727ef1b
JB
6525 if (!info->attrs[NL80211_ATTR_MAC])
6526 return -EINVAL;
6527
5727ef1b
JB
6528 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
6529 return -EINVAL;
6530
6531 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
6532 return -EINVAL;
6533
5e4b6f56
JM
6534 if (!info->attrs[NL80211_ATTR_STA_AID] &&
6535 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
6536 return -EINVAL;
6537
5727ef1b
JB
6538 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6539 params.supported_rates =
6540 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6541 params.supported_rates_len =
6542 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6543 params.listen_interval =
6544 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 6545
14f34e36
GG
6546 if (info->attrs[NL80211_ATTR_VLAN_ID])
6547 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
6548
17b94247 6549 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
ab0d76f6
JB
6550 params.support_p2p_ps =
6551 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
17b94247
AB
6552 } else {
6553 /*
6554 * if not specified, assume it's supported for P2P GO interface,
6555 * and is NOT supported for AP interface
6556 */
6557 params.support_p2p_ps =
6558 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
6559 }
6560
3d124ea2 6561 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 6562 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
6563 else
6564 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
51b50fbe 6565
9d62a986
JM
6566 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
6567 params.capability =
6568 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
6569 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
6570 }
6571
6572 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
6573 params.ext_capab =
6574 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6575 params.ext_capab_len =
6576 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6577 }
6578
36aedc90
JM
6579 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
6580 params.ht_capa =
6581 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 6582
f461be3e
MP
6583 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
6584 params.vht_capa =
6585 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
6586
c4cbaf79
LC
6587 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
6588 params.he_capa =
6589 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6590 params.he_capa_len =
6591 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
c4cbaf79
LC
6592 }
6593
43e64bf3
RM
6594 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
6595 params.he_6ghz_capa =
6596 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
6597
60f4a7b1
MK
6598 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
6599 params.opmode_notif_used = true;
6600 params.opmode_notif =
6601 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
6602 }
6603
ab0d76f6 6604 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
96b78dff 6605 params.plink_action =
f8bacc21 6606 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
96b78dff 6607
36647055
THJ
6608 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
6609 params.airtime_weight =
6610 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
6611
6612 if (params.airtime_weight &&
6613 !wiphy_ext_feature_isset(&rdev->wiphy,
6614 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6615 return -EOPNOTSUPP;
6616
e96d1cd2
ARN
6617 err = nl80211_parse_sta_txpower_setting(info, &params);
6618 if (err)
6619 return err;
6620
c01fc9ad
SD
6621 err = nl80211_parse_sta_channel_info(info, &params);
6622 if (err)
6623 return err;
6624
ff276691
JB
6625 err = nl80211_parse_sta_wme(info, &params);
6626 if (err)
6627 return err;
bdd90d5e 6628
bdd3ae3d 6629 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
6630 return -EINVAL;
6631
496fcc29
JB
6632 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
6633 * as userspace might just pass through the capabilities from the IEs
6634 * directly, rather than enforcing this restriction and returning an
6635 * error in this case.
6636 */
6637 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
6638 params.ht_capa = NULL;
6639 params.vht_capa = NULL;
c4cbaf79
LC
6640
6641 /* HE requires WME */
43e64bf3 6642 if (params.he_capa_len || params.he_6ghz_capa)
c4cbaf79 6643 return -EINVAL;
496fcc29
JB
6644 }
6645
43e64bf3
RM
6646 /* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */
6647 if (params.he_6ghz_capa && (params.ht_capa || params.vht_capa))
6648 return -EINVAL;
6649
77ee7c89
JB
6650 /* When you run into this, adjust the code below for the new flag */
6651 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
6652
bdd90d5e
JB
6653 switch (dev->ieee80211_ptr->iftype) {
6654 case NL80211_IFTYPE_AP:
6655 case NL80211_IFTYPE_AP_VLAN:
6656 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
6657 /* ignore WME attributes if iface/sta is not capable */
6658 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
6659 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
6660 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 6661
bdd90d5e 6662 /* TDLS peers cannot be added */
3d124ea2
JM
6663 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
6664 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 6665 return -EINVAL;
bdd90d5e
JB
6666 /* but don't bother the driver with it */
6667 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 6668
d582cffb
JB
6669 /* allow authenticated/associated only if driver handles it */
6670 if (!(rdev->wiphy.features &
6671 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 6672 params.sta_flags_mask & auth_assoc)
d582cffb
JB
6673 return -EINVAL;
6674
bda95eb1
JB
6675 /* Older userspace, or userspace wanting to be compatible with
6676 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
6677 * and assoc flags in the mask, but assumes the station will be
6678 * added as associated anyway since this was the required driver
6679 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
6680 * introduced.
6681 * In order to not bother drivers with this quirk in the API
6682 * set the flags in both the mask and set for new stations in
6683 * this case.
6684 */
6685 if (!(params.sta_flags_mask & auth_assoc)) {
6686 params.sta_flags_mask |= auth_assoc;
6687 params.sta_flags_set |= auth_assoc;
6688 }
6689
bdd90d5e
JB
6690 /* must be last in here for error handling */
6691 params.vlan = get_vlan(info, rdev);
6692 if (IS_ERR(params.vlan))
6693 return PTR_ERR(params.vlan);
6694 break;
6695 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
6696 /* ignore uAPSD data */
6697 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
6698
d582cffb
JB
6699 /* associated is disallowed */
6700 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
6701 return -EINVAL;
bdd90d5e 6702 /* TDLS peers cannot be added */
3d124ea2
JM
6703 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
6704 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
6705 return -EINVAL;
6706 break;
6707 case NL80211_IFTYPE_STATION:
93d08f0b 6708 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
6709 /* ignore uAPSD data */
6710 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
6711
77ee7c89
JB
6712 /* these are disallowed */
6713 if (params.sta_flags_mask &
6714 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
6715 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 6716 return -EINVAL;
bdd90d5e
JB
6717 /* Only TDLS peers can be added */
6718 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
6719 return -EINVAL;
6720 /* Can only add if TDLS ... */
6721 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
6722 return -EOPNOTSUPP;
6723 /* ... with external setup is supported */
6724 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
6725 return -EOPNOTSUPP;
77ee7c89
JB
6726 /*
6727 * Older wpa_supplicant versions always mark the TDLS peer
6728 * as authorized, but it shouldn't yet be.
6729 */
6730 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
6731 break;
6732 default:
6733 return -EOPNOTSUPP;
c75786c9
EP
6734 }
6735
bdd90d5e 6736 /* be aware of params.vlan when changing code here */
5727ef1b 6737
e35e4d28 6738 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 6739
5727ef1b
JB
6740 if (params.vlan)
6741 dev_put(params.vlan);
5727ef1b
JB
6742 return err;
6743}
6744
6745static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
6746{
4c476991
JB
6747 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6748 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
6749 struct station_del_parameters params;
6750
6751 memset(&params, 0, sizeof(params));
5727ef1b
JB
6752
6753 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 6754 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 6755
306b79ea
JB
6756 switch (dev->ieee80211_ptr->iftype) {
6757 case NL80211_IFTYPE_AP:
6758 case NL80211_IFTYPE_AP_VLAN:
6759 case NL80211_IFTYPE_MESH_POINT:
6760 case NL80211_IFTYPE_P2P_GO:
6761 /* always accept these */
6762 break;
6763 case NL80211_IFTYPE_ADHOC:
6764 /* conditionally accept */
6765 if (wiphy_ext_feature_isset(&rdev->wiphy,
6766 NL80211_EXT_FEATURE_DEL_IBSS_STA))
6767 break;
edafcf42 6768 return -EINVAL;
306b79ea 6769 default:
4c476991 6770 return -EINVAL;
306b79ea 6771 }
5727ef1b 6772
4c476991
JB
6773 if (!rdev->ops->del_station)
6774 return -EOPNOTSUPP;
3b85875a 6775
98856866
JM
6776 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
6777 params.subtype =
6778 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
6779 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
6780 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
6781 return -EINVAL;
6782 } else {
6783 /* Default to Deauthentication frame */
6784 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
6785 }
6786
6787 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
6788 params.reason_code =
6789 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
6790 if (params.reason_code == 0)
6791 return -EINVAL; /* 0 is reserved */
6792 } else {
6793 /* Default to reason code 2 */
6794 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
6795 }
6796
89c771e5 6797 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
6798}
6799
15e47304 6800static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
6801 int flags, struct net_device *dev,
6802 u8 *dst, u8 *next_hop,
6803 struct mpath_info *pinfo)
6804{
6805 void *hdr;
6806 struct nlattr *pinfoattr;
6807
1ef4c850 6808 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
6809 if (!hdr)
6810 return -1;
6811
9360ffd1
DM
6812 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6813 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
6814 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
6815 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
6816 goto nla_put_failure;
f5ea9120 6817
ae0be8de 6818 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MPATH_INFO);
2ec600d6
LCC
6819 if (!pinfoattr)
6820 goto nla_put_failure;
9360ffd1
DM
6821 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
6822 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
6823 pinfo->frame_qlen))
6824 goto nla_put_failure;
6825 if (((pinfo->filled & MPATH_INFO_SN) &&
6826 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
6827 ((pinfo->filled & MPATH_INFO_METRIC) &&
6828 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
6829 pinfo->metric)) ||
6830 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
6831 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
6832 pinfo->exptime)) ||
6833 ((pinfo->filled & MPATH_INFO_FLAGS) &&
6834 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
6835 pinfo->flags)) ||
6836 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
6837 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
6838 pinfo->discovery_timeout)) ||
6839 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
6840 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
cc241636
JH
6841 pinfo->discovery_retries)) ||
6842 ((pinfo->filled & MPATH_INFO_HOP_COUNT) &&
6843 nla_put_u8(msg, NL80211_MPATH_INFO_HOP_COUNT,
540bbcb9
JH
6844 pinfo->hop_count)) ||
6845 ((pinfo->filled & MPATH_INFO_PATH_CHANGE) &&
6846 nla_put_u32(msg, NL80211_MPATH_INFO_PATH_CHANGE,
6847 pinfo->path_change_count)))
9360ffd1 6848 goto nla_put_failure;
2ec600d6
LCC
6849
6850 nla_nest_end(msg, pinfoattr);
6851
053c095a
JB
6852 genlmsg_end(msg, hdr);
6853 return 0;
2ec600d6
LCC
6854
6855 nla_put_failure:
bc3ed28c
TG
6856 genlmsg_cancel(msg, hdr);
6857 return -EMSGSIZE;
2ec600d6
LCC
6858}
6859
6860static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 6861 struct netlink_callback *cb)
2ec600d6 6862{
2ec600d6 6863 struct mpath_info pinfo;
1b8ec87a 6864 struct cfg80211_registered_device *rdev;
97990a06 6865 struct wireless_dev *wdev;
2ec600d6
LCC
6866 u8 dst[ETH_ALEN];
6867 u8 next_hop[ETH_ALEN];
97990a06 6868 int path_idx = cb->args[2];
2ec600d6 6869 int err;
2ec600d6 6870
5297c65c 6871 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 6872 if (err)
a05829a7
JB
6873 return err;
6874 /* nl80211_prepare_wdev_dump acquired it in the successful case */
6875 __acquire(&rdev->wiphy.mtx);
bba95fef 6876
1b8ec87a 6877 if (!rdev->ops->dump_mpath) {
eec60b03 6878 err = -EOPNOTSUPP;
bba95fef
JB
6879 goto out_err;
6880 }
6881
97990a06 6882 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 6883 err = -EOPNOTSUPP;
0448b5fc 6884 goto out_err;
eec60b03
JM
6885 }
6886
bba95fef 6887 while (1) {
1b8ec87a 6888 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 6889 next_hop, &pinfo);
bba95fef 6890 if (err == -ENOENT)
2ec600d6 6891 break;
bba95fef 6892 if (err)
3b85875a 6893 goto out_err;
2ec600d6 6894
15e47304 6895 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 6896 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 6897 wdev->netdev, dst, next_hop,
bba95fef
JB
6898 &pinfo) < 0)
6899 goto out;
2ec600d6 6900
bba95fef 6901 path_idx++;
2ec600d6 6902 }
2ec600d6 6903
bba95fef 6904 out:
97990a06 6905 cb->args[2] = path_idx;
bba95fef 6906 err = skb->len;
bba95fef 6907 out_err:
a05829a7 6908 wiphy_unlock(&rdev->wiphy);
bba95fef 6909 return err;
2ec600d6
LCC
6910}
6911
6912static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
6913{
4c476991 6914 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 6915 int err;
4c476991 6916 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6917 struct mpath_info pinfo;
6918 struct sk_buff *msg;
6919 u8 *dst = NULL;
6920 u8 next_hop[ETH_ALEN];
6921
6922 memset(&pinfo, 0, sizeof(pinfo));
6923
6924 if (!info->attrs[NL80211_ATTR_MAC])
6925 return -EINVAL;
6926
6927 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6928
4c476991
JB
6929 if (!rdev->ops->get_mpath)
6930 return -EOPNOTSUPP;
2ec600d6 6931
4c476991
JB
6932 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6933 return -EOPNOTSUPP;
eec60b03 6934
e35e4d28 6935 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 6936 if (err)
4c476991 6937 return err;
2ec600d6 6938
fd2120ca 6939 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 6940 if (!msg)
4c476991 6941 return -ENOMEM;
2ec600d6 6942
15e47304 6943 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
6944 dev, dst, next_hop, &pinfo) < 0) {
6945 nlmsg_free(msg);
6946 return -ENOBUFS;
6947 }
3b85875a 6948
4c476991 6949 return genlmsg_reply(msg, info);
2ec600d6
LCC
6950}
6951
6952static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
6953{
4c476991
JB
6954 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6955 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6956 u8 *dst = NULL;
6957 u8 *next_hop = NULL;
6958
6959 if (!info->attrs[NL80211_ATTR_MAC])
6960 return -EINVAL;
6961
6962 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
6963 return -EINVAL;
6964
6965 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6966 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
6967
4c476991
JB
6968 if (!rdev->ops->change_mpath)
6969 return -EOPNOTSUPP;
35a8efe1 6970
4c476991
JB
6971 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6972 return -EOPNOTSUPP;
2ec600d6 6973
e35e4d28 6974 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 6975}
4c476991 6976
2ec600d6
LCC
6977static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
6978{
4c476991
JB
6979 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6980 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6981 u8 *dst = NULL;
6982 u8 *next_hop = NULL;
6983
6984 if (!info->attrs[NL80211_ATTR_MAC])
6985 return -EINVAL;
6986
6987 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
6988 return -EINVAL;
6989
6990 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6991 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
6992
4c476991
JB
6993 if (!rdev->ops->add_mpath)
6994 return -EOPNOTSUPP;
35a8efe1 6995
4c476991
JB
6996 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6997 return -EOPNOTSUPP;
2ec600d6 6998
e35e4d28 6999 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
7000}
7001
7002static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
7003{
4c476991
JB
7004 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7005 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
7006 u8 *dst = NULL;
7007
7008 if (info->attrs[NL80211_ATTR_MAC])
7009 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7010
4c476991
JB
7011 if (!rdev->ops->del_mpath)
7012 return -EOPNOTSUPP;
3b85875a 7013
b501426c
MP
7014 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7015 return -EOPNOTSUPP;
7016
e35e4d28 7017 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
7018}
7019
66be7d2b
HR
7020static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
7021{
7022 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7023 int err;
7024 struct net_device *dev = info->user_ptr[1];
7025 struct mpath_info pinfo;
7026 struct sk_buff *msg;
7027 u8 *dst = NULL;
7028 u8 mpp[ETH_ALEN];
7029
7030 memset(&pinfo, 0, sizeof(pinfo));
7031
7032 if (!info->attrs[NL80211_ATTR_MAC])
7033 return -EINVAL;
7034
7035 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7036
7037 if (!rdev->ops->get_mpp)
7038 return -EOPNOTSUPP;
7039
7040 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7041 return -EOPNOTSUPP;
7042
7043 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
7044 if (err)
7045 return err;
7046
7047 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7048 if (!msg)
7049 return -ENOMEM;
7050
7051 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
7052 dev, dst, mpp, &pinfo) < 0) {
7053 nlmsg_free(msg);
7054 return -ENOBUFS;
7055 }
7056
7057 return genlmsg_reply(msg, info);
7058}
7059
7060static int nl80211_dump_mpp(struct sk_buff *skb,
7061 struct netlink_callback *cb)
7062{
7063 struct mpath_info pinfo;
7064 struct cfg80211_registered_device *rdev;
7065 struct wireless_dev *wdev;
7066 u8 dst[ETH_ALEN];
7067 u8 mpp[ETH_ALEN];
7068 int path_idx = cb->args[2];
7069 int err;
7070
5297c65c 7071 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
66be7d2b 7072 if (err)
a05829a7
JB
7073 return err;
7074 /* nl80211_prepare_wdev_dump acquired it in the successful case */
7075 __acquire(&rdev->wiphy.mtx);
66be7d2b
HR
7076
7077 if (!rdev->ops->dump_mpp) {
7078 err = -EOPNOTSUPP;
7079 goto out_err;
7080 }
7081
7082 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
7083 err = -EOPNOTSUPP;
7084 goto out_err;
7085 }
7086
7087 while (1) {
7088 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
7089 mpp, &pinfo);
7090 if (err == -ENOENT)
7091 break;
7092 if (err)
7093 goto out_err;
7094
7095 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
7096 cb->nlh->nlmsg_seq, NLM_F_MULTI,
7097 wdev->netdev, dst, mpp,
7098 &pinfo) < 0)
7099 goto out;
7100
7101 path_idx++;
7102 }
7103
7104 out:
7105 cb->args[2] = path_idx;
7106 err = skb->len;
7107 out_err:
a05829a7 7108 wiphy_unlock(&rdev->wiphy);
66be7d2b
HR
7109 return err;
7110}
7111
9f1ba906
JM
7112static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
7113{
4c476991
JB
7114 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7115 struct net_device *dev = info->user_ptr[1];
c56589ed 7116 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 7117 struct bss_parameters params;
c56589ed 7118 int err;
9f1ba906
JM
7119
7120 memset(&params, 0, sizeof(params));
7121 /* default to not changing parameters */
7122 params.use_cts_prot = -1;
7123 params.use_short_preamble = -1;
7124 params.use_short_slot_time = -1;
fd8aaaf3 7125 params.ap_isolate = -1;
50b12f59 7126 params.ht_opmode = -1;
53cabad7
JB
7127 params.p2p_ctwindow = -1;
7128 params.p2p_opp_ps = -1;
9f1ba906
JM
7129
7130 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
7131 params.use_cts_prot =
7132 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
7133 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
7134 params.use_short_preamble =
7135 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
7136 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
7137 params.use_short_slot_time =
7138 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
7139 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
7140 params.basic_rates =
7141 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7142 params.basic_rates_len =
7143 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7144 }
fd8aaaf3
FF
7145 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
7146 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
7147 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
7148 params.ht_opmode =
7149 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 7150
53cabad7
JB
7151 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
7152 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7153 return -EINVAL;
7154 params.p2p_ctwindow =
ab0d76f6 7155 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
7156 if (params.p2p_ctwindow != 0 &&
7157 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
7158 return -EINVAL;
7159 }
7160
7161 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
7162 u8 tmp;
7163
7164 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7165 return -EINVAL;
7166 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
7167 params.p2p_opp_ps = tmp;
7168 if (params.p2p_opp_ps &&
7169 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
7170 return -EINVAL;
7171 }
7172
4c476991
JB
7173 if (!rdev->ops->change_bss)
7174 return -EOPNOTSUPP;
9f1ba906 7175
074ac8df 7176 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
7177 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7178 return -EOPNOTSUPP;
3b85875a 7179
c56589ed
SW
7180 wdev_lock(wdev);
7181 err = rdev_change_bss(rdev, dev, &params);
7182 wdev_unlock(wdev);
7183
7184 return err;
9f1ba906
JM
7185}
7186
b2e1b302
LR
7187static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
7188{
b2e1b302 7189 char *data = NULL;
05050753 7190 bool is_indoor;
57b5ce07 7191 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
7192 u32 owner_nlportid;
7193
80778f18
LR
7194 /*
7195 * You should only get this when cfg80211 hasn't yet initialized
7196 * completely when built-in to the kernel right between the time
7197 * window between nl80211_init() and regulatory_init(), if that is
7198 * even possible.
7199 */
458f4f9e 7200 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 7201 return -EINPROGRESS;
80778f18 7202
57b5ce07
LR
7203 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
7204 user_reg_hint_type =
7205 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
7206 else
7207 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
7208
7209 switch (user_reg_hint_type) {
7210 case NL80211_USER_REG_HINT_USER:
7211 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
7212 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
7213 return -EINVAL;
7214
7215 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
7216 return regulatory_hint_user(data, user_reg_hint_type);
7217 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
7218 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
7219 owner_nlportid = info->snd_portid;
7220 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
7221 } else {
7222 owner_nlportid = 0;
7223 is_indoor = true;
7224 }
7225
7226 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
7227 default:
7228 return -EINVAL;
7229 }
b2e1b302
LR
7230}
7231
1ea4ff3e
JB
7232static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
7233{
7234 return reg_reload_regdb();
7235}
7236
24bdd9f4 7237static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 7238 struct genl_info *info)
93da9cc1 7239{
4c476991 7240 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 7241 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
7242 struct wireless_dev *wdev = dev->ieee80211_ptr;
7243 struct mesh_config cur_params;
7244 int err = 0;
93da9cc1 7245 void *hdr;
7246 struct nlattr *pinfoattr;
7247 struct sk_buff *msg;
7248
29cbe68c
JB
7249 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
7250 return -EOPNOTSUPP;
7251
24bdd9f4 7252 if (!rdev->ops->get_mesh_config)
4c476991 7253 return -EOPNOTSUPP;
f3f92586 7254
29cbe68c
JB
7255 wdev_lock(wdev);
7256 /* If not connected, get default parameters */
7257 if (!wdev->mesh_id_len)
7258 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
7259 else
e35e4d28 7260 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
7261 wdev_unlock(wdev);
7262
93da9cc1 7263 if (err)
4c476991 7264 return err;
93da9cc1 7265
7266 /* Draw up a netlink message to send back */
fd2120ca 7267 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
7268 if (!msg)
7269 return -ENOMEM;
15e47304 7270 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 7271 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 7272 if (!hdr)
efe1cf0c 7273 goto out;
ae0be8de 7274 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 7275 if (!pinfoattr)
7276 goto nla_put_failure;
9360ffd1
DM
7277 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
7278 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
7279 cur_params.dot11MeshRetryTimeout) ||
7280 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
7281 cur_params.dot11MeshConfirmTimeout) ||
7282 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
7283 cur_params.dot11MeshHoldingTimeout) ||
7284 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
7285 cur_params.dot11MeshMaxPeerLinks) ||
7286 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
7287 cur_params.dot11MeshMaxRetries) ||
7288 nla_put_u8(msg, NL80211_MESHCONF_TTL,
7289 cur_params.dot11MeshTTL) ||
7290 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
7291 cur_params.element_ttl) ||
7292 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
7293 cur_params.auto_open_plinks) ||
7eab0f64
JL
7294 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
7295 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
7296 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
7297 cur_params.dot11MeshHWMPmaxPREQretries) ||
7298 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
7299 cur_params.path_refresh_time) ||
7300 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
7301 cur_params.min_discovery_timeout) ||
7302 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
7303 cur_params.dot11MeshHWMPactivePathTimeout) ||
7304 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
7305 cur_params.dot11MeshHWMPpreqMinInterval) ||
7306 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
7307 cur_params.dot11MeshHWMPperrMinInterval) ||
7308 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
7309 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
7310 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
7311 cur_params.dot11MeshHWMPRootMode) ||
7312 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
7313 cur_params.dot11MeshHWMPRannInterval) ||
7314 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
7315 cur_params.dot11MeshGateAnnouncementProtocol) ||
7316 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
7317 cur_params.dot11MeshForwarding) ||
335d5349 7318 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
7319 cur_params.rssi_threshold) ||
7320 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
7321 cur_params.ht_opmode) ||
7322 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
7323 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
7324 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
7325 cur_params.dot11MeshHWMProotInterval) ||
7326 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
7327 cur_params.dot11MeshHWMPconfirmationInterval) ||
7328 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
7329 cur_params.power_mode) ||
7330 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
7331 cur_params.dot11MeshAwakeWindowDuration) ||
7332 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
01d66fbd
BC
7333 cur_params.plink_timeout) ||
7334 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
e3718a61
LL
7335 cur_params.dot11MeshConnectedToMeshGate) ||
7336 nla_put_u8(msg, NL80211_MESHCONF_NOLEARN,
184eebe6
MT
7337 cur_params.dot11MeshNolearn) ||
7338 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_AS,
7339 cur_params.dot11MeshConnectedToAuthServer))
9360ffd1 7340 goto nla_put_failure;
93da9cc1 7341 nla_nest_end(msg, pinfoattr);
7342 genlmsg_end(msg, hdr);
4c476991 7343 return genlmsg_reply(msg, info);
93da9cc1 7344
3b85875a 7345 nla_put_failure:
efe1cf0c 7346 out:
d080e275 7347 nlmsg_free(msg);
4c476991 7348 return -ENOBUFS;
93da9cc1 7349}
7350
ab0d76f6
JB
7351static const struct nla_policy
7352nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
7353 [NL80211_MESHCONF_RETRY_TIMEOUT] =
7354 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7355 [NL80211_MESHCONF_CONFIRM_TIMEOUT] =
7356 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7357 [NL80211_MESHCONF_HOLDING_TIMEOUT] =
7358 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7359 [NL80211_MESHCONF_MAX_PEER_LINKS] =
7360 NLA_POLICY_RANGE(NLA_U16, 0, 255),
7361 [NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
7362 [NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
7363 [NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
7364 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
7365 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
7366 NLA_POLICY_RANGE(NLA_U32, 1, 255),
93da9cc1 7367 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
7368 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
ab0d76f6 7369 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
93da9cc1 7370 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
7371 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
7372 NLA_POLICY_MIN(NLA_U16, 1),
7373 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
7374 NLA_POLICY_MIN(NLA_U16, 1),
7375 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
7376 NLA_POLICY_MIN(NLA_U16, 1),
7377 [NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
7378 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
7379 NLA_POLICY_MIN(NLA_U16, 1),
7380 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
7381 [NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
7382 [NL80211_MESHCONF_RSSI_THRESHOLD] =
7383 NLA_POLICY_RANGE(NLA_S32, -255, 0),
a4f606ea 7384 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6 7385 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
7386 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
7387 NLA_POLICY_MIN(NLA_U16, 1),
7388 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
7389 NLA_POLICY_MIN(NLA_U16, 1),
7390 [NL80211_MESHCONF_POWER_MODE] =
7391 NLA_POLICY_RANGE(NLA_U32,
7392 NL80211_MESH_POWER_ACTIVE,
7393 NL80211_MESH_POWER_MAX),
3b1c5a53 7394 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 7395 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
01d66fbd 7396 [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
e3718a61 7397 [NL80211_MESHCONF_NOLEARN] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
184eebe6 7398 [NL80211_MESHCONF_CONNECTED_TO_AS] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
93da9cc1 7399};
7400
c80d545d
JC
7401static const struct nla_policy
7402 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 7403 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
7404 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
7405 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 7406 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 7407 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 7408 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
3d7af878
JB
7409 [NL80211_MESH_SETUP_IE] =
7410 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
7411 IEEE80211_MAX_DATA_LEN),
b130e5ce 7412 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
7413};
7414
24bdd9f4 7415static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
7416 struct mesh_config *cfg,
7417 u32 *mask_out)
93da9cc1 7418{
93da9cc1 7419 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 7420 u32 mask = 0;
9757235f 7421 u16 ht_opmode;
93da9cc1 7422
ab0d76f6
JB
7423#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
7424do { \
7425 if (tb[attr]) { \
7426 cfg->param = fn(tb[attr]); \
7427 mask |= BIT((attr) - 1); \
7428 } \
ea54fba2 7429} while (0)
bd90fdcc 7430
24bdd9f4 7431 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 7432 return -EINVAL;
8cb08174 7433 if (nla_parse_nested_deprecated(tb, NL80211_MESHCONF_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy, info->extack))
93da9cc1 7434 return -EINVAL;
7435
93da9cc1 7436 /* This makes sure that there aren't more than 32 mesh config
7437 * parameters (otherwise our bitfield scheme would not work.) */
7438 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
7439
7440 /* Fill in the params struct */
ab0d76f6
JB
7441 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
7442 NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
7443 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
7444 NL80211_MESHCONF_CONFIRM_TIMEOUT,
7445 nla_get_u16);
7446 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
7447 NL80211_MESHCONF_HOLDING_TIMEOUT,
7448 nla_get_u16);
7449 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
7450 NL80211_MESHCONF_MAX_PEER_LINKS,
7451 nla_get_u16);
7452 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
7453 NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
7454 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
7455 NL80211_MESHCONF_TTL, nla_get_u8);
7456 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
7457 NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
7458 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
7459 NL80211_MESHCONF_AUTO_OPEN_PLINKS,
7460 nla_get_u8);
ea54fba2 7461 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
ab0d76f6 7462 mask,
a4f606ea 7463 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
ab0d76f6
JB
7464 nla_get_u32);
7465 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
7466 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
7467 nla_get_u8);
7468 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
7469 NL80211_MESHCONF_PATH_REFRESH_TIME,
7470 nla_get_u32);
7471 if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
7472 (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
7473 return -EINVAL;
7474 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
7475 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
7476 nla_get_u16);
ea54fba2 7477 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
ab0d76f6 7478 mask,
a4f606ea 7479 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
ab0d76f6
JB
7480 nla_get_u32);
7481 if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
7482 (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
7483 cfg->dot11MeshHWMPactivePathTimeout > 65535))
7484 return -EINVAL;
7485 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
ea54fba2 7486 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
ab0d76f6
JB
7487 nla_get_u16);
7488 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
ea54fba2 7489 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
ab0d76f6 7490 nla_get_u16);
93da9cc1 7491 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6 7492 dot11MeshHWMPnetDiameterTraversalTime, mask,
a4f606ea 7493 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
ab0d76f6
JB
7494 nla_get_u16);
7495 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
7496 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
7497 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
7498 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
7499 nla_get_u16);
7500 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
ea54fba2 7501 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
ab0d76f6
JB
7502 nla_get_u8);
7503 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
7504 NL80211_MESHCONF_FORWARDING, nla_get_u8);
7505 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
7506 NL80211_MESHCONF_RSSI_THRESHOLD,
7507 nla_get_s32);
01d66fbd
BC
7508 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
7509 NL80211_MESHCONF_CONNECTED_TO_GATE,
7510 nla_get_u8);
184eebe6
MT
7511 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToAuthServer, mask,
7512 NL80211_MESHCONF_CONNECTED_TO_AS,
7513 nla_get_u8);
9757235f
MH
7514 /*
7515 * Check HT operation mode based on
188f60ab 7516 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
9757235f
MH
7517 */
7518 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
7519 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
7520
7521 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
7522 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
7523 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
7524 return -EINVAL;
7525
188f60ab
BC
7526 /* NON_HT_STA bit is reserved, but some programs set it */
7527 ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
9757235f 7528
9757235f 7529 cfg->ht_opmode = ht_opmode;
fd551bac 7530 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
9757235f 7531 }
728b19e5 7532 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6
JB
7533 dot11MeshHWMPactivePathToRootTimeout, mask,
7534 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
7535 nla_get_u32);
7536 if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
7537 (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
7538 cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
7539 return -EINVAL;
7540 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
7541 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
7542 nla_get_u16);
7543 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
7544 mask,
728b19e5 7545 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
ab0d76f6
JB
7546 nla_get_u16);
7547 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
7548 NL80211_MESHCONF_POWER_MODE, nla_get_u32);
7549 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
7550 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
7551 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
7552 NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
e3718a61
LL
7553 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNolearn, mask,
7554 NL80211_MESHCONF_NOLEARN, nla_get_u8);
bd90fdcc
JB
7555 if (mask_out)
7556 *mask_out = mask;
c80d545d 7557
bd90fdcc
JB
7558 return 0;
7559
7560#undef FILL_IN_MESH_PARAM_IF_SET
7561}
7562
c80d545d
JC
7563static int nl80211_parse_mesh_setup(struct genl_info *info,
7564 struct mesh_setup *setup)
7565{
bb2798d4 7566 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
7567 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
7568
7569 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
7570 return -EINVAL;
8cb08174 7571 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
7572 return -EINVAL;
7573
d299a1f2
JC
7574 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
7575 setup->sync_method =
7576 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
7577 IEEE80211_SYNC_METHOD_VENDOR :
7578 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
7579
c80d545d
JC
7580 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
7581 setup->path_sel_proto =
7582 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
7583 IEEE80211_PATH_PROTOCOL_VENDOR :
7584 IEEE80211_PATH_PROTOCOL_HWMP;
7585
7586 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
7587 setup->path_metric =
7588 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
7589 IEEE80211_PATH_METRIC_VENDOR :
7590 IEEE80211_PATH_METRIC_AIRTIME;
7591
581a8b0f 7592 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 7593 struct nlattr *ieattr =
581a8b0f 7594 tb[NL80211_MESH_SETUP_IE];
581a8b0f
JC
7595 setup->ie = nla_data(ieattr);
7596 setup->ie_len = nla_len(ieattr);
c80d545d 7597 }
bb2798d4
TP
7598 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
7599 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
7600 return -EINVAL;
7601 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
7602 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
7603 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
7604 if (setup->is_secure)
7605 setup->user_mpm = true;
c80d545d 7606
6e16d90b
CT
7607 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
7608 if (!setup->user_mpm)
7609 return -EINVAL;
7610 setup->auth_id =
7611 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
7612 }
7613
c80d545d
JC
7614 return 0;
7615}
7616
24bdd9f4 7617static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 7618 struct genl_info *info)
bd90fdcc
JB
7619{
7620 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7621 struct net_device *dev = info->user_ptr[1];
29cbe68c 7622 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
7623 struct mesh_config cfg;
7624 u32 mask;
7625 int err;
7626
29cbe68c
JB
7627 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
7628 return -EOPNOTSUPP;
7629
24bdd9f4 7630 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
7631 return -EOPNOTSUPP;
7632
24bdd9f4 7633 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
7634 if (err)
7635 return err;
7636
29cbe68c
JB
7637 wdev_lock(wdev);
7638 if (!wdev->mesh_id_len)
7639 err = -ENOLINK;
7640
7641 if (!err)
e35e4d28 7642 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
7643
7644 wdev_unlock(wdev);
7645
7646 return err;
93da9cc1 7647}
7648
ad30ca2c
AN
7649static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
7650 struct sk_buff *msg)
f130347c 7651{
f130347c
LR
7652 struct nlattr *nl_reg_rules;
7653 unsigned int i;
f130347c 7654
458f4f9e
JB
7655 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
7656 (regdom->dfs_region &&
7657 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 7658 goto nla_put_failure;
458f4f9e 7659
ae0be8de 7660 nl_reg_rules = nla_nest_start_noflag(msg, NL80211_ATTR_REG_RULES);
f130347c 7661 if (!nl_reg_rules)
ad30ca2c 7662 goto nla_put_failure;
f130347c 7663
458f4f9e 7664 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
7665 struct nlattr *nl_reg_rule;
7666 const struct ieee80211_reg_rule *reg_rule;
7667 const struct ieee80211_freq_range *freq_range;
7668 const struct ieee80211_power_rule *power_rule;
97524820 7669 unsigned int max_bandwidth_khz;
f130347c 7670
458f4f9e 7671 reg_rule = &regdom->reg_rules[i];
f130347c
LR
7672 freq_range = &reg_rule->freq_range;
7673 power_rule = &reg_rule->power_rule;
7674
ae0be8de 7675 nl_reg_rule = nla_nest_start_noflag(msg, i);
f130347c 7676 if (!nl_reg_rule)
ad30ca2c 7677 goto nla_put_failure;
f130347c 7678
97524820
JD
7679 max_bandwidth_khz = freq_range->max_bandwidth_khz;
7680 if (!max_bandwidth_khz)
7681 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
7682 reg_rule);
7683
9360ffd1
DM
7684 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
7685 reg_rule->flags) ||
7686 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
7687 freq_range->start_freq_khz) ||
7688 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
7689 freq_range->end_freq_khz) ||
7690 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 7691 max_bandwidth_khz) ||
9360ffd1
DM
7692 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
7693 power_rule->max_antenna_gain) ||
7694 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
7695 power_rule->max_eirp) ||
7696 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
7697 reg_rule->dfs_cac_ms))
ad30ca2c 7698 goto nla_put_failure;
f130347c
LR
7699
7700 nla_nest_end(msg, nl_reg_rule);
7701 }
7702
7703 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
7704 return 0;
7705
7706nla_put_failure:
7707 return -EMSGSIZE;
7708}
7709
7710static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
7711{
7712 const struct ieee80211_regdomain *regdom = NULL;
7713 struct cfg80211_registered_device *rdev;
7714 struct wiphy *wiphy = NULL;
7715 struct sk_buff *msg;
7716 void *hdr;
7717
7718 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7719 if (!msg)
7720 return -ENOBUFS;
7721
7722 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7723 NL80211_CMD_GET_REG);
7724 if (!hdr)
7725 goto put_failure;
7726
a05829a7
JB
7727 rtnl_lock();
7728
ad30ca2c 7729 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
7730 bool self_managed;
7731
ad30ca2c
AN
7732 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
7733 if (IS_ERR(rdev)) {
7734 nlmsg_free(msg);
a05829a7 7735 rtnl_unlock();
ad30ca2c
AN
7736 return PTR_ERR(rdev);
7737 }
7738
7739 wiphy = &rdev->wiphy;
1bdd716c
AN
7740 self_managed = wiphy->regulatory_flags &
7741 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
7742 regdom = get_wiphy_regdom(wiphy);
7743
1bdd716c
AN
7744 /* a self-managed-reg device must have a private regdom */
7745 if (WARN_ON(!regdom && self_managed)) {
7746 nlmsg_free(msg);
a05829a7 7747 rtnl_unlock();
1bdd716c
AN
7748 return -EINVAL;
7749 }
7750
ad30ca2c
AN
7751 if (regdom &&
7752 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
7753 goto nla_put_failure;
7754 }
7755
7756 if (!wiphy && reg_last_request_cell_base() &&
7757 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
7758 NL80211_USER_REG_HINT_CELL_BASE))
7759 goto nla_put_failure;
7760
7761 rcu_read_lock();
7762
7763 if (!regdom)
7764 regdom = rcu_dereference(cfg80211_regdomain);
7765
7766 if (nl80211_put_regdom(regdom, msg))
7767 goto nla_put_failure_rcu;
7768
7769 rcu_read_unlock();
f130347c
LR
7770
7771 genlmsg_end(msg, hdr);
a05829a7 7772 rtnl_unlock();
5fe231e8 7773 return genlmsg_reply(msg, info);
f130347c 7774
458f4f9e
JB
7775nla_put_failure_rcu:
7776 rcu_read_unlock();
f130347c 7777nla_put_failure:
a05829a7 7778 rtnl_unlock();
efe1cf0c 7779put_failure:
d080e275 7780 nlmsg_free(msg);
5fe231e8 7781 return -EMSGSIZE;
f130347c
LR
7782}
7783
ad30ca2c
AN
7784static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
7785 u32 seq, int flags, struct wiphy *wiphy,
7786 const struct ieee80211_regdomain *regdom)
7787{
7788 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
7789 NL80211_CMD_GET_REG);
7790
7791 if (!hdr)
7792 return -1;
7793
0a833c29 7794 genl_dump_check_consistent(cb, hdr);
ad30ca2c
AN
7795
7796 if (nl80211_put_regdom(regdom, msg))
7797 goto nla_put_failure;
7798
7799 if (!wiphy && reg_last_request_cell_base() &&
7800 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
7801 NL80211_USER_REG_HINT_CELL_BASE))
7802 goto nla_put_failure;
7803
7804 if (wiphy &&
7805 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
7806 goto nla_put_failure;
7807
1bdd716c
AN
7808 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
7809 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
7810 goto nla_put_failure;
7811
053c095a
JB
7812 genlmsg_end(msg, hdr);
7813 return 0;
ad30ca2c
AN
7814
7815nla_put_failure:
7816 genlmsg_cancel(msg, hdr);
7817 return -EMSGSIZE;
7818}
7819
7820static int nl80211_get_reg_dump(struct sk_buff *skb,
7821 struct netlink_callback *cb)
7822{
7823 const struct ieee80211_regdomain *regdom = NULL;
7824 struct cfg80211_registered_device *rdev;
7825 int err, reg_idx, start = cb->args[2];
7826
7827 rtnl_lock();
7828
7829 if (cfg80211_regdomain && start == 0) {
7830 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
7831 NLM_F_MULTI, NULL,
7832 rtnl_dereference(cfg80211_regdomain));
7833 if (err < 0)
7834 goto out_err;
7835 }
7836
7837 /* the global regdom is idx 0 */
7838 reg_idx = 1;
7839 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
7840 regdom = get_wiphy_regdom(&rdev->wiphy);
7841 if (!regdom)
7842 continue;
7843
7844 if (++reg_idx <= start)
7845 continue;
7846
7847 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
7848 NLM_F_MULTI, &rdev->wiphy, regdom);
7849 if (err < 0) {
7850 reg_idx--;
7851 break;
7852 }
7853 }
7854
7855 cb->args[2] = reg_idx;
7856 err = skb->len;
7857out_err:
7858 rtnl_unlock();
7859 return err;
7860}
7861
b6863036
JB
7862#ifdef CONFIG_CFG80211_CRDA_SUPPORT
7863static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
7864 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
7865 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
7866 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
7867 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
7868 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
7869 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
7870 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
7871};
7872
7873static int parse_reg_rule(struct nlattr *tb[],
7874 struct ieee80211_reg_rule *reg_rule)
7875{
7876 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
7877 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
7878
7879 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
7880 return -EINVAL;
7881 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
7882 return -EINVAL;
7883 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
7884 return -EINVAL;
7885 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
7886 return -EINVAL;
7887 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
7888 return -EINVAL;
7889
7890 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
7891
7892 freq_range->start_freq_khz =
7893 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
7894 freq_range->end_freq_khz =
7895 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
7896 freq_range->max_bandwidth_khz =
7897 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
7898
7899 power_rule->max_eirp =
7900 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
7901
7902 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
7903 power_rule->max_antenna_gain =
7904 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
7905
7906 if (tb[NL80211_ATTR_DFS_CAC_TIME])
7907 reg_rule->dfs_cac_ms =
7908 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
7909
7910 return 0;
7911}
7912
b2e1b302
LR
7913static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
7914{
7915 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
7916 struct nlattr *nl_reg_rule;
ea372c54
JB
7917 char *alpha2;
7918 int rem_reg_rules, r;
391d132c 7919 u32 num_rules = 0, rule_idx = 0;
4c7d3982 7920 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 7921 struct ieee80211_regdomain *rd;
b2e1b302
LR
7922
7923 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
7924 return -EINVAL;
7925
7926 if (!info->attrs[NL80211_ATTR_REG_RULES])
7927 return -EINVAL;
7928
7929 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
7930
8b60b078
LR
7931 if (info->attrs[NL80211_ATTR_DFS_REGION])
7932 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
7933
b2e1b302 7934 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7935 rem_reg_rules) {
b2e1b302
LR
7936 num_rules++;
7937 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 7938 return -EINVAL;
b2e1b302
LR
7939 }
7940
a05829a7
JB
7941 rtnl_lock();
7942 if (!reg_is_valid_request(alpha2)) {
7943 r = -EINVAL;
7944 goto out;
7945 }
e438768f 7946
391d132c 7947 rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
a05829a7
JB
7948 if (!rd) {
7949 r = -ENOMEM;
7950 goto out;
7951 }
b2e1b302
LR
7952
7953 rd->n_reg_rules = num_rules;
7954 rd->alpha2[0] = alpha2[0];
7955 rd->alpha2[1] = alpha2[1];
7956
8b60b078
LR
7957 /*
7958 * Disable DFS master mode if the DFS region was
7959 * not supported or known on this kernel.
7960 */
7961 if (reg_supported_dfs_region(dfs_region))
7962 rd->dfs_region = dfs_region;
7963
b2e1b302 7964 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7965 rem_reg_rules) {
8cb08174
JB
7966 r = nla_parse_nested_deprecated(tb, NL80211_REG_RULE_ATTR_MAX,
7967 nl_reg_rule, reg_rule_policy,
7968 info->extack);
ae811e21
JB
7969 if (r)
7970 goto bad_reg;
b2e1b302
LR
7971 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
7972 if (r)
7973 goto bad_reg;
7974
7975 rule_idx++;
7976
d0e18f83
LR
7977 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
7978 r = -EINVAL;
b2e1b302 7979 goto bad_reg;
d0e18f83 7980 }
b2e1b302
LR
7981 }
7982
a05829a7 7983 r = set_regdom(rd, REGD_SOURCE_CRDA);
06627990 7984 /* set_regdom takes ownership of rd */
a05829a7 7985 rd = NULL;
d2372b31 7986 bad_reg:
b2e1b302 7987 kfree(rd);
a05829a7
JB
7988 out:
7989 rtnl_unlock();
d0e18f83 7990 return r;
b2e1b302 7991}
b6863036 7992#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 7993
83f5e2cf
JB
7994static int validate_scan_freqs(struct nlattr *freqs)
7995{
7996 struct nlattr *attr1, *attr2;
7997 int n_channels = 0, tmp1, tmp2;
7998
d7f13f74
SD
7999 nla_for_each_nested(attr1, freqs, tmp1)
8000 if (nla_len(attr1) != sizeof(u32))
8001 return 0;
8002
83f5e2cf
JB
8003 nla_for_each_nested(attr1, freqs, tmp1) {
8004 n_channels++;
8005 /*
8006 * Some hardware has a limited channel list for
8007 * scanning, and it is pretty much nonsensical
8008 * to scan for a channel twice, so disallow that
8009 * and don't require drivers to check that the
8010 * channel list they get isn't longer than what
8011 * they can scan, as long as they can scan all
8012 * the channels they registered at once.
8013 */
8014 nla_for_each_nested(attr2, freqs, tmp2)
8015 if (attr1 != attr2 &&
8016 nla_get_u32(attr1) == nla_get_u32(attr2))
8017 return 0;
8018 }
8019
8020 return n_channels;
8021}
8022
57fbcce3 8023static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 8024{
57fbcce3 8025 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
8026}
8027
8028static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
8029 struct cfg80211_bss_selection *bss_select)
8030{
8031 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
8032 struct nlattr *nest;
8033 int err;
8034 bool found = false;
8035 int i;
8036
8037 /* only process one nested attribute */
8038 nest = nla_data(nla);
8039 if (!nla_ok(nest, nla_len(nest)))
8040 return -EINVAL;
8041
8cb08174
JB
8042 err = nla_parse_nested_deprecated(attr, NL80211_BSS_SELECT_ATTR_MAX,
8043 nest, nl80211_bss_select_policy,
8044 NULL);
38de03d2
AS
8045 if (err)
8046 return err;
8047
8048 /* only one attribute may be given */
8049 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
8050 if (attr[i]) {
8051 if (found)
8052 return -EINVAL;
8053 found = true;
8054 }
8055 }
8056
8057 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
8058
8059 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
8060 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
8061
8062 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
8063 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
8064 bss_select->param.band_pref =
8065 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
8066 if (!is_band_valid(wiphy, bss_select->param.band_pref))
8067 return -EINVAL;
8068 }
8069
8070 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
8071 struct nl80211_bss_select_rssi_adjust *adj_param;
8072
8073 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
8074 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
8075 bss_select->param.adjust.band = adj_param->band;
8076 bss_select->param.adjust.delta = adj_param->delta;
8077 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
8078 return -EINVAL;
8079 }
8080
8081 /* user-space did not provide behaviour attribute */
8082 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
8083 return -EINVAL;
8084
8085 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
8086 return -EINVAL;
8087
8088 return 0;
8089}
8090
9bb7e0f2
JB
8091int nl80211_parse_random_mac(struct nlattr **attrs,
8092 u8 *mac_addr, u8 *mac_addr_mask)
ad2b26ab
JB
8093{
8094 int i;
8095
8096 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
8097 eth_zero_addr(mac_addr);
8098 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
8099 mac_addr[0] = 0x2;
8100 mac_addr_mask[0] = 0x3;
8101
8102 return 0;
8103 }
8104
8105 /* need both or none */
8106 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
8107 return -EINVAL;
8108
8109 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
8110 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
8111
8112 /* don't allow or configure an mcast address */
8113 if (!is_multicast_ether_addr(mac_addr_mask) ||
8114 is_multicast_ether_addr(mac_addr))
8115 return -EINVAL;
8116
8117 /*
8118 * allow users to pass a MAC address that has bits set outside
8119 * of the mask, but don't bother drivers with having to deal
8120 * with such bits
8121 */
8122 for (i = 0; i < ETH_ALEN; i++)
8123 mac_addr[i] &= mac_addr_mask[i];
8124
8125 return 0;
8126}
8127
34373d12
VT
8128static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
8129{
8130 ASSERT_WDEV_LOCK(wdev);
8131
8132 if (!cfg80211_beaconing_iface_active(wdev))
8133 return true;
8134
8135 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
8136 return true;
8137
8138 return regulatory_pre_cac_allowed(wdev->wiphy);
8139}
8140
db0a4ad8
JB
8141static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
8142 enum nl80211_ext_feature_index feat)
8143{
8144 if (!(flags & flag))
8145 return true;
8146 if (wiphy_ext_feature_isset(wiphy, feat))
8147 return true;
8148 return false;
8149}
8150
2d23d073
RZ
8151static int
8152nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
8153 void *request, struct nlattr **attrs,
8154 bool is_sched_scan)
8155{
8156 u8 *mac_addr, *mac_addr_mask;
8157 u32 *flags;
8158 enum nl80211_feature_flags randomness_flag;
8159
8160 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
8161 return 0;
8162
8163 if (is_sched_scan) {
8164 struct cfg80211_sched_scan_request *req = request;
8165
8166 randomness_flag = wdev ?
8167 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
8168 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
8169 flags = &req->flags;
8170 mac_addr = req->mac_addr;
8171 mac_addr_mask = req->mac_addr_mask;
8172 } else {
8173 struct cfg80211_scan_request *req = request;
8174
8175 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
8176 flags = &req->flags;
8177 mac_addr = req->mac_addr;
8178 mac_addr_mask = req->mac_addr_mask;
8179 }
8180
8181 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
8182
5037a009
SD
8183 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
8184 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
db0a4ad8
JB
8185 !nl80211_check_scan_feat(wiphy, *flags,
8186 NL80211_SCAN_FLAG_LOW_SPAN,
8187 NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
8188 !nl80211_check_scan_feat(wiphy, *flags,
8189 NL80211_SCAN_FLAG_LOW_POWER,
8190 NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
8191 !nl80211_check_scan_feat(wiphy, *flags,
8192 NL80211_SCAN_FLAG_HIGH_ACCURACY,
8193 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
8194 !nl80211_check_scan_feat(wiphy, *flags,
8195 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
8196 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
8197 !nl80211_check_scan_feat(wiphy, *flags,
8198 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
8199 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
8200 !nl80211_check_scan_feat(wiphy, *flags,
8201 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
8202 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
8203 !nl80211_check_scan_feat(wiphy, *flags,
8204 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
2e076f19
JB
8205 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
8206 !nl80211_check_scan_feat(wiphy, *flags,
8207 NL80211_SCAN_FLAG_RANDOM_SN,
8208 NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
8209 !nl80211_check_scan_feat(wiphy, *flags,
8210 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
8211 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
2d23d073
RZ
8212 return -EOPNOTSUPP;
8213
8214 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
8215 int err;
8216
8217 if (!(wiphy->features & randomness_flag) ||
8218 (wdev && wdev->current_bss))
8219 return -EOPNOTSUPP;
8220
8221 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
8222 if (err)
8223 return err;
8224 }
8225
2d23d073
RZ
8226 return 0;
8227}
8228
2a519311
JB
8229static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
8230{
4c476991 8231 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 8232 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 8233 struct cfg80211_scan_request *request;
2032f3b2
TP
8234 struct nlattr *scan_freqs = NULL;
8235 bool scan_freqs_khz = false;
2a519311
JB
8236 struct nlattr *attr;
8237 struct wiphy *wiphy;
83f5e2cf 8238 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 8239 size_t ie_len;
2a519311 8240
79c97e97 8241 wiphy = &rdev->wiphy;
2a519311 8242
cb3b7d87
AB
8243 if (wdev->iftype == NL80211_IFTYPE_NAN)
8244 return -EOPNOTSUPP;
8245
4c476991
JB
8246 if (!rdev->ops->scan)
8247 return -EOPNOTSUPP;
2a519311 8248
83286856
CJ
8249 if (rdev->scan_req || rdev->scan_msg)
8250 return -EBUSY;
2a519311 8251
2032f3b2
TP
8252 if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) {
8253 if (!wiphy_ext_feature_isset(wiphy,
8254 NL80211_EXT_FEATURE_SCAN_FREQ_KHZ))
8255 return -EOPNOTSUPP;
8256 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ];
8257 scan_freqs_khz = true;
8258 } else if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES])
8259 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
8260
8261 if (scan_freqs) {
8262 n_channels = validate_scan_freqs(scan_freqs);
83286856
CJ
8263 if (!n_channels)
8264 return -EINVAL;
2a519311 8265 } else {
bdfbec2d 8266 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
8267 }
8268
8269 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
8270 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
8271 n_ssids++;
8272
83286856
CJ
8273 if (n_ssids > wiphy->max_scan_ssids)
8274 return -EINVAL;
2a519311 8275
70692ad2
JM
8276 if (info->attrs[NL80211_ATTR_IE])
8277 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8278 else
8279 ie_len = 0;
8280
83286856
CJ
8281 if (ie_len > wiphy->max_scan_ie_len)
8282 return -EINVAL;
18a83659 8283
2a519311 8284 request = kzalloc(sizeof(*request)
a2cd43c5
LC
8285 + sizeof(*request->ssids) * n_ssids
8286 + sizeof(*request->channels) * n_channels
70692ad2 8287 + ie_len, GFP_KERNEL);
83286856
CJ
8288 if (!request)
8289 return -ENOMEM;
2a519311 8290
2a519311 8291 if (n_ssids)
5ba63533 8292 request->ssids = (void *)&request->channels[n_channels];
2a519311 8293 request->n_ssids = n_ssids;
70692ad2 8294 if (ie_len) {
13874e4b 8295 if (n_ssids)
70692ad2
JM
8296 request->ie = (void *)(request->ssids + n_ssids);
8297 else
8298 request->ie = (void *)(request->channels + n_channels);
8299 }
2a519311 8300
584991dc 8301 i = 0;
2032f3b2 8302 if (scan_freqs) {
2a519311 8303 /* user specified, bail out if channel not found */
2032f3b2 8304 nla_for_each_nested(attr, scan_freqs, tmp) {
584991dc 8305 struct ieee80211_channel *chan;
2032f3b2 8306 int freq = nla_get_u32(attr);
584991dc 8307
2032f3b2
TP
8308 if (!scan_freqs_khz)
8309 freq = MHZ_TO_KHZ(freq);
584991dc 8310
2032f3b2 8311 chan = ieee80211_get_channel_khz(wiphy, freq);
584991dc 8312 if (!chan) {
2a519311
JB
8313 err = -EINVAL;
8314 goto out_free;
8315 }
584991dc
JB
8316
8317 /* ignore disabled channels */
8318 if (chan->flags & IEEE80211_CHAN_DISABLED)
8319 continue;
8320
8321 request->channels[i] = chan;
2a519311
JB
8322 i++;
8323 }
8324 } else {
57fbcce3 8325 enum nl80211_band band;
34850ab2 8326
2a519311 8327 /* all channels */
57fbcce3 8328 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 8329 int j;
7a087e74 8330
2a519311
JB
8331 if (!wiphy->bands[band])
8332 continue;
8333 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
8334 struct ieee80211_channel *chan;
8335
8336 chan = &wiphy->bands[band]->channels[j];
8337
8338 if (chan->flags & IEEE80211_CHAN_DISABLED)
8339 continue;
8340
8341 request->channels[i] = chan;
2a519311
JB
8342 i++;
8343 }
8344 }
8345 }
8346
584991dc
JB
8347 if (!i) {
8348 err = -EINVAL;
8349 goto out_free;
8350 }
8351
8352 request->n_channels = i;
8353
34373d12
VT
8354 wdev_lock(wdev);
8355 if (!cfg80211_off_channel_oper_allowed(wdev)) {
8356 struct ieee80211_channel *chan;
8357
8358 if (request->n_channels != 1) {
8359 wdev_unlock(wdev);
8360 err = -EBUSY;
8361 goto out_free;
8362 }
8363
8364 chan = request->channels[0];
8365 if (chan->center_freq != wdev->chandef.chan->center_freq) {
8366 wdev_unlock(wdev);
8367 err = -EBUSY;
8368 goto out_free;
8369 }
8370 }
8371 wdev_unlock(wdev);
8372
2a519311 8373 i = 0;
13874e4b 8374 if (n_ssids) {
2a519311 8375 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 8376 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
8377 err = -EINVAL;
8378 goto out_free;
8379 }
57a27e1d 8380 request->ssids[i].ssid_len = nla_len(attr);
2a519311 8381 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
8382 i++;
8383 }
8384 }
8385
70692ad2
JM
8386 if (info->attrs[NL80211_ATTR_IE]) {
8387 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
8388 memcpy((void *)request->ie,
8389 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
8390 request->ie_len);
8391 }
8392
57fbcce3 8393 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
8394 if (wiphy->bands[i])
8395 request->rates[i] =
8396 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
8397
8398 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
8399 nla_for_each_nested(attr,
8400 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
8401 tmp) {
57fbcce3 8402 enum nl80211_band band = nla_type(attr);
34850ab2 8403
57fbcce3 8404 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
8405 err = -EINVAL;
8406 goto out_free;
8407 }
1b09cd82
FF
8408
8409 if (!wiphy->bands[band])
8410 continue;
8411
34850ab2
JB
8412 err = ieee80211_get_ratemask(wiphy->bands[band],
8413 nla_data(attr),
8414 nla_len(attr),
8415 &request->rates[band]);
8416 if (err)
8417 goto out_free;
8418 }
8419 }
8420
1d76250b 8421 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
1d76250b
AS
8422 request->duration =
8423 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
8424 request->duration_mandatory =
8425 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
8426 }
8427
2d23d073
RZ
8428 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
8429 false);
8430 if (err)
8431 goto out_free;
ed473771 8432
e9f935e3
RM
8433 request->no_cck =
8434 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
8435
2fa436b3
VK
8436 /* Initial implementation used NL80211_ATTR_MAC to set the specific
8437 * BSSID to scan for. This was problematic because that same attribute
8438 * was already used for another purpose (local random MAC address). The
8439 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
8440 * compatibility with older userspace components, also use the
8441 * NL80211_ATTR_MAC value here if it can be determined to be used for
8442 * the specific BSSID use case instead of the random MAC address
8443 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
8444 */
8445 if (info->attrs[NL80211_ATTR_BSSID])
8446 memcpy(request->bssid,
8447 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
8448 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
8449 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
8450 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
8451 ETH_ALEN);
8452 else
8453 eth_broadcast_addr(request->bssid);
8454
fd014284 8455 request->wdev = wdev;
79c97e97 8456 request->wiphy = &rdev->wiphy;
15d6030b 8457 request->scan_start = jiffies;
2a519311 8458
79c97e97 8459 rdev->scan_req = request;
c8cb5b85 8460 err = cfg80211_scan(rdev);
2a519311 8461
504776be
CJ
8462 if (err)
8463 goto out_free;
8464
8465 nl80211_send_scan_start(rdev, wdev);
8466 if (wdev->netdev)
8467 dev_hold(wdev->netdev);
8468
8469 return 0;
8470
2a519311 8471 out_free:
504776be
CJ
8472 rdev->scan_req = NULL;
8473 kfree(request);
3b85875a 8474
2a519311
JB
8475 return err;
8476}
8477
91d3ab46
VK
8478static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
8479{
8480 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8481 struct wireless_dev *wdev = info->user_ptr[1];
8482
8483 if (!rdev->ops->abort_scan)
8484 return -EOPNOTSUPP;
8485
8486 if (rdev->scan_msg)
8487 return 0;
8488
8489 if (!rdev->scan_req)
8490 return -ENOENT;
8491
8492 rdev_abort_scan(rdev, wdev);
8493 return 0;
8494}
8495
3b06d277
AS
8496static int
8497nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
8498 struct cfg80211_sched_scan_request *request,
8499 struct nlattr **attrs)
8500{
8501 int tmp, err, i = 0;
8502 struct nlattr *attr;
8503
8504 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
8505 u32 interval;
8506
8507 /*
8508 * If scan plans are not specified,
5a88de53 8509 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
8510 * case one scan plan will be set with the specified scan
8511 * interval and infinite number of iterations.
8512 */
3b06d277
AS
8513 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
8514 if (!interval)
8515 return -EINVAL;
8516
8517 request->scan_plans[0].interval =
8518 DIV_ROUND_UP(interval, MSEC_PER_SEC);
8519 if (!request->scan_plans[0].interval)
8520 return -EINVAL;
8521
8522 if (request->scan_plans[0].interval >
8523 wiphy->max_sched_scan_plan_interval)
8524 request->scan_plans[0].interval =
8525 wiphy->max_sched_scan_plan_interval;
8526
8527 return 0;
8528 }
8529
8530 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
8531 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
8532
8533 if (WARN_ON(i >= n_plans))
8534 return -EINVAL;
8535
8cb08174
JB
8536 err = nla_parse_nested_deprecated(plan,
8537 NL80211_SCHED_SCAN_PLAN_MAX,
8538 attr, nl80211_plan_policy,
8539 NULL);
3b06d277
AS
8540 if (err)
8541 return err;
8542
8543 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
8544 return -EINVAL;
8545
8546 request->scan_plans[i].interval =
8547 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
8548 if (!request->scan_plans[i].interval ||
8549 request->scan_plans[i].interval >
8550 wiphy->max_sched_scan_plan_interval)
8551 return -EINVAL;
8552
8553 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
8554 request->scan_plans[i].iterations =
8555 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
8556 if (!request->scan_plans[i].iterations ||
8557 (request->scan_plans[i].iterations >
8558 wiphy->max_sched_scan_plan_iterations))
8559 return -EINVAL;
8560 } else if (i < n_plans - 1) {
8561 /*
8562 * All scan plans but the last one must specify
8563 * a finite number of iterations
8564 */
8565 return -EINVAL;
8566 }
8567
8568 i++;
8569 }
8570
8571 /*
8572 * The last scan plan must not specify the number of
8573 * iterations, it is supposed to run infinitely
8574 */
8575 if (request->scan_plans[n_plans - 1].iterations)
8576 return -EINVAL;
8577
8578 return 0;
8579}
8580
1e1b11b6 8581static int
8582nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
8583 struct cfg80211_match_set *match_sets,
8584 struct nlattr *tb_band_rssi,
8585 s32 rssi_thold)
8586{
8587 struct nlattr *attr;
8588 int i, tmp, ret = 0;
8589
8590 if (!wiphy_ext_feature_isset(wiphy,
8591 NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
8592 if (tb_band_rssi)
8593 ret = -EOPNOTSUPP;
8594 else
8595 for (i = 0; i < NUM_NL80211_BANDS; i++)
8596 match_sets->per_band_rssi_thold[i] =
8597 NL80211_SCAN_RSSI_THOLD_OFF;
8598 return ret;
8599 }
8600
8601 for (i = 0; i < NUM_NL80211_BANDS; i++)
8602 match_sets->per_band_rssi_thold[i] = rssi_thold;
8603
8604 nla_for_each_nested(attr, tb_band_rssi, tmp) {
8605 enum nl80211_band band = nla_type(attr);
8606
8607 if (band < 0 || band >= NUM_NL80211_BANDS)
8608 return -EINVAL;
8609
8610 match_sets->per_band_rssi_thold[band] = nla_get_s32(attr);
8611 }
8612
8613 return 0;
8614}
8615
256da02d 8616static struct cfg80211_sched_scan_request *
ad2b26ab 8617nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
aad1e812 8618 struct nlattr **attrs, int max_match_sets)
807f8a8c
LC
8619{
8620 struct cfg80211_sched_scan_request *request;
807f8a8c 8621 struct nlattr *attr;
3b06d277 8622 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 8623 enum nl80211_band band;
807f8a8c 8624 size_t ie_len;
a1f1c21c 8625 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 8626 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 8627
256da02d 8628 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 8629 n_channels = validate_scan_freqs(
256da02d 8630 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 8631 if (!n_channels)
256da02d 8632 return ERR_PTR(-EINVAL);
807f8a8c 8633 } else {
bdfbec2d 8634 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
8635 }
8636
256da02d
LC
8637 if (attrs[NL80211_ATTR_SCAN_SSIDS])
8638 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
8639 tmp)
8640 n_ssids++;
8641
93b6aa69 8642 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 8643 return ERR_PTR(-EINVAL);
807f8a8c 8644
ea73cbce
JB
8645 /*
8646 * First, count the number of 'real' matchsets. Due to an issue with
8647 * the old implementation, matchsets containing only the RSSI attribute
8648 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
8649 * RSSI for all matchsets, rather than their own matchset for reporting
8650 * all APs with a strong RSSI. This is needed to be compatible with
8651 * older userspace that treated a matchset with only the RSSI as the
8652 * global RSSI for all other matchsets - if there are other matchsets.
8653 */
256da02d 8654 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 8655 nla_for_each_nested(attr,
256da02d 8656 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
8657 tmp) {
8658 struct nlattr *rssi;
8659
8cb08174
JB
8660 err = nla_parse_nested_deprecated(tb,
8661 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
8662 attr,
8663 nl80211_match_policy,
8664 NULL);
ea73cbce 8665 if (err)
256da02d 8666 return ERR_PTR(err);
3007e352
AVS
8667
8668 /* SSID and BSSID are mutually exclusive */
8669 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
8670 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
8671 return ERR_PTR(-EINVAL);
8672
ea73cbce 8673 /* add other standalone attributes here */
3007e352
AVS
8674 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
8675 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
ea73cbce
JB
8676 n_match_sets++;
8677 continue;
8678 }
8679 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
8680 if (rssi)
8681 default_match_rssi = nla_get_s32(rssi);
8682 }
8683 }
8684
8685 /* However, if there's no other matchset, add the RSSI one */
8686 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
8687 n_match_sets = 1;
a1f1c21c 8688
aad1e812 8689 if (n_match_sets > max_match_sets)
256da02d 8690 return ERR_PTR(-EINVAL);
a1f1c21c 8691
256da02d
LC
8692 if (attrs[NL80211_ATTR_IE])
8693 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
8694 else
8695 ie_len = 0;
8696
5a865bad 8697 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 8698 return ERR_PTR(-EINVAL);
c10841ca 8699
3b06d277
AS
8700 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
8701 /*
8702 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
8703 * each scan plan already specifies its own interval
8704 */
8705 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
8706 return ERR_PTR(-EINVAL);
8707
8708 nla_for_each_nested(attr,
8709 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
8710 n_plans++;
8711 } else {
8712 /*
8713 * The scan interval attribute is kept for backward
8714 * compatibility. If no scan plans are specified and sched scan
8715 * interval is specified, one scan plan will be set with this
8716 * scan interval and infinite number of iterations.
8717 */
8718 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
8719 return ERR_PTR(-EINVAL);
8720
8721 n_plans = 1;
8722 }
8723
8724 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
8725 return ERR_PTR(-EINVAL);
8726
bf95ecdb 8727 if (!wiphy_ext_feature_isset(
8728 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
8729 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
8730 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
8731 return ERR_PTR(-EINVAL);
8732
807f8a8c 8733 request = kzalloc(sizeof(*request)
a2cd43c5 8734 + sizeof(*request->ssids) * n_ssids
a1f1c21c 8735 + sizeof(*request->match_sets) * n_match_sets
3b06d277 8736 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 8737 + sizeof(*request->channels) * n_channels
807f8a8c 8738 + ie_len, GFP_KERNEL);
256da02d
LC
8739 if (!request)
8740 return ERR_PTR(-ENOMEM);
807f8a8c
LC
8741
8742 if (n_ssids)
8743 request->ssids = (void *)&request->channels[n_channels];
8744 request->n_ssids = n_ssids;
8745 if (ie_len) {
13874e4b 8746 if (n_ssids)
807f8a8c
LC
8747 request->ie = (void *)(request->ssids + n_ssids);
8748 else
8749 request->ie = (void *)(request->channels + n_channels);
8750 }
8751
a1f1c21c
LC
8752 if (n_match_sets) {
8753 if (request->ie)
8754 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 8755 else if (n_ssids)
a1f1c21c
LC
8756 request->match_sets =
8757 (void *)(request->ssids + n_ssids);
8758 else
8759 request->match_sets =
8760 (void *)(request->channels + n_channels);
8761 }
8762 request->n_match_sets = n_match_sets;
8763
3b06d277
AS
8764 if (n_match_sets)
8765 request->scan_plans = (void *)(request->match_sets +
8766 n_match_sets);
8767 else if (request->ie)
8768 request->scan_plans = (void *)(request->ie + ie_len);
8769 else if (n_ssids)
8770 request->scan_plans = (void *)(request->ssids + n_ssids);
8771 else
8772 request->scan_plans = (void *)(request->channels + n_channels);
8773
8774 request->n_scan_plans = n_plans;
8775
807f8a8c 8776 i = 0;
256da02d 8777 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
8778 /* user specified, bail out if channel not found */
8779 nla_for_each_nested(attr,
256da02d 8780 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
8781 tmp) {
8782 struct ieee80211_channel *chan;
8783
8784 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
8785
8786 if (!chan) {
8787 err = -EINVAL;
8788 goto out_free;
8789 }
8790
8791 /* ignore disabled channels */
8792 if (chan->flags & IEEE80211_CHAN_DISABLED)
8793 continue;
8794
8795 request->channels[i] = chan;
8796 i++;
8797 }
8798 } else {
8799 /* all channels */
57fbcce3 8800 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 8801 int j;
7a087e74 8802
807f8a8c
LC
8803 if (!wiphy->bands[band])
8804 continue;
8805 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
8806 struct ieee80211_channel *chan;
8807
8808 chan = &wiphy->bands[band]->channels[j];
8809
8810 if (chan->flags & IEEE80211_CHAN_DISABLED)
8811 continue;
8812
8813 request->channels[i] = chan;
8814 i++;
8815 }
8816 }
8817 }
8818
8819 if (!i) {
8820 err = -EINVAL;
8821 goto out_free;
8822 }
8823
8824 request->n_channels = i;
8825
8826 i = 0;
13874e4b 8827 if (n_ssids) {
256da02d 8828 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 8829 tmp) {
57a27e1d 8830 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
8831 err = -EINVAL;
8832 goto out_free;
8833 }
57a27e1d 8834 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
8835 memcpy(request->ssids[i].ssid, nla_data(attr),
8836 nla_len(attr));
807f8a8c
LC
8837 i++;
8838 }
8839 }
8840
a1f1c21c 8841 i = 0;
256da02d 8842 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 8843 nla_for_each_nested(attr,
256da02d 8844 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 8845 tmp) {
3007e352 8846 struct nlattr *ssid, *bssid, *rssi;
a1f1c21c 8847
8cb08174
JB
8848 err = nla_parse_nested_deprecated(tb,
8849 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
8850 attr,
8851 nl80211_match_policy,
8852 NULL);
ae811e21
JB
8853 if (err)
8854 goto out_free;
4a4ab0d7 8855 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
3007e352 8856 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
d39f3b4f
JB
8857
8858 if (!ssid && !bssid) {
8859 i++;
8860 continue;
8861 }
8862
8863 if (WARN_ON(i >= n_match_sets)) {
8864 /* this indicates a programming error,
8865 * the loop above should have verified
8866 * things properly
8867 */
8868 err = -EINVAL;
8869 goto out_free;
8870 }
8871
8872 if (ssid) {
d39f3b4f
JB
8873 memcpy(request->match_sets[i].ssid.ssid,
8874 nla_data(ssid), nla_len(ssid));
8875 request->match_sets[i].ssid.ssid_len =
8876 nla_len(ssid);
8877 }
cb9abd48 8878 if (bssid)
d39f3b4f
JB
8879 memcpy(request->match_sets[i].bssid,
8880 nla_data(bssid), ETH_ALEN);
3007e352 8881
d39f3b4f
JB
8882 /* special attribute - old implementation w/a */
8883 request->match_sets[i].rssi_thold = default_match_rssi;
8884 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
8885 if (rssi)
ea73cbce 8886 request->match_sets[i].rssi_thold =
d39f3b4f 8887 nla_get_s32(rssi);
1e1b11b6 8888
8889 /* Parse per band RSSI attribute */
8890 err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
8891 &request->match_sets[i],
8892 tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
8893 request->match_sets[i].rssi_thold);
8894 if (err)
8895 goto out_free;
8896
a1f1c21c
LC
8897 i++;
8898 }
ea73cbce
JB
8899
8900 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 8901 if (i == 0 && n_match_sets)
ea73cbce
JB
8902 request->match_sets[0].rssi_thold = default_match_rssi;
8903
8904 request->min_rssi_thold = INT_MAX;
8905 for (i = 0; i < n_match_sets; i++)
8906 request->min_rssi_thold =
8907 min(request->match_sets[i].rssi_thold,
8908 request->min_rssi_thold);
8909 } else {
8910 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
8911 }
8912
9900e484
JB
8913 if (ie_len) {
8914 request->ie_len = ie_len;
807f8a8c 8915 memcpy((void *)request->ie,
256da02d 8916 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
8917 request->ie_len);
8918 }
8919
2d23d073
RZ
8920 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
8921 if (err)
8922 goto out_free;
ed473771 8923
9c748934
LC
8924 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
8925 request->delay =
8926 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
8927
bf95ecdb 8928 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
8929 request->relative_rssi = nla_get_s8(
8930 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
8931 request->relative_rssi_set = true;
8932 }
8933
8934 if (request->relative_rssi_set &&
8935 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
8936 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
8937
8938 rssi_adjust = nla_data(
8939 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
8940 request->rssi_adjust.band = rssi_adjust->band;
8941 request->rssi_adjust.delta = rssi_adjust->delta;
8942 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
8943 err = -EINVAL;
8944 goto out_free;
8945 }
8946 }
8947
3b06d277
AS
8948 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
8949 if (err)
8950 goto out_free;
8951
15d6030b 8952 request->scan_start = jiffies;
807f8a8c 8953
256da02d 8954 return request;
807f8a8c
LC
8955
8956out_free:
8957 kfree(request);
256da02d
LC
8958 return ERR_PTR(err);
8959}
8960
8961static int nl80211_start_sched_scan(struct sk_buff *skb,
8962 struct genl_info *info)
8963{
8964 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8965 struct net_device *dev = info->user_ptr[1];
ad2b26ab 8966 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 8967 struct cfg80211_sched_scan_request *sched_scan_req;
ca986ad9 8968 bool want_multi;
256da02d
LC
8969 int err;
8970
ca986ad9 8971 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
256da02d
LC
8972 return -EOPNOTSUPP;
8973
ca986ad9
AVS
8974 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
8975 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
8976 if (err)
8977 return err;
256da02d 8978
31a60ed1 8979 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
aad1e812
AVS
8980 info->attrs,
8981 rdev->wiphy.max_match_sets);
31a60ed1
JR
8982
8983 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
8984 if (err)
8985 goto out_err;
8986
ca986ad9
AVS
8987 /* leave request id zero for legacy request
8988 * or if driver does not support multi-scheduled scan
8989 */
2fd351a8
DK
8990 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1)
8991 sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
ca986ad9 8992
31a60ed1 8993 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
8994 if (err)
8995 goto out_free;
8996
31a60ed1
JR
8997 sched_scan_req->dev = dev;
8998 sched_scan_req->wiphy = &rdev->wiphy;
8999
93a1e86c
JR
9000 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
9001 sched_scan_req->owner_nlportid = info->snd_portid;
9002
ca986ad9 9003 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
256da02d 9004
96b08fd6 9005 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
256da02d
LC
9006 return 0;
9007
9008out_free:
31a60ed1 9009 kfree(sched_scan_req);
256da02d 9010out_err:
807f8a8c
LC
9011 return err;
9012}
9013
9014static int nl80211_stop_sched_scan(struct sk_buff *skb,
9015 struct genl_info *info)
9016{
ca986ad9 9017 struct cfg80211_sched_scan_request *req;
807f8a8c 9018 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ca986ad9 9019 u64 cookie;
807f8a8c 9020
ca986ad9 9021 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
807f8a8c
LC
9022 return -EOPNOTSUPP;
9023
ca986ad9
AVS
9024 if (info->attrs[NL80211_ATTR_COOKIE]) {
9025 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9026 return __cfg80211_stop_sched_scan(rdev, cookie, false);
9027 }
9028
9029 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
9030 struct cfg80211_sched_scan_request,
9031 list);
9032 if (!req || req->reqid ||
9033 (req->owner_nlportid &&
9034 req->owner_nlportid != info->snd_portid))
9035 return -ENOENT;
9036
9037 return cfg80211_stop_sched_scan_req(rdev, req, false);
807f8a8c
LC
9038}
9039
04f39047
SW
9040static int nl80211_start_radar_detection(struct sk_buff *skb,
9041 struct genl_info *info)
9042{
9043 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9044 struct net_device *dev = info->user_ptr[1];
9045 struct wireless_dev *wdev = dev->ieee80211_ptr;
13cf6dec 9046 struct wiphy *wiphy = wdev->wiphy;
04f39047 9047 struct cfg80211_chan_def chandef;
55f7435c 9048 enum nl80211_dfs_regions dfs_region;
31559f35 9049 unsigned int cac_time_ms;
04f39047
SW
9050 int err;
9051
13cf6dec 9052 dfs_region = reg_get_dfs_region(wiphy);
55f7435c
LR
9053 if (dfs_region == NL80211_DFS_UNSET)
9054 return -EINVAL;
9055
04f39047
SW
9056 err = nl80211_parse_chandef(rdev, info, &chandef);
9057 if (err)
9058 return err;
9059
ff311bc1
SW
9060 if (netif_carrier_ok(dev))
9061 return -EBUSY;
9062
04f39047
SW
9063 if (wdev->cac_started)
9064 return -EBUSY;
9065
13cf6dec 9066 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
04f39047
SW
9067 if (err < 0)
9068 return err;
9069
9070 if (err == 0)
9071 return -EINVAL;
9072
13cf6dec 9073 if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
04f39047
SW
9074 return -EINVAL;
9075
13cf6dec
DL
9076 /* CAC start is offloaded to HW and can't be started manually */
9077 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
9078 return -EOPNOTSUPP;
9079
04f39047
SW
9080 if (!rdev->ops->start_radar_detection)
9081 return -EOPNOTSUPP;
9082
31559f35
JD
9083 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
9084 if (WARN_ON(!cac_time_ms))
9085 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
9086
a1056b1b 9087 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 9088 if (!err) {
9e0e2961 9089 wdev->chandef = chandef;
04f39047
SW
9090 wdev->cac_started = true;
9091 wdev->cac_start_time = jiffies;
31559f35 9092 wdev->cac_time_ms = cac_time_ms;
04f39047 9093 }
04f39047
SW
9094 return err;
9095}
9096
30c63115
S
9097static int nl80211_notify_radar_detection(struct sk_buff *skb,
9098 struct genl_info *info)
9099{
9100 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9101 struct net_device *dev = info->user_ptr[1];
9102 struct wireless_dev *wdev = dev->ieee80211_ptr;
9103 struct wiphy *wiphy = wdev->wiphy;
9104 struct cfg80211_chan_def chandef;
9105 enum nl80211_dfs_regions dfs_region;
9106 int err;
9107
9108 dfs_region = reg_get_dfs_region(wiphy);
9109 if (dfs_region == NL80211_DFS_UNSET) {
9110 GENL_SET_ERR_MSG(info,
9111 "DFS Region is not set. Unexpected Radar indication");
9112 return -EINVAL;
9113 }
9114
9115 err = nl80211_parse_chandef(rdev, info, &chandef);
9116 if (err) {
9117 GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
9118 return err;
9119 }
9120
9121 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
9122 if (err < 0) {
9123 GENL_SET_ERR_MSG(info, "chandef is invalid");
9124 return err;
9125 }
9126
9127 if (err == 0) {
9128 GENL_SET_ERR_MSG(info,
9129 "Unexpected Radar indication for chandef/iftype");
9130 return -EINVAL;
9131 }
9132
9133 /* Do not process this notification if radar is already detected
9134 * by kernel on this channel, and return success.
9135 */
9136 if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
9137 return 0;
9138
9139 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
9140
9141 cfg80211_sched_dfs_chan_update(rdev);
9142
a680fe46 9143 rdev->radar_chandef = chandef;
30c63115
S
9144
9145 /* Propagate this notification to other radios as well */
9146 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
9147
9148 return 0;
9149}
9150
16ef1fe2
SW
9151static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
9152{
9153 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9154 struct net_device *dev = info->user_ptr[1];
9155 struct wireless_dev *wdev = dev->ieee80211_ptr;
9156 struct cfg80211_csa_settings params;
a05829a7 9157 struct nlattr **csa_attrs = NULL;
16ef1fe2 9158 int err;
ee4bc9e7 9159 bool need_new_beacon = false;
8d9de16f 9160 bool need_handle_dfs_flag = true;
9a774c78 9161 int len, i;
252e07ca 9162 u32 cs_count;
16ef1fe2
SW
9163
9164 if (!rdev->ops->channel_switch ||
9165 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
9166 return -EOPNOTSUPP;
9167
ee4bc9e7
SW
9168 switch (dev->ieee80211_ptr->iftype) {
9169 case NL80211_IFTYPE_AP:
9170 case NL80211_IFTYPE_P2P_GO:
9171 need_new_beacon = true;
8d9de16f
BB
9172 /* For all modes except AP the handle_dfs flag needs to be
9173 * supplied to tell the kernel that userspace will handle radar
9174 * events when they happen. Otherwise a switch to a channel
9175 * requiring DFS will be rejected.
9176 */
9177 need_handle_dfs_flag = false;
ee4bc9e7
SW
9178
9179 /* useless if AP is not running */
9180 if (!wdev->beacon_interval)
1ff79dfa 9181 return -ENOTCONN;
ee4bc9e7
SW
9182 break;
9183 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
9184 if (!wdev->ssid_len)
9185 return -ENOTCONN;
9186 break;
c6da674a 9187 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
9188 if (!wdev->mesh_id_len)
9189 return -ENOTCONN;
ee4bc9e7
SW
9190 break;
9191 default:
16ef1fe2 9192 return -EOPNOTSUPP;
ee4bc9e7 9193 }
16ef1fe2
SW
9194
9195 memset(&params, 0, sizeof(params));
c177db2d 9196 params.beacon_csa.ftm_responder = -1;
16ef1fe2
SW
9197
9198 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
9199 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
9200 return -EINVAL;
9201
9202 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 9203 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
9204 return -EINVAL;
9205
252e07ca
LC
9206 /* Even though the attribute is u32, the specification says
9207 * u8, so let's make sure we don't overflow.
9208 */
9209 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
9210 if (cs_count > 255)
9211 return -EINVAL;
9212
9213 params.count = cs_count;
16ef1fe2 9214
ee4bc9e7
SW
9215 if (!need_new_beacon)
9216 goto skip_beacons;
9217
81e54d08 9218 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
16ef1fe2
SW
9219 if (err)
9220 return err;
9221
a05829a7
JB
9222 csa_attrs = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*csa_attrs),
9223 GFP_KERNEL);
9224 if (!csa_attrs)
9225 return -ENOMEM;
9226
8cb08174
JB
9227 err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
9228 info->attrs[NL80211_ATTR_CSA_IES],
9229 nl80211_policy, info->extack);
16ef1fe2 9230 if (err)
a05829a7 9231 goto free;
16ef1fe2 9232
81e54d08 9233 err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
16ef1fe2 9234 if (err)
a05829a7 9235 goto free;
16ef1fe2 9236
a05829a7
JB
9237 if (!csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
9238 err = -EINVAL;
9239 goto free;
9240 }
16ef1fe2 9241
00c207ed 9242 len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
a05829a7
JB
9243 if (!len || (len % sizeof(u16))) {
9244 err = -EINVAL;
9245 goto free;
9246 }
16ef1fe2 9247
9a774c78
AO
9248 params.n_counter_offsets_beacon = len / sizeof(u16);
9249 if (rdev->wiphy.max_num_csa_counters &&
9250 (params.n_counter_offsets_beacon >
a05829a7
JB
9251 rdev->wiphy.max_num_csa_counters)) {
9252 err = -EINVAL;
9253 goto free;
9254 }
16ef1fe2 9255
9a774c78 9256 params.counter_offsets_beacon =
00c207ed 9257 nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
9a774c78
AO
9258
9259 /* sanity checks - counters should fit and be the same */
9260 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
9261 u16 offset = params.counter_offsets_beacon[i];
9262
a05829a7
JB
9263 if (offset >= params.beacon_csa.tail_len) {
9264 err = -EINVAL;
9265 goto free;
9266 }
9a774c78 9267
a05829a7
JB
9268 if (params.beacon_csa.tail[offset] != params.count) {
9269 err = -EINVAL;
9270 goto free;
9271 }
9a774c78
AO
9272 }
9273
00c207ed
JC
9274 if (csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
9275 len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
a05829a7
JB
9276 if (!len || (len % sizeof(u16))) {
9277 err = -EINVAL;
9278 goto free;
9279 }
16ef1fe2 9280
9a774c78
AO
9281 params.n_counter_offsets_presp = len / sizeof(u16);
9282 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 9283 (params.n_counter_offsets_presp >
a05829a7
JB
9284 rdev->wiphy.max_num_csa_counters)) {
9285 err = -EINVAL;
9286 goto free;
9287 }
9a774c78
AO
9288
9289 params.counter_offsets_presp =
00c207ed 9290 nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
9a774c78
AO
9291
9292 /* sanity checks - counters should fit and be the same */
9293 for (i = 0; i < params.n_counter_offsets_presp; i++) {
9294 u16 offset = params.counter_offsets_presp[i];
9295
a05829a7
JB
9296 if (offset >= params.beacon_csa.probe_resp_len) {
9297 err = -EINVAL;
9298 goto free;
9299 }
9a774c78
AO
9300
9301 if (params.beacon_csa.probe_resp[offset] !=
a05829a7
JB
9302 params.count) {
9303 err = -EINVAL;
9304 goto free;
9305 }
9a774c78 9306 }
16ef1fe2
SW
9307 }
9308
ee4bc9e7 9309skip_beacons:
16ef1fe2
SW
9310 err = nl80211_parse_chandef(rdev, info, &params.chandef);
9311 if (err)
a05829a7 9312 goto free;
16ef1fe2 9313
923b352f 9314 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
a05829a7
JB
9315 wdev->iftype)) {
9316 err = -EINVAL;
9317 goto free;
9318 }
16ef1fe2 9319
2beb6dab
LC
9320 err = cfg80211_chandef_dfs_required(wdev->wiphy,
9321 &params.chandef,
9322 wdev->iftype);
9323 if (err < 0)
a05829a7 9324 goto free;
2beb6dab 9325
8d9de16f 9326 if (err > 0) {
2beb6dab 9327 params.radar_required = true;
8d9de16f
BB
9328 if (need_handle_dfs_flag &&
9329 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
a05829a7
JB
9330 err = -EINVAL;
9331 goto free;
8d9de16f
BB
9332 }
9333 }
16ef1fe2 9334
16ef1fe2
SW
9335 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
9336 params.block_tx = true;
9337
c56589ed
SW
9338 wdev_lock(wdev);
9339 err = rdev_channel_switch(rdev, dev, &params);
9340 wdev_unlock(wdev);
9341
a05829a7
JB
9342free:
9343 kfree(csa_attrs);
c56589ed 9344 return err;
16ef1fe2
SW
9345}
9346
9720bb3a
JB
9347static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
9348 u32 seq, int flags,
2a519311 9349 struct cfg80211_registered_device *rdev,
48ab905d
JB
9350 struct wireless_dev *wdev,
9351 struct cfg80211_internal_bss *intbss)
2a519311 9352{
48ab905d 9353 struct cfg80211_bss *res = &intbss->pub;
9caf0364 9354 const struct cfg80211_bss_ies *ies;
2a519311
JB
9355 void *hdr;
9356 struct nlattr *bss;
48ab905d
JB
9357
9358 ASSERT_WDEV_LOCK(wdev);
2a519311 9359
15e47304 9360 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
9361 NL80211_CMD_NEW_SCAN_RESULTS);
9362 if (!hdr)
9363 return -1;
9364
0a833c29 9365 genl_dump_check_consistent(cb, hdr);
9720bb3a 9366
97990a06
JB
9367 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
9368 goto nla_put_failure;
9369 if (wdev->netdev &&
9360ffd1
DM
9370 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
9371 goto nla_put_failure;
2dad624e
ND
9372 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
9373 NL80211_ATTR_PAD))
97990a06 9374 goto nla_put_failure;
2a519311 9375
ae0be8de 9376 bss = nla_nest_start_noflag(msg, NL80211_ATTR_BSS);
2a519311
JB
9377 if (!bss)
9378 goto nla_put_failure;
9360ffd1 9379 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 9380 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 9381 goto nla_put_failure;
9caf0364
JB
9382
9383 rcu_read_lock();
0e227084
JB
9384 /* indicate whether we have probe response data or not */
9385 if (rcu_access_pointer(res->proberesp_ies) &&
9386 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
9387 goto fail_unlock_rcu;
9388
9389 /* this pointer prefers to be pointed to probe response data
9390 * but is always valid
9391 */
9caf0364 9392 ies = rcu_dereference(res->ies);
8cef2c9d 9393 if (ies) {
2dad624e
ND
9394 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
9395 NL80211_BSS_PAD))
8cef2c9d 9396 goto fail_unlock_rcu;
8cef2c9d
JB
9397 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
9398 ies->len, ies->data))
9399 goto fail_unlock_rcu;
9caf0364 9400 }
0e227084
JB
9401
9402 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 9403 ies = rcu_dereference(res->beacon_ies);
0e227084 9404 if (ies && ies->from_beacon) {
2dad624e
ND
9405 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
9406 NL80211_BSS_PAD))
8cef2c9d
JB
9407 goto fail_unlock_rcu;
9408 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
9409 ies->len, ies->data))
9410 goto fail_unlock_rcu;
9caf0364
JB
9411 }
9412 rcu_read_unlock();
9413
9360ffd1
DM
9414 if (res->beacon_interval &&
9415 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
9416 goto nla_put_failure;
9417 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
9418 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
942ba88b
TP
9419 nla_put_u32(msg, NL80211_BSS_FREQUENCY_OFFSET,
9420 res->channel->freq_offset) ||
dcd6eac1 9421 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
9422 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
9423 jiffies_to_msecs(jiffies - intbss->ts)))
9424 goto nla_put_failure;
2a519311 9425
1d76250b
AS
9426 if (intbss->parent_tsf &&
9427 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
9428 intbss->parent_tsf, NL80211_BSS_PAD) ||
9429 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
9430 intbss->parent_bssid)))
9431 goto nla_put_failure;
9432
6e19bc4b 9433 if (intbss->ts_boottime &&
2dad624e
ND
9434 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
9435 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
9436 goto nla_put_failure;
9437
983dafaa
SD
9438 if (!nl80211_put_signal(msg, intbss->pub.chains,
9439 intbss->pub.chain_signal,
9440 NL80211_BSS_CHAIN_SIGNAL))
9441 goto nla_put_failure;
9442
77965c97 9443 switch (rdev->wiphy.signal_type) {
2a519311 9444 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
9445 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
9446 goto nla_put_failure;
2a519311
JB
9447 break;
9448 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
9449 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
9450 goto nla_put_failure;
2a519311
JB
9451 break;
9452 default:
9453 break;
9454 }
9455
48ab905d 9456 switch (wdev->iftype) {
074ac8df 9457 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 9458 case NL80211_IFTYPE_STATION:
9360ffd1
DM
9459 if (intbss == wdev->current_bss &&
9460 nla_put_u32(msg, NL80211_BSS_STATUS,
9461 NL80211_BSS_STATUS_ASSOCIATED))
9462 goto nla_put_failure;
48ab905d
JB
9463 break;
9464 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
9465 if (intbss == wdev->current_bss &&
9466 nla_put_u32(msg, NL80211_BSS_STATUS,
9467 NL80211_BSS_STATUS_IBSS_JOINED))
9468 goto nla_put_failure;
48ab905d
JB
9469 break;
9470 default:
9471 break;
9472 }
9473
2a519311
JB
9474 nla_nest_end(msg, bss);
9475
053c095a
JB
9476 genlmsg_end(msg, hdr);
9477 return 0;
2a519311 9478
8cef2c9d
JB
9479 fail_unlock_rcu:
9480 rcu_read_unlock();
2a519311
JB
9481 nla_put_failure:
9482 genlmsg_cancel(msg, hdr);
9483 return -EMSGSIZE;
9484}
9485
97990a06 9486static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 9487{
48ab905d 9488 struct cfg80211_registered_device *rdev;
2a519311 9489 struct cfg80211_internal_bss *scan;
48ab905d 9490 struct wireless_dev *wdev;
97990a06 9491 int start = cb->args[2], idx = 0;
2a519311
JB
9492 int err;
9493
5297c65c 9494 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
a05829a7 9495 if (err)
67748893 9496 return err;
a05829a7
JB
9497 /* nl80211_prepare_wdev_dump acquired it in the successful case */
9498 __acquire(&rdev->wiphy.mtx);
2a519311 9499
48ab905d
JB
9500 wdev_lock(wdev);
9501 spin_lock_bh(&rdev->bss_lock);
d1e23c94
DK
9502
9503 /*
9504 * dump_scan will be called multiple times to break up the scan results
9505 * into multiple messages. It is unlikely that any more bss-es will be
9506 * expired after the first call, so only call only call this on the
9507 * first dump_scan invocation.
9508 */
9509 if (start == 0)
9510 cfg80211_bss_expire(rdev);
48ab905d 9511
9720bb3a
JB
9512 cb->seq = rdev->bss_generation;
9513
48ab905d 9514 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
9515 if (++idx <= start)
9516 continue;
9720bb3a 9517 if (nl80211_send_bss(skb, cb,
2a519311 9518 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 9519 rdev, wdev, scan) < 0) {
2a519311 9520 idx--;
67748893 9521 break;
2a519311
JB
9522 }
9523 }
9524
48ab905d
JB
9525 spin_unlock_bh(&rdev->bss_lock);
9526 wdev_unlock(wdev);
2a519311 9527
97990a06 9528 cb->args[2] = idx;
a05829a7 9529 wiphy_unlock(&rdev->wiphy);
2a519311 9530
67748893 9531 return skb->len;
2a519311
JB
9532}
9533
15e47304 9534static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
9535 int flags, struct net_device *dev,
9536 bool allow_radio_stats,
9537 struct survey_info *survey)
61fa713c
HS
9538{
9539 void *hdr;
9540 struct nlattr *infoattr;
9541
11f78ac3
JB
9542 /* skip radio stats if userspace didn't request them */
9543 if (!survey->channel && !allow_radio_stats)
9544 return 0;
9545
15e47304 9546 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
9547 NL80211_CMD_NEW_SURVEY_RESULTS);
9548 if (!hdr)
9549 return -ENOMEM;
9550
9360ffd1
DM
9551 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9552 goto nla_put_failure;
61fa713c 9553
ae0be8de 9554 infoattr = nla_nest_start_noflag(msg, NL80211_ATTR_SURVEY_INFO);
61fa713c
HS
9555 if (!infoattr)
9556 goto nla_put_failure;
9557
11f78ac3
JB
9558 if (survey->channel &&
9559 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
9560 survey->channel->center_freq))
9561 goto nla_put_failure;
58ef7c1b
TP
9562
9563 if (survey->channel && survey->channel->freq_offset &&
9564 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY_OFFSET,
9565 survey->channel->freq_offset))
9566 goto nla_put_failure;
9360ffd1
DM
9567
9568 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
9569 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
9570 goto nla_put_failure;
9571 if ((survey->filled & SURVEY_INFO_IN_USE) &&
9572 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
9573 goto nla_put_failure;
4ed20beb 9574 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
9575 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
9576 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 9577 goto nla_put_failure;
4ed20beb 9578 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
9579 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
9580 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9581 goto nla_put_failure;
4ed20beb 9582 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
9583 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
9584 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9585 goto nla_put_failure;
4ed20beb 9586 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
9587 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
9588 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9589 goto nla_put_failure;
4ed20beb 9590 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
9591 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
9592 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9593 goto nla_put_failure;
052536ab 9594 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
9595 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
9596 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 9597 goto nla_put_failure;
c8cd6e7f
FF
9598 if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) &&
9599 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX,
9600 survey->time_bss_rx, NL80211_SURVEY_INFO_PAD))
9601 goto nla_put_failure;
61fa713c
HS
9602
9603 nla_nest_end(msg, infoattr);
9604
053c095a
JB
9605 genlmsg_end(msg, hdr);
9606 return 0;
61fa713c
HS
9607
9608 nla_put_failure:
9609 genlmsg_cancel(msg, hdr);
9610 return -EMSGSIZE;
9611}
9612
11f78ac3 9613static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 9614{
50508d94 9615 struct nlattr **attrbuf;
61fa713c 9616 struct survey_info survey;
1b8ec87a 9617 struct cfg80211_registered_device *rdev;
97990a06
JB
9618 struct wireless_dev *wdev;
9619 int survey_idx = cb->args[2];
61fa713c 9620 int res;
11f78ac3 9621 bool radio_stats;
61fa713c 9622
50508d94
JB
9623 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
9624 if (!attrbuf)
9625 return -ENOMEM;
9626
5297c65c 9627 res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
a05829a7
JB
9628 if (res) {
9629 kfree(attrbuf);
9630 return res;
9631 }
9632 /* nl80211_prepare_wdev_dump acquired it in the successful case */
9633 __acquire(&rdev->wiphy.mtx);
61fa713c 9634
11f78ac3 9635 /* prepare_wdev_dump parsed the attributes */
c90c39da 9636 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 9637
97990a06
JB
9638 if (!wdev->netdev) {
9639 res = -EINVAL;
9640 goto out_err;
9641 }
9642
1b8ec87a 9643 if (!rdev->ops->dump_survey) {
61fa713c
HS
9644 res = -EOPNOTSUPP;
9645 goto out_err;
9646 }
9647
9648 while (1) {
1b8ec87a 9649 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
9650 if (res == -ENOENT)
9651 break;
9652 if (res)
9653 goto out_err;
9654
11f78ac3
JB
9655 /* don't send disabled channels, but do send non-channel data */
9656 if (survey.channel &&
9657 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
9658 survey_idx++;
9659 continue;
9660 }
9661
61fa713c 9662 if (nl80211_send_survey(skb,
15e47304 9663 NETLINK_CB(cb->skb).portid,
61fa713c 9664 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 9665 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
9666 goto out;
9667 survey_idx++;
9668 }
9669
9670 out:
97990a06 9671 cb->args[2] = survey_idx;
61fa713c
HS
9672 res = skb->len;
9673 out_err:
50508d94 9674 kfree(attrbuf);
a05829a7 9675 wiphy_unlock(&rdev->wiphy);
61fa713c
HS
9676 return res;
9677}
9678
b23aa676
SO
9679static bool nl80211_valid_wpa_versions(u32 wpa_versions)
9680{
9681 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
cc3e14c2
CHH
9682 NL80211_WPA_VERSION_2 |
9683 NL80211_WPA_VERSION_3));
b23aa676
SO
9684}
9685
636a5d36
JM
9686static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
9687{
4c476991
JB
9688 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9689 struct net_device *dev = info->user_ptr[1];
19957bb3 9690 struct ieee80211_channel *chan;
11b6b5a4
JM
9691 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
9692 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 9693 enum nl80211_auth_type auth_type;
fffd0934 9694 struct key_parse key;
d5cdfacb 9695 bool local_state_change;
942ba88b 9696 u32 freq;
636a5d36 9697
f4a11bb0
JB
9698 if (!info->attrs[NL80211_ATTR_MAC])
9699 return -EINVAL;
9700
1778092e
JM
9701 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
9702 return -EINVAL;
9703
19957bb3
JB
9704 if (!info->attrs[NL80211_ATTR_SSID])
9705 return -EINVAL;
9706
9707 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
9708 return -EINVAL;
9709
fffd0934
JB
9710 err = nl80211_parse_key(info, &key);
9711 if (err)
9712 return err;
9713
9714 if (key.idx >= 0) {
e31b8213
JB
9715 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
9716 return -EINVAL;
fffd0934
JB
9717 if (!key.p.key || !key.p.key_len)
9718 return -EINVAL;
9719 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
9720 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
9721 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
9722 key.p.key_len != WLAN_KEY_LEN_WEP104))
9723 return -EINVAL;
b6b5555b 9724 if (key.idx > 3)
fffd0934
JB
9725 return -EINVAL;
9726 } else {
9727 key.p.key_len = 0;
9728 key.p.key = NULL;
9729 }
9730
afea0b7a
JB
9731 if (key.idx >= 0) {
9732 int i;
9733 bool ok = false;
7a087e74 9734
afea0b7a
JB
9735 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
9736 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
9737 ok = true;
9738 break;
9739 }
9740 }
4c476991
JB
9741 if (!ok)
9742 return -EINVAL;
afea0b7a
JB
9743 }
9744
4c476991
JB
9745 if (!rdev->ops->auth)
9746 return -EOPNOTSUPP;
636a5d36 9747
074ac8df 9748 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9749 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9750 return -EOPNOTSUPP;
eec60b03 9751
19957bb3 9752 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
942ba88b
TP
9753 freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
9754 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
9755 freq +=
9756 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
9757
9758 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
664834de 9759 if (!chan)
4c476991 9760 return -EINVAL;
636a5d36 9761
19957bb3
JB
9762 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9763 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
9764
9765 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
9766 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9767 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9768 }
9769
19957bb3 9770 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 9771 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 9772 return -EINVAL;
636a5d36 9773
63181060
JM
9774 if ((auth_type == NL80211_AUTHTYPE_SAE ||
9775 auth_type == NL80211_AUTHTYPE_FILS_SK ||
9776 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
9777 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 9778 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
9779 return -EINVAL;
9780
11b6b5a4 9781 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
9782 if (auth_type != NL80211_AUTHTYPE_SAE &&
9783 auth_type != NL80211_AUTHTYPE_FILS_SK &&
9784 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
9785 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 9786 return -EINVAL;
11b6b5a4
JM
9787 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
9788 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e
JM
9789 }
9790
d5cdfacb
JM
9791 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
9792
95de817b
JB
9793 /*
9794 * Since we no longer track auth state, ignore
9795 * requests to only change local state.
9796 */
9797 if (local_state_change)
9798 return 0;
9799
91bf9b26
JB
9800 wdev_lock(dev->ieee80211_ptr);
9801 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
9802 ssid, ssid_len, ie, ie_len,
9803 key.p.key, key.p.key_len, key.idx,
11b6b5a4 9804 auth_data, auth_data_len);
91bf9b26
JB
9805 wdev_unlock(dev->ieee80211_ptr);
9806 return err;
636a5d36
JM
9807}
9808
64bf3d4b
DK
9809static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
9810 struct genl_info *info)
9811{
9812 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9813 GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
9814 return -EINVAL;
9815 }
9816
9817 if (!rdev->ops->tx_control_port ||
9818 !wiphy_ext_feature_isset(&rdev->wiphy,
9819 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
9820 return -EOPNOTSUPP;
9821
9822 return 0;
9823}
9824
c0692b8f
JB
9825static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
9826 struct genl_info *info,
3dc27d25
JB
9827 struct cfg80211_crypto_settings *settings,
9828 int cipher_limit)
b23aa676 9829{
c0b2bbd8
JB
9830 memset(settings, 0, sizeof(*settings));
9831
b23aa676
SO
9832 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
9833
c0692b8f
JB
9834 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
9835 u16 proto;
7a087e74 9836
c0692b8f
JB
9837 proto = nla_get_u16(
9838 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
9839 settings->control_port_ethertype = cpu_to_be16(proto);
9840 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
9841 proto != ETH_P_PAE)
9842 return -EINVAL;
9843 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
9844 settings->control_port_no_encrypt = true;
9845 } else
9846 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
9847
64bf3d4b
DK
9848 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
9849 int r = validate_pae_over_nl80211(rdev, info);
9850
9851 if (r < 0)
9852 return r;
9853
9854 settings->control_port_over_nl80211 = true;
7f3f96ce
MT
9855
9856 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH])
9857 settings->control_port_no_preauth = true;
64bf3d4b
DK
9858 }
9859
b23aa676
SO
9860 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
9861 void *data;
9862 int len, i;
9863
9864 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
9865 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
9866 settings->n_ciphers_pairwise = len / sizeof(u32);
9867
9868 if (len % sizeof(u32))
9869 return -EINVAL;
9870
3dc27d25 9871 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
9872 return -EINVAL;
9873
9874 memcpy(settings->ciphers_pairwise, data, len);
9875
9876 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
9877 if (!cfg80211_supported_cipher_suite(
9878 &rdev->wiphy,
b23aa676
SO
9879 settings->ciphers_pairwise[i]))
9880 return -EINVAL;
9881 }
9882
9883 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
9884 settings->cipher_group =
9885 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
9886 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
9887 settings->cipher_group))
b23aa676
SO
9888 return -EINVAL;
9889 }
9890
9891 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
9892 settings->wpa_versions =
9893 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
9894 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
9895 return -EINVAL;
9896 }
9897
9898 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
9899 void *data;
6d30240e 9900 int len;
b23aa676
SO
9901
9902 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
9903 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
9904 settings->n_akm_suites = len / sizeof(u32);
9905
9906 if (len % sizeof(u32))
9907 return -EINVAL;
9908
1b9ca027
JM
9909 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
9910 return -EINVAL;
9911
b23aa676 9912 memcpy(settings->akm_suites, data, len);
b23aa676
SO
9913 }
9914
91b5ab62
EP
9915 if (info->attrs[NL80211_ATTR_PMK]) {
9916 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
9917 return -EINVAL;
9918 if (!wiphy_ext_feature_isset(&rdev->wiphy,
f9662274
CHH
9919 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) &&
9920 !wiphy_ext_feature_isset(&rdev->wiphy,
9921 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
91b5ab62
EP
9922 return -EINVAL;
9923 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
9924 }
9925
26f7044e
CHH
9926 if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
9927 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2831a631
CHH
9928 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
9929 !wiphy_ext_feature_isset(&rdev->wiphy,
9930 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP))
26f7044e
CHH
9931 return -EINVAL;
9932 settings->sae_pwd =
9933 nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
9934 settings->sae_pwd_len =
9935 nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
9936 }
9937
9f0ffa41
RD
9938 if (info->attrs[NL80211_ATTR_SAE_PWE])
9939 settings->sae_pwe =
9940 nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
9941 else
9942 settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
9943
b23aa676
SO
9944 return 0;
9945}
9946
636a5d36
JM
9947static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
9948{
4c476991
JB
9949 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9950 struct net_device *dev = info->user_ptr[1];
f444de05 9951 struct ieee80211_channel *chan;
f62fab73
JB
9952 struct cfg80211_assoc_request req = {};
9953 const u8 *bssid, *ssid;
9954 int err, ssid_len = 0;
942ba88b 9955 u32 freq;
636a5d36 9956
bad29297
AZ
9957 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9958 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9959 return -EPERM;
9960
f4a11bb0 9961 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
9962 !info->attrs[NL80211_ATTR_SSID] ||
9963 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
9964 return -EINVAL;
9965
4c476991
JB
9966 if (!rdev->ops->assoc)
9967 return -EOPNOTSUPP;
636a5d36 9968
074ac8df 9969 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9970 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9971 return -EOPNOTSUPP;
eec60b03 9972
19957bb3 9973 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 9974
942ba88b
TP
9975 freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
9976 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
9977 freq +=
9978 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
9979 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
664834de 9980 if (!chan)
4c476991 9981 return -EINVAL;
636a5d36 9982
19957bb3
JB
9983 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9984 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
9985
9986 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
9987 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9988 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9989 }
9990
dc6382ce 9991 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 9992 enum nl80211_mfp mfp =
dc6382ce 9993 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 9994 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 9995 req.use_mfp = true;
4c476991
JB
9996 else if (mfp != NL80211_MFP_NO)
9997 return -EINVAL;
dc6382ce
JM
9998 }
9999
3e5d7649 10000 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 10001 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 10002
7e7c8926 10003 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 10004 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
10005
10006 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
10007 memcpy(&req.ht_capa_mask,
10008 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10009 sizeof(req.ht_capa_mask));
7e7c8926
BG
10010
10011 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 10012 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 10013 return -EINVAL;
f62fab73
JB
10014 memcpy(&req.ht_capa,
10015 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10016 sizeof(req.ht_capa));
7e7c8926
BG
10017 }
10018
ee2aca34 10019 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 10020 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
10021
10022 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
10023 memcpy(&req.vht_capa_mask,
10024 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
10025 sizeof(req.vht_capa_mask));
ee2aca34
JB
10026
10027 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 10028 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 10029 return -EINVAL;
f62fab73
JB
10030 memcpy(&req.vht_capa,
10031 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
10032 sizeof(req.vht_capa));
ee2aca34
JB
10033 }
10034
bab5ab7d 10035 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
10036 if (!((rdev->wiphy.features &
10037 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
10038 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
10039 !wiphy_ext_feature_isset(&rdev->wiphy,
10040 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
10041 return -EINVAL;
10042 req.flags |= ASSOC_REQ_USE_RRM;
10043 }
10044
348bd456
JM
10045 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
10046 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
10047 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
10048 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
10049 return -EINVAL;
10050 req.fils_nonces =
10051 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
10052 }
10053
d2b7588a
TP
10054 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]) {
10055 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY])
10056 return -EINVAL;
10057 memcpy(&req.s1g_capa_mask,
10058 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]),
10059 sizeof(req.s1g_capa_mask));
10060 }
10061
10062 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) {
10063 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK])
10064 return -EINVAL;
10065 memcpy(&req.s1g_capa,
10066 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]),
10067 sizeof(req.s1g_capa));
10068 }
10069
f62fab73 10070 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
10071 if (!err) {
10072 wdev_lock(dev->ieee80211_ptr);
bd2522b1 10073
f62fab73
JB
10074 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
10075 ssid, ssid_len, &req);
bd2522b1
AZ
10076
10077 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10078 dev->ieee80211_ptr->conn_owner_nlportid =
10079 info->snd_portid;
10080 memcpy(dev->ieee80211_ptr->disconnect_bssid,
10081 bssid, ETH_ALEN);
10082 }
10083
91bf9b26
JB
10084 wdev_unlock(dev->ieee80211_ptr);
10085 }
636a5d36 10086
636a5d36
JM
10087 return err;
10088}
10089
10090static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
10091{
4c476991
JB
10092 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10093 struct net_device *dev = info->user_ptr[1];
19957bb3 10094 const u8 *ie = NULL, *bssid;
91bf9b26 10095 int ie_len = 0, err;
19957bb3 10096 u16 reason_code;
d5cdfacb 10097 bool local_state_change;
636a5d36 10098
bad29297
AZ
10099 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10100 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10101 return -EPERM;
10102
f4a11bb0
JB
10103 if (!info->attrs[NL80211_ATTR_MAC])
10104 return -EINVAL;
10105
10106 if (!info->attrs[NL80211_ATTR_REASON_CODE])
10107 return -EINVAL;
10108
4c476991
JB
10109 if (!rdev->ops->deauth)
10110 return -EOPNOTSUPP;
636a5d36 10111
074ac8df 10112 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10113 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10114 return -EOPNOTSUPP;
eec60b03 10115
19957bb3 10116 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 10117
19957bb3
JB
10118 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
10119 if (reason_code == 0) {
f4a11bb0 10120 /* Reason Code 0 is reserved */
4c476991 10121 return -EINVAL;
255e737e 10122 }
636a5d36
JM
10123
10124 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
10125 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10126 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10127 }
10128
d5cdfacb
JM
10129 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10130
91bf9b26
JB
10131 wdev_lock(dev->ieee80211_ptr);
10132 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
10133 local_state_change);
10134 wdev_unlock(dev->ieee80211_ptr);
10135 return err;
636a5d36
JM
10136}
10137
10138static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
10139{
4c476991
JB
10140 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10141 struct net_device *dev = info->user_ptr[1];
19957bb3 10142 const u8 *ie = NULL, *bssid;
91bf9b26 10143 int ie_len = 0, err;
19957bb3 10144 u16 reason_code;
d5cdfacb 10145 bool local_state_change;
636a5d36 10146
bad29297
AZ
10147 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10148 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10149 return -EPERM;
10150
f4a11bb0
JB
10151 if (!info->attrs[NL80211_ATTR_MAC])
10152 return -EINVAL;
10153
10154 if (!info->attrs[NL80211_ATTR_REASON_CODE])
10155 return -EINVAL;
10156
4c476991
JB
10157 if (!rdev->ops->disassoc)
10158 return -EOPNOTSUPP;
636a5d36 10159
074ac8df 10160 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10161 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10162 return -EOPNOTSUPP;
eec60b03 10163
19957bb3 10164 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 10165
19957bb3
JB
10166 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
10167 if (reason_code == 0) {
f4a11bb0 10168 /* Reason Code 0 is reserved */
4c476991 10169 return -EINVAL;
255e737e 10170 }
636a5d36
JM
10171
10172 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
10173 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10174 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10175 }
10176
d5cdfacb
JM
10177 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10178
91bf9b26
JB
10179 wdev_lock(dev->ieee80211_ptr);
10180 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
10181 local_state_change);
10182 wdev_unlock(dev->ieee80211_ptr);
10183 return err;
636a5d36
JM
10184}
10185
dd5b4cc7
FF
10186static bool
10187nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 10188 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
10189 int rateval)
10190{
10191 struct wiphy *wiphy = &rdev->wiphy;
10192 bool found = false;
10193 int band, i;
10194
57fbcce3 10195 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
10196 struct ieee80211_supported_band *sband;
10197
10198 sband = wiphy->bands[band];
10199 if (!sband)
10200 continue;
10201
10202 for (i = 0; i < sband->n_bitrates; i++) {
10203 if (sband->bitrates[i].bitrate == rateval) {
10204 mcast_rate[band] = i + 1;
10205 found = true;
10206 break;
10207 }
10208 }
10209 }
10210
10211 return found;
10212}
10213
04a773ad
JB
10214static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
10215{
4c476991
JB
10216 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10217 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
10218 struct cfg80211_ibss_params ibss;
10219 struct wiphy *wiphy;
fffd0934 10220 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
10221 int err;
10222
8e30bc55
JB
10223 memset(&ibss, 0, sizeof(ibss));
10224
683b6d3b 10225 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
10226 !nla_len(info->attrs[NL80211_ATTR_SSID]))
10227 return -EINVAL;
10228
8e30bc55
JB
10229 ibss.beacon_interval = 100;
10230
12d20fc9 10231 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
10232 ibss.beacon_interval =
10233 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 10234
0c317a02
PK
10235 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
10236 ibss.beacon_interval);
12d20fc9
PK
10237 if (err)
10238 return err;
8e30bc55 10239
4c476991
JB
10240 if (!rdev->ops->join_ibss)
10241 return -EOPNOTSUPP;
04a773ad 10242
4c476991
JB
10243 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
10244 return -EOPNOTSUPP;
04a773ad 10245
79c97e97 10246 wiphy = &rdev->wiphy;
04a773ad 10247
39193498 10248 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 10249 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
10250
10251 if (!is_valid_ether_addr(ibss.bssid))
10252 return -EINVAL;
10253 }
04a773ad
JB
10254 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10255 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10256
10257 if (info->attrs[NL80211_ATTR_IE]) {
10258 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10259 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10260 }
10261
683b6d3b
JB
10262 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
10263 if (err)
10264 return err;
04a773ad 10265
174e0cd2
IP
10266 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
10267 NL80211_IFTYPE_ADHOC))
54858ee5
AS
10268 return -EINVAL;
10269
2f301ab2 10270 switch (ibss.chandef.width) {
bf372645
SW
10271 case NL80211_CHAN_WIDTH_5:
10272 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
10273 case NL80211_CHAN_WIDTH_20_NOHT:
10274 break;
10275 case NL80211_CHAN_WIDTH_20:
10276 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
10277 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
10278 return -EINVAL;
10279 break;
10280 case NL80211_CHAN_WIDTH_80:
10281 case NL80211_CHAN_WIDTH_80P80:
10282 case NL80211_CHAN_WIDTH_160:
10283 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
10284 return -EINVAL;
10285 if (!wiphy_ext_feature_isset(&rdev->wiphy,
10286 NL80211_EXT_FEATURE_VHT_IBSS))
10287 return -EINVAL;
10288 break;
2f301ab2 10289 default:
c04d6150 10290 return -EINVAL;
2f301ab2 10291 }
db9c64cf 10292
04a773ad 10293 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
10294 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
10295
fbd2c8dc
TP
10296 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
10297 u8 *rates =
10298 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10299 int n_rates =
10300 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10301 struct ieee80211_supported_band *sband =
683b6d3b 10302 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 10303
34850ab2
JB
10304 err = ieee80211_get_ratemask(sband, rates, n_rates,
10305 &ibss.basic_rates);
10306 if (err)
10307 return err;
fbd2c8dc 10308 }
dd5b4cc7 10309
803768f5
SW
10310 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10311 memcpy(&ibss.ht_capa_mask,
10312 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10313 sizeof(ibss.ht_capa_mask));
10314
10315 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
10316 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10317 return -EINVAL;
10318 memcpy(&ibss.ht_capa,
10319 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10320 sizeof(ibss.ht_capa));
10321 }
10322
dd5b4cc7
FF
10323 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
10324 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
10325 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
10326 return -EINVAL;
fbd2c8dc 10327
4c476991 10328 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
10329 bool no_ht = false;
10330
768075eb 10331 connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
4c476991
JB
10332 if (IS_ERR(connkeys))
10333 return PTR_ERR(connkeys);
de7044ee 10334
3d9d1d66
JB
10335 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
10336 no_ht) {
453431a5 10337 kfree_sensitive(connkeys);
de7044ee
SM
10338 return -EINVAL;
10339 }
4c476991 10340 }
04a773ad 10341
267335d6
AQ
10342 ibss.control_port =
10343 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
10344
c3bfe1f6
DK
10345 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
10346 int r = validate_pae_over_nl80211(rdev, info);
10347
d350a0f4 10348 if (r < 0) {
453431a5 10349 kfree_sensitive(connkeys);
c3bfe1f6 10350 return r;
d350a0f4 10351 }
c3bfe1f6
DK
10352
10353 ibss.control_port_over_nl80211 = true;
10354 }
10355
5336fa88
SW
10356 ibss.userspace_handles_dfs =
10357 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
10358
f8d16d3e
DK
10359 wdev_lock(dev->ieee80211_ptr);
10360 err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 10361 if (err)
453431a5 10362 kfree_sensitive(connkeys);
f8d16d3e
DK
10363 else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
10364 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10365 wdev_unlock(dev->ieee80211_ptr);
10366
04a773ad
JB
10367 return err;
10368}
10369
10370static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
10371{
4c476991
JB
10372 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10373 struct net_device *dev = info->user_ptr[1];
04a773ad 10374
4c476991
JB
10375 if (!rdev->ops->leave_ibss)
10376 return -EOPNOTSUPP;
04a773ad 10377
4c476991
JB
10378 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
10379 return -EOPNOTSUPP;
04a773ad 10380
4c476991 10381 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
10382}
10383
f4e583c8
AQ
10384static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
10385{
10386 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10387 struct net_device *dev = info->user_ptr[1];
57fbcce3 10388 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
10389 u32 nla_rate;
10390 int err;
10391
10392 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
10393 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
10394 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
10395 return -EOPNOTSUPP;
10396
10397 if (!rdev->ops->set_mcast_rate)
10398 return -EOPNOTSUPP;
10399
10400 memset(mcast_rate, 0, sizeof(mcast_rate));
10401
10402 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
10403 return -EINVAL;
10404
10405 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
10406 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
10407 return -EINVAL;
10408
a1056b1b 10409 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
10410
10411 return err;
10412}
10413
ad7e718c
JB
10414static struct sk_buff *
10415__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
10416 struct wireless_dev *wdev, int approxlen,
10417 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
10418 enum nl80211_attrs attr,
10419 const struct nl80211_vendor_cmd_info *info,
10420 gfp_t gfp)
ad7e718c
JB
10421{
10422 struct sk_buff *skb;
10423 void *hdr;
10424 struct nlattr *data;
10425
10426 skb = nlmsg_new(approxlen + 100, gfp);
10427 if (!skb)
10428 return NULL;
10429
10430 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
10431 if (!hdr) {
10432 kfree_skb(skb);
10433 return NULL;
10434 }
10435
10436 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
10437 goto nla_put_failure;
567ffc35
JB
10438
10439 if (info) {
10440 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
10441 info->vendor_id))
10442 goto nla_put_failure;
10443 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
10444 info->subcmd))
10445 goto nla_put_failure;
10446 }
10447
6c09e791 10448 if (wdev) {
2dad624e
ND
10449 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
10450 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
10451 goto nla_put_failure;
10452 if (wdev->netdev &&
10453 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
10454 wdev->netdev->ifindex))
10455 goto nla_put_failure;
10456 }
10457
ae0be8de 10458 data = nla_nest_start_noflag(skb, attr);
76e1fb4b
JB
10459 if (!data)
10460 goto nla_put_failure;
ad7e718c
JB
10461
10462 ((void **)skb->cb)[0] = rdev;
10463 ((void **)skb->cb)[1] = hdr;
10464 ((void **)skb->cb)[2] = data;
10465
10466 return skb;
10467
10468 nla_put_failure:
10469 kfree_skb(skb);
10470 return NULL;
10471}
f4e583c8 10472
e03ad6ea 10473struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 10474 struct wireless_dev *wdev,
e03ad6ea
JB
10475 enum nl80211_commands cmd,
10476 enum nl80211_attrs attr,
55c1fdf0 10477 unsigned int portid,
e03ad6ea
JB
10478 int vendor_event_idx,
10479 int approxlen, gfp_t gfp)
10480{
f26cbf40 10481 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
10482 const struct nl80211_vendor_cmd_info *info;
10483
10484 switch (cmd) {
10485 case NL80211_CMD_TESTMODE:
10486 if (WARN_ON(vendor_event_idx != -1))
10487 return NULL;
10488 info = NULL;
10489 break;
10490 case NL80211_CMD_VENDOR:
10491 if (WARN_ON(vendor_event_idx < 0 ||
10492 vendor_event_idx >= wiphy->n_vendor_events))
10493 return NULL;
10494 info = &wiphy->vendor_events[vendor_event_idx];
10495 break;
10496 default:
10497 WARN_ON(1);
10498 return NULL;
10499 }
10500
55c1fdf0 10501 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0,
e03ad6ea
JB
10502 cmd, attr, info, gfp);
10503}
10504EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
10505
10506void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
10507{
10508 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
10509 void *hdr = ((void **)skb->cb)[1];
55c1fdf0 10510 struct nlmsghdr *nlhdr = nlmsg_hdr(skb);
e03ad6ea
JB
10511 struct nlattr *data = ((void **)skb->cb)[2];
10512 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
10513
bd8c78e7
JB
10514 /* clear CB data for netlink core to own from now on */
10515 memset(skb->cb, 0, sizeof(skb->cb));
10516
e03ad6ea
JB
10517 nla_nest_end(skb, data);
10518 genlmsg_end(skb, hdr);
10519
55c1fdf0
JB
10520 if (nlhdr->nlmsg_pid) {
10521 genlmsg_unicast(wiphy_net(&rdev->wiphy), skb,
10522 nlhdr->nlmsg_pid);
10523 } else {
10524 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
10525 mcgrp = NL80211_MCGRP_VENDOR;
e03ad6ea 10526
55c1fdf0
JB
10527 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
10528 skb, 0, mcgrp, gfp);
10529 }
e03ad6ea
JB
10530}
10531EXPORT_SYMBOL(__cfg80211_send_event_skb);
10532
aff89a9b 10533#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
10534static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
10535{
4c476991 10536 struct cfg80211_registered_device *rdev = info->user_ptr[0];
a05829a7 10537 struct wireless_dev *wdev;
aff89a9b
JB
10538 int err;
10539
a05829a7
JB
10540 lockdep_assert_held(&rdev->wiphy.mtx);
10541
10542 wdev = __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
10543 info->attrs);
10544
fc73f11f
DS
10545 if (!rdev->ops->testmode_cmd)
10546 return -EOPNOTSUPP;
10547
10548 if (IS_ERR(wdev)) {
10549 err = PTR_ERR(wdev);
10550 if (err != -EINVAL)
10551 return err;
10552 wdev = NULL;
10553 } else if (wdev->wiphy != &rdev->wiphy) {
10554 return -EINVAL;
10555 }
10556
aff89a9b
JB
10557 if (!info->attrs[NL80211_ATTR_TESTDATA])
10558 return -EINVAL;
10559
ad7e718c 10560 rdev->cur_cmd_info = info;
fc73f11f 10561 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
10562 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
10563 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 10564 rdev->cur_cmd_info = NULL;
aff89a9b 10565
aff89a9b
JB
10566 return err;
10567}
10568
71063f0e
WYG
10569static int nl80211_testmode_dump(struct sk_buff *skb,
10570 struct netlink_callback *cb)
10571{
00918d33 10572 struct cfg80211_registered_device *rdev;
50508d94 10573 struct nlattr **attrbuf = NULL;
71063f0e
WYG
10574 int err;
10575 long phy_idx;
10576 void *data = NULL;
10577 int data_len = 0;
10578
5fe231e8
JB
10579 rtnl_lock();
10580
71063f0e
WYG
10581 if (cb->args[0]) {
10582 /*
10583 * 0 is a valid index, but not valid for args[0],
10584 * so we need to offset by 1.
10585 */
10586 phy_idx = cb->args[0] - 1;
a4956dca
LC
10587
10588 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
10589 if (!rdev) {
10590 err = -ENOENT;
10591 goto out_err;
10592 }
71063f0e 10593 } else {
50508d94
JB
10594 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
10595 GFP_KERNEL);
10596 if (!attrbuf) {
10597 err = -ENOMEM;
10598 goto out_err;
10599 }
c90c39da 10600
8cb08174
JB
10601 err = nlmsg_parse_deprecated(cb->nlh,
10602 GENL_HDRLEN + nl80211_fam.hdrsize,
10603 attrbuf, nl80211_fam.maxattr,
10604 nl80211_policy, NULL);
71063f0e 10605 if (err)
5fe231e8 10606 goto out_err;
00918d33 10607
c90c39da 10608 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 10609 if (IS_ERR(rdev)) {
5fe231e8
JB
10610 err = PTR_ERR(rdev);
10611 goto out_err;
00918d33 10612 }
2bd7e35d 10613 phy_idx = rdev->wiphy_idx;
2bd7e35d 10614
c90c39da
JB
10615 if (attrbuf[NL80211_ATTR_TESTDATA])
10616 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
10617 }
10618
10619 if (cb->args[1]) {
10620 data = nla_data((void *)cb->args[1]);
10621 data_len = nla_len((void *)cb->args[1]);
10622 }
10623
00918d33 10624 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
10625 err = -EOPNOTSUPP;
10626 goto out_err;
10627 }
10628
10629 while (1) {
15e47304 10630 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
10631 cb->nlh->nlmsg_seq, NLM_F_MULTI,
10632 NL80211_CMD_TESTMODE);
10633 struct nlattr *tmdata;
10634
cb35fba3
DC
10635 if (!hdr)
10636 break;
10637
9360ffd1 10638 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
10639 genlmsg_cancel(skb, hdr);
10640 break;
10641 }
10642
ae0be8de 10643 tmdata = nla_nest_start_noflag(skb, NL80211_ATTR_TESTDATA);
71063f0e
WYG
10644 if (!tmdata) {
10645 genlmsg_cancel(skb, hdr);
10646 break;
10647 }
e35e4d28 10648 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
10649 nla_nest_end(skb, tmdata);
10650
10651 if (err == -ENOBUFS || err == -ENOENT) {
10652 genlmsg_cancel(skb, hdr);
10653 break;
10654 } else if (err) {
10655 genlmsg_cancel(skb, hdr);
10656 goto out_err;
10657 }
10658
10659 genlmsg_end(skb, hdr);
10660 }
10661
10662 err = skb->len;
10663 /* see above */
10664 cb->args[0] = phy_idx + 1;
10665 out_err:
50508d94 10666 kfree(attrbuf);
5fe231e8 10667 rtnl_unlock();
71063f0e
WYG
10668 return err;
10669}
aff89a9b
JB
10670#endif
10671
b23aa676
SO
10672static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
10673{
4c476991
JB
10674 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10675 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
10676 struct cfg80211_connect_params connect;
10677 struct wiphy *wiphy;
fffd0934 10678 struct cfg80211_cached_keys *connkeys = NULL;
942ba88b 10679 u32 freq = 0;
b23aa676
SO
10680 int err;
10681
10682 memset(&connect, 0, sizeof(connect));
10683
b23aa676
SO
10684 if (!info->attrs[NL80211_ATTR_SSID] ||
10685 !nla_len(info->attrs[NL80211_ATTR_SSID]))
10686 return -EINVAL;
10687
10688 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
10689 connect.auth_type =
10690 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
10691 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
10692 NL80211_CMD_CONNECT))
b23aa676
SO
10693 return -EINVAL;
10694 } else
10695 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
10696
10697 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
10698
3a00df57
AS
10699 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
10700 !wiphy_ext_feature_isset(&rdev->wiphy,
10701 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
10702 return -EINVAL;
10703 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
10704
c0692b8f 10705 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 10706 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
10707 if (err)
10708 return err;
b23aa676 10709
074ac8df 10710 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10711 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10712 return -EOPNOTSUPP;
b23aa676 10713
79c97e97 10714 wiphy = &rdev->wiphy;
b23aa676 10715
4486ea98
BS
10716 connect.bg_scan_period = -1;
10717 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
10718 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
10719 connect.bg_scan_period =
10720 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
10721 }
10722
b23aa676
SO
10723 if (info->attrs[NL80211_ATTR_MAC])
10724 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
10725 else if (info->attrs[NL80211_ATTR_MAC_HINT])
10726 connect.bssid_hint =
10727 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
10728 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10729 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10730
10731 if (info->attrs[NL80211_ATTR_IE]) {
10732 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10733 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10734 }
10735
cee00a95
JM
10736 if (info->attrs[NL80211_ATTR_USE_MFP]) {
10737 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
65026002
EG
10738 if (connect.mfp == NL80211_MFP_OPTIONAL &&
10739 !wiphy_ext_feature_isset(&rdev->wiphy,
10740 NL80211_EXT_FEATURE_MFP_OPTIONAL))
10741 return -EOPNOTSUPP;
cee00a95
JM
10742 } else {
10743 connect.mfp = NL80211_MFP_NO;
10744 }
10745
ba6fbacf
JM
10746 if (info->attrs[NL80211_ATTR_PREV_BSSID])
10747 connect.prev_bssid =
10748 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
10749
942ba88b
TP
10750 if (info->attrs[NL80211_ATTR_WIPHY_FREQ])
10751 freq = MHZ_TO_KHZ(nla_get_u32(
10752 info->attrs[NL80211_ATTR_WIPHY_FREQ]));
10753 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
10754 freq +=
10755 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
10756
10757 if (freq) {
10758 connect.channel = nl80211_get_valid_chan(wiphy, freq);
664834de 10759 if (!connect.channel)
1df4a510
JM
10760 return -EINVAL;
10761 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
942ba88b
TP
10762 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
10763 freq = MHZ_TO_KHZ(freq);
10764 connect.channel_hint = nl80211_get_valid_chan(wiphy, freq);
664834de 10765 if (!connect.channel_hint)
4c476991 10766 return -EINVAL;
b23aa676
SO
10767 }
10768
2a38075c
AAL
10769 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
10770 connect.edmg.channels =
10771 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
10772
10773 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
10774 connect.edmg.bw_config =
10775 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
10776 }
10777
fffd0934 10778 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
768075eb 10779 connkeys = nl80211_parse_connkeys(rdev, info, NULL);
4c476991
JB
10780 if (IS_ERR(connkeys))
10781 return PTR_ERR(connkeys);
fffd0934
JB
10782 }
10783
7e7c8926
BG
10784 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
10785 connect.flags |= ASSOC_REQ_DISABLE_HT;
10786
10787 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10788 memcpy(&connect.ht_capa_mask,
10789 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10790 sizeof(connect.ht_capa_mask));
10791
10792 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 10793 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
453431a5 10794 kfree_sensitive(connkeys);
7e7c8926 10795 return -EINVAL;
b4e4f47e 10796 }
7e7c8926
BG
10797 memcpy(&connect.ht_capa,
10798 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10799 sizeof(connect.ht_capa));
10800 }
10801
ee2aca34
JB
10802 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
10803 connect.flags |= ASSOC_REQ_DISABLE_VHT;
10804
10805 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
10806 memcpy(&connect.vht_capa_mask,
10807 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
10808 sizeof(connect.vht_capa_mask));
10809
10810 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
10811 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
453431a5 10812 kfree_sensitive(connkeys);
ee2aca34
JB
10813 return -EINVAL;
10814 }
10815 memcpy(&connect.vht_capa,
10816 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
10817 sizeof(connect.vht_capa));
10818 }
10819
bab5ab7d 10820 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
10821 if (!((rdev->wiphy.features &
10822 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
10823 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
10824 !wiphy_ext_feature_isset(&rdev->wiphy,
10825 NL80211_EXT_FEATURE_RRM)) {
453431a5 10826 kfree_sensitive(connkeys);
bab5ab7d 10827 return -EINVAL;
707554b4 10828 }
bab5ab7d
AK
10829 connect.flags |= ASSOC_REQ_USE_RRM;
10830 }
10831
34d50519 10832 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 10833 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
453431a5 10834 kfree_sensitive(connkeys);
34d50519
LD
10835 return -EOPNOTSUPP;
10836 }
10837
38de03d2
AS
10838 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
10839 /* bss selection makes no sense if bssid is set */
10840 if (connect.bssid) {
453431a5 10841 kfree_sensitive(connkeys);
38de03d2
AS
10842 return -EINVAL;
10843 }
10844
10845 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
10846 wiphy, &connect.bss_select);
10847 if (err) {
453431a5 10848 kfree_sensitive(connkeys);
38de03d2
AS
10849 return err;
10850 }
10851 }
10852
a3caf744
VK
10853 if (wiphy_ext_feature_isset(&rdev->wiphy,
10854 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
10855 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
10856 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
10857 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
10858 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10859 connect.fils_erp_username =
10860 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10861 connect.fils_erp_username_len =
10862 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10863 connect.fils_erp_realm =
10864 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10865 connect.fils_erp_realm_len =
10866 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10867 connect.fils_erp_next_seq_num =
10868 nla_get_u16(
10869 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
10870 connect.fils_erp_rrk =
10871 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10872 connect.fils_erp_rrk_len =
10873 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10874 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
10875 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
10876 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
10877 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
453431a5 10878 kfree_sensitive(connkeys);
a3caf744
VK
10879 return -EINVAL;
10880 }
10881
40cbfa90
SD
10882 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
10883 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
453431a5 10884 kfree_sensitive(connkeys);
40cbfa90
SD
10885 GENL_SET_ERR_MSG(info,
10886 "external auth requires connection ownership");
10887 return -EINVAL;
10888 }
10889 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
10890 }
10891
83739b03 10892 wdev_lock(dev->ieee80211_ptr);
bd2522b1 10893
4ce2bd9c
JM
10894 err = cfg80211_connect(rdev, dev, &connect, connkeys,
10895 connect.prev_bssid);
fffd0934 10896 if (err)
453431a5 10897 kfree_sensitive(connkeys);
bd2522b1
AZ
10898
10899 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10900 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10901 if (connect.bssid)
10902 memcpy(dev->ieee80211_ptr->disconnect_bssid,
10903 connect.bssid, ETH_ALEN);
10904 else
3b1648f1 10905 eth_zero_addr(dev->ieee80211_ptr->disconnect_bssid);
bd2522b1
AZ
10906 }
10907
10908 wdev_unlock(dev->ieee80211_ptr);
10909
b23aa676
SO
10910 return err;
10911}
10912
088e8df8 10913static int nl80211_update_connect_params(struct sk_buff *skb,
10914 struct genl_info *info)
10915{
10916 struct cfg80211_connect_params connect = {};
10917 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10918 struct net_device *dev = info->user_ptr[1];
10919 struct wireless_dev *wdev = dev->ieee80211_ptr;
7f9a3e15
VK
10920 bool fils_sk_offload;
10921 u32 auth_type;
088e8df8 10922 u32 changed = 0;
10923 int ret;
10924
10925 if (!rdev->ops->update_connect_params)
10926 return -EOPNOTSUPP;
10927
10928 if (info->attrs[NL80211_ATTR_IE]) {
088e8df8 10929 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10930 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10931 changed |= UPDATE_ASSOC_IES;
10932 }
10933
7f9a3e15
VK
10934 fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
10935 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
10936
10937 /*
10938 * when driver supports fils-sk offload all attributes must be
10939 * provided. So the else covers "fils-sk-not-all" and
10940 * "no-fils-sk-any".
10941 */
10942 if (fils_sk_offload &&
10943 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
10944 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
10945 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
10946 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10947 connect.fils_erp_username =
10948 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10949 connect.fils_erp_username_len =
10950 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10951 connect.fils_erp_realm =
10952 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10953 connect.fils_erp_realm_len =
10954 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10955 connect.fils_erp_next_seq_num =
10956 nla_get_u16(
10957 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
10958 connect.fils_erp_rrk =
10959 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10960 connect.fils_erp_rrk_len =
10961 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10962 changed |= UPDATE_FILS_ERP_INFO;
10963 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
10964 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
10965 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
10966 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10967 return -EINVAL;
10968 }
10969
10970 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
10971 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
10972 if (!nl80211_valid_auth_type(rdev, auth_type,
10973 NL80211_CMD_CONNECT))
10974 return -EINVAL;
10975
10976 if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
10977 fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
10978 return -EINVAL;
10979
10980 connect.auth_type = auth_type;
10981 changed |= UPDATE_AUTH_TYPE;
10982 }
10983
088e8df8 10984 wdev_lock(dev->ieee80211_ptr);
10985 if (!wdev->current_bss)
10986 ret = -ENOLINK;
10987 else
10988 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
10989 wdev_unlock(dev->ieee80211_ptr);
10990
10991 return ret;
10992}
10993
b23aa676
SO
10994static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
10995{
4c476991
JB
10996 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10997 struct net_device *dev = info->user_ptr[1];
b23aa676 10998 u16 reason;
83739b03 10999 int ret;
b23aa676 11000
bad29297
AZ
11001 if (dev->ieee80211_ptr->conn_owner_nlportid &&
11002 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
11003 return -EPERM;
11004
b23aa676
SO
11005 if (!info->attrs[NL80211_ATTR_REASON_CODE])
11006 reason = WLAN_REASON_DEAUTH_LEAVING;
11007 else
11008 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
11009
11010 if (reason == 0)
11011 return -EINVAL;
11012
074ac8df 11013 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11014 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11015 return -EOPNOTSUPP;
b23aa676 11016
83739b03
JB
11017 wdev_lock(dev->ieee80211_ptr);
11018 ret = cfg80211_disconnect(rdev, dev, reason, true);
11019 wdev_unlock(dev->ieee80211_ptr);
11020 return ret;
b23aa676
SO
11021}
11022
463d0183
JB
11023static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
11024{
4c476991 11025 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
11026 struct net *net;
11027 int err;
463d0183 11028
4b681c82
VK
11029 if (info->attrs[NL80211_ATTR_PID]) {
11030 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
11031
11032 net = get_net_ns_by_pid(pid);
11033 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
11034 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 11035
4b681c82
VK
11036 net = get_net_ns_by_fd(fd);
11037 } else {
11038 return -EINVAL;
11039 }
463d0183 11040
4c476991
JB
11041 if (IS_ERR(net))
11042 return PTR_ERR(net);
463d0183
JB
11043
11044 err = 0;
11045
11046 /* check if anything to do */
4c476991
JB
11047 if (!net_eq(wiphy_net(&rdev->wiphy), net))
11048 err = cfg80211_switch_netns(rdev, net);
463d0183 11049
463d0183 11050 put_net(net);
463d0183
JB
11051 return err;
11052}
11053
67fbb16b
SO
11054static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
11055{
4c476991 11056 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
11057 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
11058 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 11059 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
11060 struct cfg80211_pmksa pmksa;
11061
11062 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
11063
67fbb16b
SO
11064 if (!info->attrs[NL80211_ATTR_PMKID])
11065 return -EINVAL;
11066
67fbb16b 11067 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
a3caf744
VK
11068
11069 if (info->attrs[NL80211_ATTR_MAC]) {
11070 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
11071 } else if (info->attrs[NL80211_ATTR_SSID] &&
11072 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
11073 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
11074 info->attrs[NL80211_ATTR_PMK])) {
11075 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
11076 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
11077 pmksa.cache_id =
11078 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
11079 } else {
11080 return -EINVAL;
11081 }
11082 if (info->attrs[NL80211_ATTR_PMK]) {
11083 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
11084 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
11085 }
67fbb16b 11086
7fc82af8
VJ
11087 if (info->attrs[NL80211_ATTR_PMK_LIFETIME])
11088 pmksa.pmk_lifetime =
11089 nla_get_u32(info->attrs[NL80211_ATTR_PMK_LIFETIME]);
11090
11091 if (info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD])
11092 pmksa.pmk_reauth_threshold =
11093 nla_get_u8(
11094 info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD]);
11095
074ac8df 11096 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
6c900360
LD
11097 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
11098 !(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP &&
11099 wiphy_ext_feature_isset(&rdev->wiphy,
11100 NL80211_EXT_FEATURE_AP_PMKSA_CACHING)))
4c476991 11101 return -EOPNOTSUPP;
67fbb16b
SO
11102
11103 switch (info->genlhdr->cmd) {
11104 case NL80211_CMD_SET_PMKSA:
11105 rdev_ops = rdev->ops->set_pmksa;
11106 break;
11107 case NL80211_CMD_DEL_PMKSA:
11108 rdev_ops = rdev->ops->del_pmksa;
11109 break;
11110 default:
11111 WARN_ON(1);
11112 break;
11113 }
11114
4c476991
JB
11115 if (!rdev_ops)
11116 return -EOPNOTSUPP;
67fbb16b 11117
4c476991 11118 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
11119}
11120
11121static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
11122{
4c476991
JB
11123 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11124 struct net_device *dev = info->user_ptr[1];
67fbb16b 11125
074ac8df 11126 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11127 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11128 return -EOPNOTSUPP;
67fbb16b 11129
4c476991
JB
11130 if (!rdev->ops->flush_pmksa)
11131 return -EOPNOTSUPP;
67fbb16b 11132
e35e4d28 11133 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
11134}
11135
109086ce
AN
11136static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
11137{
11138 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11139 struct net_device *dev = info->user_ptr[1];
11140 u8 action_code, dialog_token;
df942e7b 11141 u32 peer_capability = 0;
109086ce
AN
11142 u16 status_code;
11143 u8 *peer;
31fa97c5 11144 bool initiator;
109086ce
AN
11145
11146 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
11147 !rdev->ops->tdls_mgmt)
11148 return -EOPNOTSUPP;
11149
11150 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
11151 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
11152 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
11153 !info->attrs[NL80211_ATTR_IE] ||
11154 !info->attrs[NL80211_ATTR_MAC])
11155 return -EINVAL;
11156
11157 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11158 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
11159 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
11160 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 11161 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
11162 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
11163 peer_capability =
11164 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 11165
e35e4d28 11166 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 11167 dialog_token, status_code, peer_capability,
31fa97c5 11168 initiator,
e35e4d28
HG
11169 nla_data(info->attrs[NL80211_ATTR_IE]),
11170 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
11171}
11172
11173static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
11174{
11175 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11176 struct net_device *dev = info->user_ptr[1];
11177 enum nl80211_tdls_operation operation;
11178 u8 *peer;
11179
11180 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
11181 !rdev->ops->tdls_oper)
11182 return -EOPNOTSUPP;
11183
11184 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
11185 !info->attrs[NL80211_ATTR_MAC])
11186 return -EINVAL;
11187
11188 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
11189 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11190
e35e4d28 11191 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
11192}
11193
9588bbd5
JM
11194static int nl80211_remain_on_channel(struct sk_buff *skb,
11195 struct genl_info *info)
11196{
4c476991 11197 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11198 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 11199 struct cfg80211_chan_def chandef;
34373d12 11200 const struct cfg80211_chan_def *compat_chandef;
9588bbd5
JM
11201 struct sk_buff *msg;
11202 void *hdr;
11203 u64 cookie;
683b6d3b 11204 u32 duration;
9588bbd5
JM
11205 int err;
11206
11207 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
11208 !info->attrs[NL80211_ATTR_DURATION])
11209 return -EINVAL;
11210
11211 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
11212
ebf348fc
JB
11213 if (!rdev->ops->remain_on_channel ||
11214 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
11215 return -EOPNOTSUPP;
11216
9588bbd5 11217 /*
ebf348fc
JB
11218 * We should be on that channel for at least a minimum amount of
11219 * time (10ms) but no longer than the driver supports.
9588bbd5 11220 */
ebf348fc 11221 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 11222 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
11223 return -EINVAL;
11224
683b6d3b
JB
11225 err = nl80211_parse_chandef(rdev, info, &chandef);
11226 if (err)
11227 return err;
9588bbd5 11228
34373d12
VT
11229 wdev_lock(wdev);
11230 if (!cfg80211_off_channel_oper_allowed(wdev) &&
11231 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
11232 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
11233 &chandef);
11234 if (compat_chandef != &chandef) {
11235 wdev_unlock(wdev);
11236 return -EBUSY;
11237 }
11238 }
11239 wdev_unlock(wdev);
11240
9588bbd5 11241 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
11242 if (!msg)
11243 return -ENOMEM;
9588bbd5 11244
15e47304 11245 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 11246 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
11247 if (!hdr) {
11248 err = -ENOBUFS;
9588bbd5
JM
11249 goto free_msg;
11250 }
11251
683b6d3b
JB
11252 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
11253 duration, &cookie);
9588bbd5
JM
11254
11255 if (err)
11256 goto free_msg;
11257
2dad624e
ND
11258 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11259 NL80211_ATTR_PAD))
9360ffd1 11260 goto nla_put_failure;
9588bbd5
JM
11261
11262 genlmsg_end(msg, hdr);
4c476991
JB
11263
11264 return genlmsg_reply(msg, info);
9588bbd5
JM
11265
11266 nla_put_failure:
11267 err = -ENOBUFS;
11268 free_msg:
11269 nlmsg_free(msg);
9588bbd5
JM
11270 return err;
11271}
11272
11273static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
11274 struct genl_info *info)
11275{
4c476991 11276 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11277 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 11278 u64 cookie;
9588bbd5
JM
11279
11280 if (!info->attrs[NL80211_ATTR_COOKIE])
11281 return -EINVAL;
11282
4c476991
JB
11283 if (!rdev->ops->cancel_remain_on_channel)
11284 return -EOPNOTSUPP;
9588bbd5 11285
9588bbd5
JM
11286 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11287
e35e4d28 11288 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
11289}
11290
13ae75b1
JM
11291static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
11292 struct genl_info *info)
11293{
13ae75b1 11294 struct cfg80211_bitrate_mask mask;
a7c7fbff 11295 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 11296 struct net_device *dev = info->user_ptr[1];
a7c7fbff 11297 int err;
13ae75b1 11298
4c476991
JB
11299 if (!rdev->ops->set_bitrate_mask)
11300 return -EOPNOTSUPP;
13ae75b1 11301
9a5f6488 11302 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
eb89a6a6 11303 NL80211_ATTR_TX_RATES, &mask,
857b34c4 11304 dev, true);
a7c7fbff
PK
11305 if (err)
11306 return err;
13ae75b1 11307
e35e4d28 11308 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
11309}
11310
2e161f78 11311static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 11312{
4c476991 11313 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11314 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 11315 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
11316
11317 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
11318 return -EINVAL;
11319
2e161f78
JB
11320 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
11321 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 11322
71bbc994
JB
11323 switch (wdev->iftype) {
11324 case NL80211_IFTYPE_STATION:
11325 case NL80211_IFTYPE_ADHOC:
11326 case NL80211_IFTYPE_P2P_CLIENT:
11327 case NL80211_IFTYPE_AP:
11328 case NL80211_IFTYPE_AP_VLAN:
11329 case NL80211_IFTYPE_MESH_POINT:
11330 case NL80211_IFTYPE_P2P_GO:
98104fde 11331 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 11332 break;
cb3b7d87 11333 case NL80211_IFTYPE_NAN:
71bbc994 11334 default:
4c476991 11335 return -EOPNOTSUPP;
71bbc994 11336 }
026331c4
JM
11337
11338 /* not much point in registering if we can't reply */
4c476991
JB
11339 if (!rdev->ops->mgmt_tx)
11340 return -EOPNOTSUPP;
026331c4 11341
9dba48a6
JB
11342 if (info->attrs[NL80211_ATTR_RECEIVE_MULTICAST] &&
11343 !wiphy_ext_feature_isset(&rdev->wiphy,
11344 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS)) {
11345 GENL_SET_ERR_MSG(info,
11346 "multicast RX registrations are not supported");
11347 return -EOPNOTSUPP;
11348 }
11349
15e47304 11350 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
ff74c51e
IP
11351 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
11352 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]),
9dba48a6 11353 info->attrs[NL80211_ATTR_RECEIVE_MULTICAST],
ff74c51e 11354 info->extack);
026331c4
JM
11355}
11356
2e161f78 11357static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 11358{
4c476991 11359 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11360 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 11361 struct cfg80211_chan_def chandef;
026331c4 11362 int err;
d64d373f 11363 void *hdr = NULL;
026331c4 11364 u64 cookie;
e247bd90 11365 struct sk_buff *msg = NULL;
b176e629
AO
11366 struct cfg80211_mgmt_tx_params params = {
11367 .dont_wait_for_ack =
11368 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
11369 };
026331c4 11370
683b6d3b 11371 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
11372 return -EINVAL;
11373
4c476991
JB
11374 if (!rdev->ops->mgmt_tx)
11375 return -EOPNOTSUPP;
026331c4 11376
71bbc994 11377 switch (wdev->iftype) {
ea141b75
AQ
11378 case NL80211_IFTYPE_P2P_DEVICE:
11379 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
11380 return -EINVAL;
d7832c71 11381 break;
71bbc994
JB
11382 case NL80211_IFTYPE_STATION:
11383 case NL80211_IFTYPE_ADHOC:
11384 case NL80211_IFTYPE_P2P_CLIENT:
11385 case NL80211_IFTYPE_AP:
11386 case NL80211_IFTYPE_AP_VLAN:
11387 case NL80211_IFTYPE_MESH_POINT:
11388 case NL80211_IFTYPE_P2P_GO:
11389 break;
cb3b7d87 11390 case NL80211_IFTYPE_NAN:
71bbc994 11391 default:
4c476991 11392 return -EOPNOTSUPP;
71bbc994 11393 }
026331c4 11394
f7ca38df 11395 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 11396 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 11397 return -EINVAL;
b176e629 11398 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
11399
11400 /*
11401 * We should wait on the channel for at least a minimum amount
11402 * of time (10ms) but no longer than the driver supports.
11403 */
b176e629
AO
11404 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
11405 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 11406 return -EINVAL;
f7ca38df
JB
11407 }
11408
b176e629 11409 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 11410
b176e629 11411 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
11412 return -EINVAL;
11413
b176e629 11414 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 11415
ea141b75
AQ
11416 /* get the channel if any has been specified, otherwise pass NULL to
11417 * the driver. The latter will use the current one
11418 */
11419 chandef.chan = NULL;
11420 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
11421 err = nl80211_parse_chandef(rdev, info, &chandef);
11422 if (err)
11423 return err;
11424 }
11425
b176e629 11426 if (!chandef.chan && params.offchan)
ea141b75 11427 return -EINVAL;
026331c4 11428
34373d12
VT
11429 wdev_lock(wdev);
11430 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
11431 wdev_unlock(wdev);
11432 return -EBUSY;
11433 }
11434 wdev_unlock(wdev);
11435
34d22ce2
AO
11436 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
11437 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
11438
11439 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
11440 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
11441 int i;
11442
11443 if (len % sizeof(u16))
11444 return -EINVAL;
11445
11446 params.n_csa_offsets = len / sizeof(u16);
11447 params.csa_offsets =
11448 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
11449
11450 /* check that all the offsets fit the frame */
11451 for (i = 0; i < params.n_csa_offsets; i++) {
11452 if (params.csa_offsets[i] >= params.len)
11453 return -EINVAL;
11454 }
11455 }
11456
b176e629 11457 if (!params.dont_wait_for_ack) {
e247bd90
JB
11458 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11459 if (!msg)
11460 return -ENOMEM;
026331c4 11461
15e47304 11462 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 11463 NL80211_CMD_FRAME);
cb35fba3
DC
11464 if (!hdr) {
11465 err = -ENOBUFS;
e247bd90
JB
11466 goto free_msg;
11467 }
026331c4 11468 }
e247bd90 11469
b176e629
AO
11470 params.chan = chandef.chan;
11471 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
11472 if (err)
11473 goto free_msg;
11474
e247bd90 11475 if (msg) {
2dad624e
ND
11476 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11477 NL80211_ATTR_PAD))
9360ffd1 11478 goto nla_put_failure;
026331c4 11479
e247bd90
JB
11480 genlmsg_end(msg, hdr);
11481 return genlmsg_reply(msg, info);
11482 }
11483
11484 return 0;
026331c4
JM
11485
11486 nla_put_failure:
11487 err = -ENOBUFS;
11488 free_msg:
11489 nlmsg_free(msg);
026331c4
JM
11490 return err;
11491}
11492
f7ca38df
JB
11493static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
11494{
11495 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11496 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
11497 u64 cookie;
11498
11499 if (!info->attrs[NL80211_ATTR_COOKIE])
11500 return -EINVAL;
11501
11502 if (!rdev->ops->mgmt_tx_cancel_wait)
11503 return -EOPNOTSUPP;
11504
71bbc994
JB
11505 switch (wdev->iftype) {
11506 case NL80211_IFTYPE_STATION:
11507 case NL80211_IFTYPE_ADHOC:
11508 case NL80211_IFTYPE_P2P_CLIENT:
11509 case NL80211_IFTYPE_AP:
11510 case NL80211_IFTYPE_AP_VLAN:
11511 case NL80211_IFTYPE_P2P_GO:
98104fde 11512 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 11513 break;
cb3b7d87 11514 case NL80211_IFTYPE_NAN:
71bbc994 11515 default:
f7ca38df 11516 return -EOPNOTSUPP;
71bbc994 11517 }
f7ca38df
JB
11518
11519 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11520
e35e4d28 11521 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
11522}
11523
ffb9eb3d
KV
11524static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
11525{
4c476991 11526 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 11527 struct wireless_dev *wdev;
4c476991 11528 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
11529 u8 ps_state;
11530 bool state;
11531 int err;
11532
4c476991
JB
11533 if (!info->attrs[NL80211_ATTR_PS_STATE])
11534 return -EINVAL;
ffb9eb3d
KV
11535
11536 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
11537
ffb9eb3d
KV
11538 wdev = dev->ieee80211_ptr;
11539
4c476991
JB
11540 if (!rdev->ops->set_power_mgmt)
11541 return -EOPNOTSUPP;
ffb9eb3d
KV
11542
11543 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
11544
11545 if (state == wdev->ps)
4c476991 11546 return 0;
ffb9eb3d 11547
e35e4d28 11548 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
11549 if (!err)
11550 wdev->ps = state;
ffb9eb3d
KV
11551 return err;
11552}
11553
11554static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
11555{
4c476991 11556 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
11557 enum nl80211_ps_state ps_state;
11558 struct wireless_dev *wdev;
4c476991 11559 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
11560 struct sk_buff *msg;
11561 void *hdr;
11562 int err;
11563
ffb9eb3d
KV
11564 wdev = dev->ieee80211_ptr;
11565
4c476991
JB
11566 if (!rdev->ops->set_power_mgmt)
11567 return -EOPNOTSUPP;
ffb9eb3d
KV
11568
11569 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
11570 if (!msg)
11571 return -ENOMEM;
ffb9eb3d 11572
15e47304 11573 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
11574 NL80211_CMD_GET_POWER_SAVE);
11575 if (!hdr) {
4c476991 11576 err = -ENOBUFS;
ffb9eb3d
KV
11577 goto free_msg;
11578 }
11579
11580 if (wdev->ps)
11581 ps_state = NL80211_PS_ENABLED;
11582 else
11583 ps_state = NL80211_PS_DISABLED;
11584
9360ffd1
DM
11585 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
11586 goto nla_put_failure;
ffb9eb3d
KV
11587
11588 genlmsg_end(msg, hdr);
4c476991 11589 return genlmsg_reply(msg, info);
ffb9eb3d 11590
4c476991 11591 nla_put_failure:
ffb9eb3d 11592 err = -ENOBUFS;
4c476991 11593 free_msg:
ffb9eb3d 11594 nlmsg_free(msg);
ffb9eb3d
KV
11595 return err;
11596}
11597
94e860f1
JB
11598static const struct nla_policy
11599nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
4a4b8169 11600 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
d6dc1a38
JO
11601 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
11602 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
11603 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
11604 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
11605 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
bee427b8 11606 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
d6dc1a38
JO
11607};
11608
84f10708 11609static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 11610 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
11611{
11612 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 11613 struct net_device *dev = info->user_ptr[1];
1da5fcc8 11614 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 11615
d9d8b019 11616 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
11617 return -EINVAL;
11618
84f10708
TP
11619 if (!rdev->ops->set_cqm_txe_config)
11620 return -EOPNOTSUPP;
11621
11622 if (wdev->iftype != NL80211_IFTYPE_STATION &&
11623 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
11624 return -EOPNOTSUPP;
11625
e35e4d28 11626 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
11627}
11628
4a4b8169
AZ
11629static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
11630 struct net_device *dev)
11631{
11632 struct wireless_dev *wdev = dev->ieee80211_ptr;
11633 s32 last, low, high;
11634 u32 hyst;
1222a160 11635 int i, n, low_index;
4a4b8169
AZ
11636 int err;
11637
11638 /* RSSI reporting disabled? */
11639 if (!wdev->cqm_config)
11640 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
11641
11642 /*
11643 * Obtain current RSSI value if possible, if not and no RSSI threshold
11644 * event has been received yet, we should receive an event after a
11645 * connection is established and enough beacons received to calculate
11646 * the average.
11647 */
11648 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
11649 rdev->ops->get_station) {
73887fd9 11650 struct station_info sinfo = {};
4a4b8169
AZ
11651 u8 *mac_addr;
11652
11653 mac_addr = wdev->current_bss->pub.bssid;
11654
73887fd9
JB
11655 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
11656 if (err)
4a4b8169
AZ
11657 return err;
11658
df16737d 11659 cfg80211_sinfo_release_content(&sinfo);
397c657a 11660 if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
4a4b8169 11661 wdev->cqm_config->last_rssi_event_value =
73887fd9 11662 (s8) sinfo.rx_beacon_signal_avg;
4a4b8169
AZ
11663 }
11664
11665 last = wdev->cqm_config->last_rssi_event_value;
11666 hyst = wdev->cqm_config->rssi_hyst;
11667 n = wdev->cqm_config->n_rssi_thresholds;
11668
4b2c5a14
MH
11669 for (i = 0; i < n; i++) {
11670 i = array_index_nospec(i, n);
4a4b8169
AZ
11671 if (last < wdev->cqm_config->rssi_thresholds[i])
11672 break;
4b2c5a14 11673 }
4a4b8169 11674
1222a160
MH
11675 low_index = i - 1;
11676 if (low_index >= 0) {
11677 low_index = array_index_nospec(low_index, n);
11678 low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
11679 } else {
11680 low = S32_MIN;
11681 }
11682 if (i < n) {
11683 i = array_index_nospec(i, n);
11684 high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
11685 } else {
11686 high = S32_MAX;
11687 }
4a4b8169
AZ
11688
11689 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
11690}
11691
d6dc1a38 11692static int nl80211_set_cqm_rssi(struct genl_info *info,
4a4b8169
AZ
11693 const s32 *thresholds, int n_thresholds,
11694 u32 hysteresis)
d6dc1a38 11695{
4c476991 11696 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 11697 struct net_device *dev = info->user_ptr[1];
1da5fcc8 11698 struct wireless_dev *wdev = dev->ieee80211_ptr;
4a4b8169
AZ
11699 int i, err;
11700 s32 prev = S32_MIN;
d6dc1a38 11701
4a4b8169
AZ
11702 /* Check all values negative and sorted */
11703 for (i = 0; i < n_thresholds; i++) {
11704 if (thresholds[i] > 0 || thresholds[i] <= prev)
11705 return -EINVAL;
d6dc1a38 11706
4a4b8169
AZ
11707 prev = thresholds[i];
11708 }
d6dc1a38 11709
074ac8df 11710 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11711 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
11712 return -EOPNOTSUPP;
d6dc1a38 11713
4a4b8169
AZ
11714 wdev_lock(wdev);
11715 cfg80211_cqm_config_free(wdev);
11716 wdev_unlock(wdev);
11717
11718 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
11719 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
11720 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
11721
11722 return rdev_set_cqm_rssi_config(rdev, dev,
11723 thresholds[0], hysteresis);
11724 }
11725
11726 if (!wiphy_ext_feature_isset(&rdev->wiphy,
11727 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
11728 return -EOPNOTSUPP;
11729
11730 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
11731 n_thresholds = 0;
11732
11733 wdev_lock(wdev);
11734 if (n_thresholds) {
11735 struct cfg80211_cqm_config *cqm_config;
11736
11737 cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
11738 n_thresholds * sizeof(s32), GFP_KERNEL);
11739 if (!cqm_config) {
11740 err = -ENOMEM;
11741 goto unlock;
11742 }
11743
11744 cqm_config->rssi_hyst = hysteresis;
11745 cqm_config->n_rssi_thresholds = n_thresholds;
11746 memcpy(cqm_config->rssi_thresholds, thresholds,
11747 n_thresholds * sizeof(s32));
11748
11749 wdev->cqm_config = cqm_config;
11750 }
11751
11752 err = cfg80211_cqm_rssi_update(rdev, dev);
11753
11754unlock:
11755 wdev_unlock(wdev);
11756
11757 return err;
d6dc1a38
JO
11758}
11759
11760static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
11761{
11762 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
11763 struct nlattr *cqm;
11764 int err;
11765
11766 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
11767 if (!cqm)
11768 return -EINVAL;
d6dc1a38 11769
8cb08174
JB
11770 err = nla_parse_nested_deprecated(attrs, NL80211_ATTR_CQM_MAX, cqm,
11771 nl80211_attr_cqm_policy,
11772 info->extack);
d6dc1a38 11773 if (err)
1da5fcc8 11774 return err;
d6dc1a38
JO
11775
11776 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
11777 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4a4b8169
AZ
11778 const s32 *thresholds =
11779 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
11780 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
1da5fcc8 11781 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 11782
4a4b8169
AZ
11783 if (len % 4)
11784 return -EINVAL;
11785
11786 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
11787 hysteresis);
1da5fcc8
JB
11788 }
11789
11790 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
11791 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
11792 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
11793 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
11794 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
11795 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
11796
11797 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
11798 }
11799
11800 return -EINVAL;
d6dc1a38
JO
11801}
11802
6e0bd6c3
RL
11803static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
11804{
11805 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11806 struct net_device *dev = info->user_ptr[1];
11807 struct ocb_setup setup = {};
11808 int err;
11809
11810 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
11811 if (err)
11812 return err;
11813
11814 return cfg80211_join_ocb(rdev, dev, &setup);
11815}
11816
11817static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
11818{
11819 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11820 struct net_device *dev = info->user_ptr[1];
11821
11822 return cfg80211_leave_ocb(rdev, dev);
11823}
11824
29cbe68c
JB
11825static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
11826{
11827 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11828 struct net_device *dev = info->user_ptr[1];
11829 struct mesh_config cfg;
c80d545d 11830 struct mesh_setup setup;
29cbe68c
JB
11831 int err;
11832
11833 /* start with default */
11834 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 11835 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 11836
24bdd9f4 11837 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 11838 /* and parse parameters if given */
24bdd9f4 11839 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
11840 if (err)
11841 return err;
11842 }
11843
11844 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
11845 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
11846 return -EINVAL;
11847
c80d545d
JC
11848 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
11849 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
11850
4bb62344
CYY
11851 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
11852 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
11853 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
11854 return -EINVAL;
11855
9bdbf04d
MP
11856 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
11857 setup.beacon_interval =
11858 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 11859
0c317a02
PK
11860 err = cfg80211_validate_beacon_int(rdev,
11861 NL80211_IFTYPE_MESH_POINT,
11862 setup.beacon_interval);
12d20fc9
PK
11863 if (err)
11864 return err;
9bdbf04d
MP
11865 }
11866
11867 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
11868 setup.dtim_period =
11869 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
11870 if (setup.dtim_period < 1 || setup.dtim_period > 100)
11871 return -EINVAL;
11872 }
11873
c80d545d
JC
11874 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
11875 /* parse additional setup parameters if given */
11876 err = nl80211_parse_mesh_setup(info, &setup);
11877 if (err)
11878 return err;
11879 }
11880
d37bb18a
TP
11881 if (setup.user_mpm)
11882 cfg.auto_open_plinks = false;
11883
cc1d2806 11884 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
11885 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
11886 if (err)
11887 return err;
cc1d2806 11888 } else {
188c1b3c 11889 /* __cfg80211_join_mesh() will sort it out */
683b6d3b 11890 setup.chandef.chan = NULL;
cc1d2806
JB
11891 }
11892
ffb3cf30
AN
11893 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
11894 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11895 int n_rates =
11896 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11897 struct ieee80211_supported_band *sband;
11898
11899 if (!setup.chandef.chan)
11900 return -EINVAL;
11901
11902 sband = rdev->wiphy.bands[setup.chandef.chan->band];
11903
11904 err = ieee80211_get_ratemask(sband, rates, n_rates,
11905 &setup.basic_rates);
11906 if (err)
11907 return err;
11908 }
11909
8564e382 11910 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9a5f6488
TC
11911 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
11912 NL80211_ATTR_TX_RATES,
eb89a6a6 11913 &setup.beacon_rate,
857b34c4 11914 dev, false);
8564e382
JB
11915 if (err)
11916 return err;
11917
265698d7
JB
11918 if (!setup.chandef.chan)
11919 return -EINVAL;
11920
8564e382
JB
11921 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
11922 &setup.beacon_rate);
11923 if (err)
11924 return err;
11925 }
11926
d37d49c2
BB
11927 setup.userspace_handles_dfs =
11928 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
11929
1224f583
DK
11930 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
11931 int r = validate_pae_over_nl80211(rdev, info);
11932
11933 if (r < 0)
11934 return r;
11935
11936 setup.control_port_over_nl80211 = true;
11937 }
11938
188c1b3c
DK
11939 wdev_lock(dev->ieee80211_ptr);
11940 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
11941 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
11942 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
11943 wdev_unlock(dev->ieee80211_ptr);
11944
11945 return err;
29cbe68c
JB
11946}
11947
11948static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
11949{
11950 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11951 struct net_device *dev = info->user_ptr[1];
11952
11953 return cfg80211_leave_mesh(rdev, dev);
11954}
11955
dfb89c56 11956#ifdef CONFIG_PM
bb92d199
AK
11957static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
11958 struct cfg80211_registered_device *rdev)
11959{
6abb9cb9 11960 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
11961 struct nlattr *nl_pats, *nl_pat;
11962 int i, pat_len;
11963
6abb9cb9 11964 if (!wowlan->n_patterns)
bb92d199
AK
11965 return 0;
11966
ae0be8de 11967 nl_pats = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
bb92d199
AK
11968 if (!nl_pats)
11969 return -ENOBUFS;
11970
6abb9cb9 11971 for (i = 0; i < wowlan->n_patterns; i++) {
ae0be8de 11972 nl_pat = nla_nest_start_noflag(msg, i + 1);
bb92d199
AK
11973 if (!nl_pat)
11974 return -ENOBUFS;
6abb9cb9 11975 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 11976 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 11977 wowlan->patterns[i].mask) ||
50ac6607
AK
11978 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
11979 wowlan->patterns[i].pattern) ||
11980 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 11981 wowlan->patterns[i].pkt_offset))
bb92d199
AK
11982 return -ENOBUFS;
11983 nla_nest_end(msg, nl_pat);
11984 }
11985 nla_nest_end(msg, nl_pats);
11986
11987 return 0;
11988}
11989
2a0e047e
JB
11990static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
11991 struct cfg80211_wowlan_tcp *tcp)
11992{
11993 struct nlattr *nl_tcp;
11994
11995 if (!tcp)
11996 return 0;
11997
ae0be8de
MK
11998 nl_tcp = nla_nest_start_noflag(msg,
11999 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
2a0e047e
JB
12000 if (!nl_tcp)
12001 return -ENOBUFS;
12002
930345ea
JB
12003 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
12004 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
12005 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
12006 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
12007 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
12008 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
12009 tcp->payload_len, tcp->payload) ||
12010 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
12011 tcp->data_interval) ||
12012 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
12013 tcp->wake_len, tcp->wake_data) ||
12014 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
12015 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
12016 return -ENOBUFS;
12017
12018 if (tcp->payload_seq.len &&
12019 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
12020 sizeof(tcp->payload_seq), &tcp->payload_seq))
12021 return -ENOBUFS;
12022
12023 if (tcp->payload_tok.len &&
12024 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
12025 sizeof(tcp->payload_tok) + tcp->tokens_size,
12026 &tcp->payload_tok))
12027 return -ENOBUFS;
12028
e248ad30
JB
12029 nla_nest_end(msg, nl_tcp);
12030
2a0e047e
JB
12031 return 0;
12032}
12033
75453ccb
LC
12034static int nl80211_send_wowlan_nd(struct sk_buff *msg,
12035 struct cfg80211_sched_scan_request *req)
12036{
3b06d277 12037 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
12038 int i;
12039
12040 if (!req)
12041 return 0;
12042
ae0be8de 12043 nd = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
75453ccb
LC
12044 if (!nd)
12045 return -ENOBUFS;
12046
3b06d277
AS
12047 if (req->n_scan_plans == 1 &&
12048 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
12049 req->scan_plans[0].interval * 1000))
75453ccb
LC
12050 return -ENOBUFS;
12051
21fea567
LC
12052 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
12053 return -ENOBUFS;
12054
bf95ecdb 12055 if (req->relative_rssi_set) {
12056 struct nl80211_bss_select_rssi_adjust rssi_adjust;
12057
12058 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
12059 req->relative_rssi))
12060 return -ENOBUFS;
12061
12062 rssi_adjust.band = req->rssi_adjust.band;
12063 rssi_adjust.delta = req->rssi_adjust.delta;
12064 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
12065 sizeof(rssi_adjust), &rssi_adjust))
12066 return -ENOBUFS;
12067 }
12068
ae0be8de 12069 freqs = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
75453ccb
LC
12070 if (!freqs)
12071 return -ENOBUFS;
12072
53b18980
JB
12073 for (i = 0; i < req->n_channels; i++) {
12074 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
12075 return -ENOBUFS;
12076 }
75453ccb
LC
12077
12078 nla_nest_end(msg, freqs);
12079
12080 if (req->n_match_sets) {
ae0be8de
MK
12081 matches = nla_nest_start_noflag(msg,
12082 NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
12083 if (!matches)
12084 return -ENOBUFS;
12085
75453ccb 12086 for (i = 0; i < req->n_match_sets; i++) {
ae0be8de 12087 match = nla_nest_start_noflag(msg, i);
76e1fb4b
JB
12088 if (!match)
12089 return -ENOBUFS;
12090
53b18980
JB
12091 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
12092 req->match_sets[i].ssid.ssid_len,
12093 req->match_sets[i].ssid.ssid))
12094 return -ENOBUFS;
75453ccb
LC
12095 nla_nest_end(msg, match);
12096 }
12097 nla_nest_end(msg, matches);
12098 }
12099
ae0be8de 12100 scan_plans = nla_nest_start_noflag(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
3b06d277
AS
12101 if (!scan_plans)
12102 return -ENOBUFS;
12103
12104 for (i = 0; i < req->n_scan_plans; i++) {
ae0be8de 12105 scan_plan = nla_nest_start_noflag(msg, i + 1);
76e1fb4b
JB
12106 if (!scan_plan)
12107 return -ENOBUFS;
12108
67626964 12109 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
3b06d277
AS
12110 req->scan_plans[i].interval) ||
12111 (req->scan_plans[i].iterations &&
12112 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
12113 req->scan_plans[i].iterations)))
12114 return -ENOBUFS;
12115 nla_nest_end(msg, scan_plan);
12116 }
12117 nla_nest_end(msg, scan_plans);
12118
75453ccb
LC
12119 nla_nest_end(msg, nd);
12120
12121 return 0;
12122}
12123
ff1b6e69
JB
12124static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
12125{
12126 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12127 struct sk_buff *msg;
12128 void *hdr;
2a0e047e 12129 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 12130
964dc9e2 12131 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
12132 return -EOPNOTSUPP;
12133
6abb9cb9 12134 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 12135 /* adjust size to have room for all the data */
6abb9cb9
JB
12136 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
12137 rdev->wiphy.wowlan_config->tcp->payload_len +
12138 rdev->wiphy.wowlan_config->tcp->wake_len +
12139 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
12140 }
12141
12142 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
12143 if (!msg)
12144 return -ENOMEM;
12145
15e47304 12146 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
12147 NL80211_CMD_GET_WOWLAN);
12148 if (!hdr)
12149 goto nla_put_failure;
12150
6abb9cb9 12151 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
12152 struct nlattr *nl_wowlan;
12153
ae0be8de
MK
12154 nl_wowlan = nla_nest_start_noflag(msg,
12155 NL80211_ATTR_WOWLAN_TRIGGERS);
ff1b6e69
JB
12156 if (!nl_wowlan)
12157 goto nla_put_failure;
12158
6abb9cb9 12159 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 12160 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 12161 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 12162 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 12163 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 12164 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 12165 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 12166 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 12167 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 12168 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 12169 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 12170 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 12171 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
12172 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
12173 goto nla_put_failure;
2a0e047e 12174
bb92d199
AK
12175 if (nl80211_send_wowlan_patterns(msg, rdev))
12176 goto nla_put_failure;
2a0e047e 12177
6abb9cb9
JB
12178 if (nl80211_send_wowlan_tcp(msg,
12179 rdev->wiphy.wowlan_config->tcp))
2a0e047e 12180 goto nla_put_failure;
75453ccb
LC
12181
12182 if (nl80211_send_wowlan_nd(
12183 msg,
12184 rdev->wiphy.wowlan_config->nd_config))
12185 goto nla_put_failure;
2a0e047e 12186
ff1b6e69
JB
12187 nla_nest_end(msg, nl_wowlan);
12188 }
12189
12190 genlmsg_end(msg, hdr);
12191 return genlmsg_reply(msg, info);
12192
12193nla_put_failure:
12194 nlmsg_free(msg);
12195 return -ENOBUFS;
12196}
12197
2a0e047e
JB
12198static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
12199 struct nlattr *attr,
12200 struct cfg80211_wowlan *trig)
12201{
12202 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
12203 struct cfg80211_wowlan_tcp *cfg;
12204 struct nl80211_wowlan_tcp_data_token *tok = NULL;
12205 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
12206 u32 size;
12207 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
12208 int err, port;
12209
964dc9e2 12210 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
12211 return -EINVAL;
12212
8cb08174
JB
12213 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TCP, attr,
12214 nl80211_wowlan_tcp_policy, NULL);
2a0e047e
JB
12215 if (err)
12216 return err;
12217
12218 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
12219 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
12220 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
12221 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
12222 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
12223 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
12224 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
12225 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
12226 return -EINVAL;
12227
12228 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 12229 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
12230 return -EINVAL;
12231
12232 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 12233 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 12234 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
12235 return -EINVAL;
12236
12237 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 12238 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
12239 return -EINVAL;
12240
12241 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
12242 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
12243 return -EINVAL;
12244
12245 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
12246 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
12247
12248 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
12249 tokens_size = tokln - sizeof(*tok);
12250
12251 if (!tok->len || tokens_size % tok->len)
12252 return -EINVAL;
964dc9e2 12253 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 12254 return -EINVAL;
964dc9e2 12255 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 12256 return -EINVAL;
964dc9e2 12257 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 12258 return -EINVAL;
964dc9e2 12259 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
12260 return -EINVAL;
12261 if (tok->offset + tok->len > data_size)
12262 return -EINVAL;
12263 }
12264
12265 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
12266 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 12267 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
12268 return -EINVAL;
12269 if (seq->len == 0 || seq->len > 4)
12270 return -EINVAL;
12271 if (seq->len + seq->offset > data_size)
12272 return -EINVAL;
12273 }
12274
12275 size = sizeof(*cfg);
12276 size += data_size;
12277 size += wake_size + wake_mask_size;
12278 size += tokens_size;
12279
12280 cfg = kzalloc(size, GFP_KERNEL);
12281 if (!cfg)
12282 return -ENOMEM;
67b61f6c
JB
12283 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
12284 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
12285 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
12286 ETH_ALEN);
12287 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
12288 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
12289 else
12290 port = 0;
12291#ifdef CONFIG_INET
12292 /* allocate a socket and port for it and use it */
12293 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
12294 IPPROTO_TCP, &cfg->sock, 1);
12295 if (err) {
12296 kfree(cfg);
12297 return err;
12298 }
12299 if (inet_csk_get_port(cfg->sock->sk, port)) {
12300 sock_release(cfg->sock);
12301 kfree(cfg);
12302 return -EADDRINUSE;
12303 }
12304 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
12305#else
12306 if (!port) {
12307 kfree(cfg);
12308 return -EINVAL;
12309 }
12310 cfg->src_port = port;
12311#endif
12312
12313 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
12314 cfg->payload_len = data_size;
12315 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
12316 memcpy((void *)cfg->payload,
12317 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
12318 data_size);
12319 if (seq)
12320 cfg->payload_seq = *seq;
12321 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
12322 cfg->wake_len = wake_size;
12323 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
12324 memcpy((void *)cfg->wake_data,
12325 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
12326 wake_size);
12327 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
12328 data_size + wake_size;
12329 memcpy((void *)cfg->wake_mask,
12330 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
12331 wake_mask_size);
12332 if (tok) {
12333 cfg->tokens_size = tokens_size;
12334 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
12335 }
12336
12337 trig->tcp = cfg;
12338
12339 return 0;
12340}
12341
8cd4d456
LC
12342static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
12343 const struct wiphy_wowlan_support *wowlan,
12344 struct nlattr *attr,
12345 struct cfg80211_wowlan *trig)
12346{
12347 struct nlattr **tb;
12348 int err;
12349
6396bb22 12350 tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
8cd4d456
LC
12351 if (!tb)
12352 return -ENOMEM;
12353
12354 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
12355 err = -EOPNOTSUPP;
12356 goto out;
12357 }
12358
8cb08174
JB
12359 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_MAX, attr,
12360 nl80211_policy, NULL);
8cd4d456
LC
12361 if (err)
12362 goto out;
12363
aad1e812
AVS
12364 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
12365 wowlan->max_nd_match_sets);
8cd4d456
LC
12366 err = PTR_ERR_OR_ZERO(trig->nd_config);
12367 if (err)
12368 trig->nd_config = NULL;
12369
12370out:
12371 kfree(tb);
12372 return err;
12373}
12374
ff1b6e69
JB
12375static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
12376{
12377 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12378 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 12379 struct cfg80211_wowlan new_triggers = {};
ae33bd81 12380 struct cfg80211_wowlan *ntrig;
964dc9e2 12381 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 12382 int err, i;
6abb9cb9 12383 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 12384 bool regular = false;
ff1b6e69 12385
964dc9e2 12386 if (!wowlan)
ff1b6e69
JB
12387 return -EOPNOTSUPP;
12388
ae33bd81
JB
12389 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
12390 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 12391 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
12392 goto set_wakeup;
12393 }
ff1b6e69 12394
8cb08174
JB
12395 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TRIG,
12396 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
12397 nl80211_wowlan_policy, info->extack);
ff1b6e69
JB
12398 if (err)
12399 return err;
12400
12401 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
12402 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
12403 return -EINVAL;
12404 new_triggers.any = true;
12405 }
12406
12407 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
12408 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
12409 return -EINVAL;
12410 new_triggers.disconnect = true;
98fc4386 12411 regular = true;
ff1b6e69
JB
12412 }
12413
12414 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
12415 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
12416 return -EINVAL;
12417 new_triggers.magic_pkt = true;
98fc4386 12418 regular = true;
ff1b6e69
JB
12419 }
12420
77dbbb13
JB
12421 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
12422 return -EINVAL;
12423
12424 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
12425 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
12426 return -EINVAL;
12427 new_triggers.gtk_rekey_failure = true;
98fc4386 12428 regular = true;
77dbbb13
JB
12429 }
12430
12431 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
12432 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
12433 return -EINVAL;
12434 new_triggers.eap_identity_req = true;
98fc4386 12435 regular = true;
77dbbb13
JB
12436 }
12437
12438 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
12439 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
12440 return -EINVAL;
12441 new_triggers.four_way_handshake = true;
98fc4386 12442 regular = true;
77dbbb13
JB
12443 }
12444
12445 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
12446 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
12447 return -EINVAL;
12448 new_triggers.rfkill_release = true;
98fc4386 12449 regular = true;
77dbbb13
JB
12450 }
12451
ff1b6e69
JB
12452 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
12453 struct nlattr *pat;
12454 int n_patterns = 0;
bb92d199 12455 int rem, pat_len, mask_len, pkt_offset;
50ac6607 12456 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 12457
98fc4386
JB
12458 regular = true;
12459
ff1b6e69
JB
12460 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
12461 rem)
12462 n_patterns++;
12463 if (n_patterns > wowlan->n_patterns)
12464 return -EINVAL;
12465
12466 new_triggers.patterns = kcalloc(n_patterns,
12467 sizeof(new_triggers.patterns[0]),
12468 GFP_KERNEL);
12469 if (!new_triggers.patterns)
12470 return -ENOMEM;
12471
12472 new_triggers.n_patterns = n_patterns;
12473 i = 0;
12474
12475 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
12476 rem) {
922bd80f
JB
12477 u8 *mask_pat;
12478
8cb08174
JB
12479 err = nla_parse_nested_deprecated(pat_tb,
12480 MAX_NL80211_PKTPAT,
12481 pat,
12482 nl80211_packet_pattern_policy,
12483 info->extack);
95bca62f
JB
12484 if (err)
12485 goto error;
12486
ff1b6e69 12487 err = -EINVAL;
50ac6607
AK
12488 if (!pat_tb[NL80211_PKTPAT_MASK] ||
12489 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 12490 goto error;
50ac6607 12491 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 12492 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 12493 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
12494 goto error;
12495 if (pat_len > wowlan->pattern_max_len ||
12496 pat_len < wowlan->pattern_min_len)
12497 goto error;
12498
50ac6607 12499 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
12500 pkt_offset = 0;
12501 else
12502 pkt_offset = nla_get_u32(
50ac6607 12503 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
12504 if (pkt_offset > wowlan->max_pkt_offset)
12505 goto error;
12506 new_triggers.patterns[i].pkt_offset = pkt_offset;
12507
922bd80f
JB
12508 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
12509 if (!mask_pat) {
ff1b6e69
JB
12510 err = -ENOMEM;
12511 goto error;
12512 }
922bd80f
JB
12513 new_triggers.patterns[i].mask = mask_pat;
12514 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 12515 mask_len);
922bd80f
JB
12516 mask_pat += mask_len;
12517 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 12518 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 12519 memcpy(mask_pat,
50ac6607 12520 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
12521 pat_len);
12522 i++;
12523 }
12524 }
12525
2a0e047e 12526 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 12527 regular = true;
2a0e047e
JB
12528 err = nl80211_parse_wowlan_tcp(
12529 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
12530 &new_triggers);
12531 if (err)
12532 goto error;
12533 }
12534
8cd4d456 12535 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 12536 regular = true;
8cd4d456
LC
12537 err = nl80211_parse_wowlan_nd(
12538 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
12539 &new_triggers);
12540 if (err)
12541 goto error;
12542 }
12543
98fc4386
JB
12544 /* The 'any' trigger means the device continues operating more or less
12545 * as in its normal operation mode and wakes up the host on most of the
12546 * normal interrupts (like packet RX, ...)
12547 * It therefore makes little sense to combine with the more constrained
12548 * wakeup trigger modes.
12549 */
12550 if (new_triggers.any && regular) {
12551 err = -EINVAL;
12552 goto error;
12553 }
12554
ae33bd81
JB
12555 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
12556 if (!ntrig) {
12557 err = -ENOMEM;
12558 goto error;
ff1b6e69 12559 }
ae33bd81 12560 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 12561 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 12562
ae33bd81 12563 set_wakeup:
6abb9cb9
JB
12564 if (rdev->ops->set_wakeup &&
12565 prev_enabled != !!rdev->wiphy.wowlan_config)
12566 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 12567
ff1b6e69
JB
12568 return 0;
12569 error:
12570 for (i = 0; i < new_triggers.n_patterns; i++)
12571 kfree(new_triggers.patterns[i].mask);
12572 kfree(new_triggers.patterns);
2a0e047e
JB
12573 if (new_triggers.tcp && new_triggers.tcp->sock)
12574 sock_release(new_triggers.tcp->sock);
12575 kfree(new_triggers.tcp);
e5dbe070 12576 kfree(new_triggers.nd_config);
ff1b6e69
JB
12577 return err;
12578}
dfb89c56 12579#endif
ff1b6e69 12580
be29b99a
AK
12581static int nl80211_send_coalesce_rules(struct sk_buff *msg,
12582 struct cfg80211_registered_device *rdev)
12583{
12584 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
12585 int i, j, pat_len;
12586 struct cfg80211_coalesce_rules *rule;
12587
12588 if (!rdev->coalesce->n_rules)
12589 return 0;
12590
ae0be8de 12591 nl_rules = nla_nest_start_noflag(msg, NL80211_ATTR_COALESCE_RULE);
be29b99a
AK
12592 if (!nl_rules)
12593 return -ENOBUFS;
12594
12595 for (i = 0; i < rdev->coalesce->n_rules; i++) {
ae0be8de 12596 nl_rule = nla_nest_start_noflag(msg, i + 1);
be29b99a
AK
12597 if (!nl_rule)
12598 return -ENOBUFS;
12599
12600 rule = &rdev->coalesce->rules[i];
12601 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
12602 rule->delay))
12603 return -ENOBUFS;
12604
12605 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
12606 rule->condition))
12607 return -ENOBUFS;
12608
ae0be8de
MK
12609 nl_pats = nla_nest_start_noflag(msg,
12610 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
be29b99a
AK
12611 if (!nl_pats)
12612 return -ENOBUFS;
12613
12614 for (j = 0; j < rule->n_patterns; j++) {
ae0be8de 12615 nl_pat = nla_nest_start_noflag(msg, j + 1);
be29b99a
AK
12616 if (!nl_pat)
12617 return -ENOBUFS;
12618 pat_len = rule->patterns[j].pattern_len;
12619 if (nla_put(msg, NL80211_PKTPAT_MASK,
12620 DIV_ROUND_UP(pat_len, 8),
12621 rule->patterns[j].mask) ||
12622 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
12623 rule->patterns[j].pattern) ||
12624 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
12625 rule->patterns[j].pkt_offset))
12626 return -ENOBUFS;
12627 nla_nest_end(msg, nl_pat);
12628 }
12629 nla_nest_end(msg, nl_pats);
12630 nla_nest_end(msg, nl_rule);
12631 }
12632 nla_nest_end(msg, nl_rules);
12633
12634 return 0;
12635}
12636
12637static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
12638{
12639 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12640 struct sk_buff *msg;
12641 void *hdr;
12642
12643 if (!rdev->wiphy.coalesce)
12644 return -EOPNOTSUPP;
12645
12646 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12647 if (!msg)
12648 return -ENOMEM;
12649
12650 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12651 NL80211_CMD_GET_COALESCE);
12652 if (!hdr)
12653 goto nla_put_failure;
12654
12655 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
12656 goto nla_put_failure;
12657
12658 genlmsg_end(msg, hdr);
12659 return genlmsg_reply(msg, info);
12660
12661nla_put_failure:
12662 nlmsg_free(msg);
12663 return -ENOBUFS;
12664}
12665
12666void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
12667{
12668 struct cfg80211_coalesce *coalesce = rdev->coalesce;
12669 int i, j;
12670 struct cfg80211_coalesce_rules *rule;
12671
12672 if (!coalesce)
12673 return;
12674
12675 for (i = 0; i < coalesce->n_rules; i++) {
12676 rule = &coalesce->rules[i];
12677 for (j = 0; j < rule->n_patterns; j++)
12678 kfree(rule->patterns[j].mask);
12679 kfree(rule->patterns);
12680 }
12681 kfree(coalesce->rules);
12682 kfree(coalesce);
12683 rdev->coalesce = NULL;
12684}
12685
12686static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
12687 struct nlattr *rule,
12688 struct cfg80211_coalesce_rules *new_rule)
12689{
12690 int err, i;
12691 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
12692 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
12693 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
12694 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
12695
8cb08174
JB
12696 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_COALESCE_RULE_MAX,
12697 rule, nl80211_coalesce_policy, NULL);
be29b99a
AK
12698 if (err)
12699 return err;
12700
12701 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
12702 new_rule->delay =
12703 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
12704 if (new_rule->delay > coalesce->max_delay)
12705 return -EINVAL;
12706
12707 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
12708 new_rule->condition =
12709 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
be29b99a
AK
12710
12711 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
12712 return -EINVAL;
12713
12714 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
12715 rem)
12716 n_patterns++;
12717 if (n_patterns > coalesce->n_patterns)
12718 return -EINVAL;
12719
12720 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
12721 GFP_KERNEL);
12722 if (!new_rule->patterns)
12723 return -ENOMEM;
12724
12725 new_rule->n_patterns = n_patterns;
12726 i = 0;
12727
12728 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
12729 rem) {
922bd80f
JB
12730 u8 *mask_pat;
12731
8cb08174
JB
12732 err = nla_parse_nested_deprecated(pat_tb, MAX_NL80211_PKTPAT,
12733 pat,
12734 nl80211_packet_pattern_policy,
12735 NULL);
95bca62f
JB
12736 if (err)
12737 return err;
12738
be29b99a
AK
12739 if (!pat_tb[NL80211_PKTPAT_MASK] ||
12740 !pat_tb[NL80211_PKTPAT_PATTERN])
12741 return -EINVAL;
12742 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
12743 mask_len = DIV_ROUND_UP(pat_len, 8);
12744 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
12745 return -EINVAL;
12746 if (pat_len > coalesce->pattern_max_len ||
12747 pat_len < coalesce->pattern_min_len)
12748 return -EINVAL;
12749
12750 if (!pat_tb[NL80211_PKTPAT_OFFSET])
12751 pkt_offset = 0;
12752 else
12753 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
12754 if (pkt_offset > coalesce->max_pkt_offset)
12755 return -EINVAL;
12756 new_rule->patterns[i].pkt_offset = pkt_offset;
12757
922bd80f
JB
12758 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
12759 if (!mask_pat)
be29b99a 12760 return -ENOMEM;
922bd80f
JB
12761
12762 new_rule->patterns[i].mask = mask_pat;
12763 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
12764 mask_len);
12765
12766 mask_pat += mask_len;
12767 new_rule->patterns[i].pattern = mask_pat;
be29b99a 12768 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
12769 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
12770 pat_len);
be29b99a
AK
12771 i++;
12772 }
12773
12774 return 0;
12775}
12776
12777static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
12778{
12779 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12780 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
12781 struct cfg80211_coalesce new_coalesce = {};
12782 struct cfg80211_coalesce *n_coalesce;
12783 int err, rem_rule, n_rules = 0, i, j;
12784 struct nlattr *rule;
12785 struct cfg80211_coalesce_rules *tmp_rule;
12786
12787 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
12788 return -EOPNOTSUPP;
12789
12790 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
12791 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 12792 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
12793 return 0;
12794 }
12795
12796 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
12797 rem_rule)
12798 n_rules++;
12799 if (n_rules > coalesce->n_rules)
12800 return -EINVAL;
12801
12802 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
12803 GFP_KERNEL);
12804 if (!new_coalesce.rules)
12805 return -ENOMEM;
12806
12807 new_coalesce.n_rules = n_rules;
12808 i = 0;
12809
12810 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
12811 rem_rule) {
12812 err = nl80211_parse_coalesce_rule(rdev, rule,
12813 &new_coalesce.rules[i]);
12814 if (err)
12815 goto error;
12816
12817 i++;
12818 }
12819
a1056b1b 12820 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
12821 if (err)
12822 goto error;
12823
12824 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
12825 if (!n_coalesce) {
12826 err = -ENOMEM;
12827 goto error;
12828 }
12829 cfg80211_rdev_free_coalesce(rdev);
12830 rdev->coalesce = n_coalesce;
12831
12832 return 0;
12833error:
12834 for (i = 0; i < new_coalesce.n_rules; i++) {
12835 tmp_rule = &new_coalesce.rules[i];
12836 for (j = 0; j < tmp_rule->n_patterns; j++)
12837 kfree(tmp_rule->patterns[j].mask);
12838 kfree(tmp_rule->patterns);
12839 }
12840 kfree(new_coalesce.rules);
12841
12842 return err;
12843}
12844
e5497d76
JB
12845static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
12846{
12847 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12848 struct net_device *dev = info->user_ptr[1];
12849 struct wireless_dev *wdev = dev->ieee80211_ptr;
12850 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
f495acd8 12851 struct cfg80211_gtk_rekey_data rekey_data = {};
e5497d76
JB
12852 int err;
12853
12854 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
12855 return -EINVAL;
12856
8cb08174
JB
12857 err = nla_parse_nested_deprecated(tb, MAX_NL80211_REKEY_DATA,
12858 info->attrs[NL80211_ATTR_REKEY_DATA],
12859 nl80211_rekey_policy, info->extack);
e5497d76
JB
12860 if (err)
12861 return err;
12862
e785fa0a
VD
12863 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
12864 !tb[NL80211_REKEY_DATA_KCK])
12865 return -EINVAL;
093a48d2
NE
12866 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
12867 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
12868 nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
e5497d76 12869 return -ERANGE;
093a48d2
NE
12870 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
12871 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
12872 nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
e5497d76
JB
12873 return -ERANGE;
12874
78f686ca
JB
12875 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
12876 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
12877 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
093a48d2
NE
12878 rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
12879 rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]);
12880 if (tb[NL80211_REKEY_DATA_AKM])
12881 rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
e5497d76
JB
12882
12883 wdev_lock(wdev);
12884 if (!wdev->current_bss) {
12885 err = -ENOTCONN;
12886 goto out;
12887 }
12888
12889 if (!rdev->ops->set_rekey_data) {
12890 err = -EOPNOTSUPP;
12891 goto out;
12892 }
12893
e35e4d28 12894 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
12895 out:
12896 wdev_unlock(wdev);
12897 return err;
12898}
12899
28946da7
JB
12900static int nl80211_register_unexpected_frame(struct sk_buff *skb,
12901 struct genl_info *info)
12902{
12903 struct net_device *dev = info->user_ptr[1];
12904 struct wireless_dev *wdev = dev->ieee80211_ptr;
12905
12906 if (wdev->iftype != NL80211_IFTYPE_AP &&
12907 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12908 return -EINVAL;
12909
15e47304 12910 if (wdev->ap_unexpected_nlportid)
28946da7
JB
12911 return -EBUSY;
12912
15e47304 12913 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
12914 return 0;
12915}
12916
7f6cf311
JB
12917static int nl80211_probe_client(struct sk_buff *skb,
12918 struct genl_info *info)
12919{
12920 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12921 struct net_device *dev = info->user_ptr[1];
12922 struct wireless_dev *wdev = dev->ieee80211_ptr;
12923 struct sk_buff *msg;
12924 void *hdr;
12925 const u8 *addr;
12926 u64 cookie;
12927 int err;
12928
12929 if (wdev->iftype != NL80211_IFTYPE_AP &&
12930 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12931 return -EOPNOTSUPP;
12932
12933 if (!info->attrs[NL80211_ATTR_MAC])
12934 return -EINVAL;
12935
12936 if (!rdev->ops->probe_client)
12937 return -EOPNOTSUPP;
12938
12939 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12940 if (!msg)
12941 return -ENOMEM;
12942
15e47304 12943 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 12944 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
12945 if (!hdr) {
12946 err = -ENOBUFS;
7f6cf311
JB
12947 goto free_msg;
12948 }
12949
12950 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12951
e35e4d28 12952 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
12953 if (err)
12954 goto free_msg;
12955
2dad624e
ND
12956 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12957 NL80211_ATTR_PAD))
9360ffd1 12958 goto nla_put_failure;
7f6cf311
JB
12959
12960 genlmsg_end(msg, hdr);
12961
12962 return genlmsg_reply(msg, info);
12963
12964 nla_put_failure:
12965 err = -ENOBUFS;
12966 free_msg:
12967 nlmsg_free(msg);
12968 return err;
12969}
12970
5e760230
JB
12971static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
12972{
12973 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
12974 struct cfg80211_beacon_registration *reg, *nreg;
12975 int rv;
5e760230
JB
12976
12977 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
12978 return -EOPNOTSUPP;
12979
37c73b5f
BG
12980 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
12981 if (!nreg)
12982 return -ENOMEM;
12983
12984 /* First, check if already registered. */
12985 spin_lock_bh(&rdev->beacon_registrations_lock);
12986 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
12987 if (reg->nlportid == info->snd_portid) {
12988 rv = -EALREADY;
12989 goto out_err;
12990 }
12991 }
12992 /* Add it to the list */
12993 nreg->nlportid = info->snd_portid;
12994 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 12995
37c73b5f 12996 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
12997
12998 return 0;
37c73b5f
BG
12999out_err:
13000 spin_unlock_bh(&rdev->beacon_registrations_lock);
13001 kfree(nreg);
13002 return rv;
5e760230
JB
13003}
13004
98104fde
JB
13005static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
13006{
13007 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13008 struct wireless_dev *wdev = info->user_ptr[1];
13009 int err;
13010
13011 if (!rdev->ops->start_p2p_device)
13012 return -EOPNOTSUPP;
13013
13014 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
13015 return -EOPNOTSUPP;
13016
73c7da3d 13017 if (wdev_running(wdev))
98104fde
JB
13018 return 0;
13019
b6a55015
LC
13020 if (rfkill_blocked(rdev->rfkill))
13021 return -ERFKILL;
98104fde 13022
eeb126e9 13023 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
13024 if (err)
13025 return err;
13026
73c7da3d 13027 wdev->is_running = true;
98104fde 13028 rdev->opencount++;
98104fde
JB
13029
13030 return 0;
13031}
13032
13033static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
13034{
13035 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13036 struct wireless_dev *wdev = info->user_ptr[1];
13037
13038 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
13039 return -EOPNOTSUPP;
13040
13041 if (!rdev->ops->stop_p2p_device)
13042 return -EOPNOTSUPP;
13043
f9f47529 13044 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
13045
13046 return 0;
13047}
13048
cb3b7d87
AB
13049static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
13050{
13051 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13052 struct wireless_dev *wdev = info->user_ptr[1];
13053 struct cfg80211_nan_conf conf = {};
13054 int err;
13055
13056 if (wdev->iftype != NL80211_IFTYPE_NAN)
13057 return -EOPNOTSUPP;
13058
eeb04a96 13059 if (wdev_running(wdev))
cb3b7d87
AB
13060 return -EEXIST;
13061
13062 if (rfkill_blocked(rdev->rfkill))
13063 return -ERFKILL;
13064
13065 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
13066 return -EINVAL;
13067
cb3b7d87
AB
13068 conf.master_pref =
13069 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
cb3b7d87 13070
8585989d
LC
13071 if (info->attrs[NL80211_ATTR_BANDS]) {
13072 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
13073
13074 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
13075 return -EOPNOTSUPP;
13076
13077 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
13078 return -EINVAL;
13079
13080 conf.bands = bands;
13081 }
cb3b7d87
AB
13082
13083 err = rdev_start_nan(rdev, wdev, &conf);
13084 if (err)
13085 return err;
13086
73c7da3d 13087 wdev->is_running = true;
cb3b7d87
AB
13088 rdev->opencount++;
13089
13090 return 0;
13091}
13092
13093static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
13094{
13095 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13096 struct wireless_dev *wdev = info->user_ptr[1];
13097
13098 if (wdev->iftype != NL80211_IFTYPE_NAN)
13099 return -EOPNOTSUPP;
13100
13101 cfg80211_stop_nan(rdev, wdev);
13102
13103 return 0;
13104}
13105
a442b761
AB
13106static int validate_nan_filter(struct nlattr *filter_attr)
13107{
13108 struct nlattr *attr;
13109 int len = 0, n_entries = 0, rem;
13110
13111 nla_for_each_nested(attr, filter_attr, rem) {
13112 len += nla_len(attr);
13113 n_entries++;
13114 }
13115
13116 if (len >= U8_MAX)
13117 return -EINVAL;
13118
13119 return n_entries;
13120}
13121
13122static int handle_nan_filter(struct nlattr *attr_filter,
13123 struct cfg80211_nan_func *func,
13124 bool tx)
13125{
13126 struct nlattr *attr;
13127 int n_entries, rem, i;
13128 struct cfg80211_nan_func_filter *filter;
13129
13130 n_entries = validate_nan_filter(attr_filter);
13131 if (n_entries < 0)
13132 return n_entries;
13133
13134 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
13135
13136 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
13137 if (!filter)
13138 return -ENOMEM;
13139
13140 i = 0;
13141 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 13142 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
a442b761
AB
13143 filter[i].len = nla_len(attr);
13144 i++;
13145 }
13146 if (tx) {
13147 func->num_tx_filters = n_entries;
13148 func->tx_filters = filter;
13149 } else {
13150 func->num_rx_filters = n_entries;
13151 func->rx_filters = filter;
13152 }
13153
13154 return 0;
13155}
13156
13157static int nl80211_nan_add_func(struct sk_buff *skb,
13158 struct genl_info *info)
13159{
13160 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13161 struct wireless_dev *wdev = info->user_ptr[1];
13162 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
13163 struct cfg80211_nan_func *func;
13164 struct sk_buff *msg = NULL;
13165 void *hdr = NULL;
13166 int err = 0;
13167
13168 if (wdev->iftype != NL80211_IFTYPE_NAN)
13169 return -EOPNOTSUPP;
13170
73c7da3d 13171 if (!wdev_running(wdev))
a442b761
AB
13172 return -ENOTCONN;
13173
13174 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
13175 return -EINVAL;
13176
8cb08174
JB
13177 err = nla_parse_nested_deprecated(tb, NL80211_NAN_FUNC_ATTR_MAX,
13178 info->attrs[NL80211_ATTR_NAN_FUNC],
13179 nl80211_nan_func_policy,
13180 info->extack);
a442b761
AB
13181 if (err)
13182 return err;
13183
13184 func = kzalloc(sizeof(*func), GFP_KERNEL);
13185 if (!func)
13186 return -ENOMEM;
13187
b60ad348 13188 func->cookie = cfg80211_assign_cookie(rdev);
a442b761 13189
cb9abd48 13190 if (!tb[NL80211_NAN_FUNC_TYPE]) {
a442b761
AB
13191 err = -EINVAL;
13192 goto out;
13193 }
13194
13195
13196 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
13197
13198 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
13199 err = -EINVAL;
13200 goto out;
13201 }
13202
13203 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
13204 sizeof(func->service_id));
13205
13206 func->close_range =
13207 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
13208
13209 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
13210 func->serv_spec_info_len =
13211 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
13212 func->serv_spec_info =
13213 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
13214 func->serv_spec_info_len,
13215 GFP_KERNEL);
13216 if (!func->serv_spec_info) {
13217 err = -ENOMEM;
13218 goto out;
13219 }
13220 }
13221
13222 if (tb[NL80211_NAN_FUNC_TTL])
13223 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
13224
13225 switch (func->type) {
13226 case NL80211_NAN_FUNC_PUBLISH:
13227 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
13228 err = -EINVAL;
13229 goto out;
13230 }
13231
13232 func->publish_type =
13233 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
13234 func->publish_bcast =
13235 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
13236
13237 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
13238 func->publish_bcast) {
13239 err = -EINVAL;
13240 goto out;
13241 }
13242 break;
13243 case NL80211_NAN_FUNC_SUBSCRIBE:
13244 func->subscribe_active =
13245 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
13246 break;
13247 case NL80211_NAN_FUNC_FOLLOW_UP:
13248 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
3ea15452
HC
13249 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
13250 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
a442b761
AB
13251 err = -EINVAL;
13252 goto out;
13253 }
13254
13255 func->followup_id =
13256 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
13257 func->followup_reqid =
13258 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
13259 memcpy(func->followup_dest.addr,
13260 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
13261 sizeof(func->followup_dest.addr));
13262 if (func->ttl) {
13263 err = -EINVAL;
13264 goto out;
13265 }
13266 break;
13267 default:
13268 err = -EINVAL;
13269 goto out;
13270 }
13271
13272 if (tb[NL80211_NAN_FUNC_SRF]) {
13273 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
13274
8cb08174
JB
13275 err = nla_parse_nested_deprecated(srf_tb,
13276 NL80211_NAN_SRF_ATTR_MAX,
13277 tb[NL80211_NAN_FUNC_SRF],
13278 nl80211_nan_srf_policy,
13279 info->extack);
a442b761
AB
13280 if (err)
13281 goto out;
13282
13283 func->srf_include =
13284 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
13285
13286 if (srf_tb[NL80211_NAN_SRF_BF]) {
13287 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
13288 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
13289 err = -EINVAL;
13290 goto out;
13291 }
13292
13293 func->srf_bf_len =
13294 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
13295 func->srf_bf =
13296 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
13297 func->srf_bf_len, GFP_KERNEL);
13298 if (!func->srf_bf) {
13299 err = -ENOMEM;
13300 goto out;
13301 }
13302
13303 func->srf_bf_idx =
13304 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
13305 } else {
13306 struct nlattr *attr, *mac_attr =
13307 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
13308 int n_entries, rem, i = 0;
13309
13310 if (!mac_attr) {
13311 err = -EINVAL;
13312 goto out;
13313 }
13314
13315 n_entries = validate_acl_mac_addrs(mac_attr);
13316 if (n_entries <= 0) {
13317 err = -EINVAL;
13318 goto out;
13319 }
13320
13321 func->srf_num_macs = n_entries;
13322 func->srf_macs =
6396bb22 13323 kcalloc(n_entries, sizeof(*func->srf_macs),
a442b761
AB
13324 GFP_KERNEL);
13325 if (!func->srf_macs) {
13326 err = -ENOMEM;
13327 goto out;
13328 }
13329
13330 nla_for_each_nested(attr, mac_attr, rem)
13331 memcpy(func->srf_macs[i++].addr, nla_data(attr),
13332 sizeof(*func->srf_macs));
13333 }
13334 }
13335
13336 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
13337 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
13338 func, true);
13339 if (err)
13340 goto out;
13341 }
13342
13343 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
13344 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
13345 func, false);
13346 if (err)
13347 goto out;
13348 }
13349
13350 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13351 if (!msg) {
13352 err = -ENOMEM;
13353 goto out;
13354 }
13355
13356 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13357 NL80211_CMD_ADD_NAN_FUNCTION);
13358 /* This can't really happen - we just allocated 4KB */
13359 if (WARN_ON(!hdr)) {
13360 err = -ENOMEM;
13361 goto out;
13362 }
13363
13364 err = rdev_add_nan_func(rdev, wdev, func);
13365out:
13366 if (err < 0) {
13367 cfg80211_free_nan_func(func);
13368 nlmsg_free(msg);
13369 return err;
13370 }
13371
13372 /* propagate the instance id and cookie to userspace */
13373 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
13374 NL80211_ATTR_PAD))
13375 goto nla_put_failure;
13376
ae0be8de 13377 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
a442b761
AB
13378 if (!func_attr)
13379 goto nla_put_failure;
13380
13381 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
13382 func->instance_id))
13383 goto nla_put_failure;
13384
13385 nla_nest_end(msg, func_attr);
13386
13387 genlmsg_end(msg, hdr);
13388 return genlmsg_reply(msg, info);
13389
13390nla_put_failure:
13391 nlmsg_free(msg);
13392 return -ENOBUFS;
13393}
13394
13395static int nl80211_nan_del_func(struct sk_buff *skb,
13396 struct genl_info *info)
13397{
13398 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13399 struct wireless_dev *wdev = info->user_ptr[1];
13400 u64 cookie;
13401
13402 if (wdev->iftype != NL80211_IFTYPE_NAN)
13403 return -EOPNOTSUPP;
13404
73c7da3d 13405 if (!wdev_running(wdev))
a442b761
AB
13406 return -ENOTCONN;
13407
13408 if (!info->attrs[NL80211_ATTR_COOKIE])
13409 return -EINVAL;
13410
a442b761
AB
13411 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
13412
13413 rdev_del_nan_func(rdev, wdev, cookie);
13414
13415 return 0;
13416}
13417
a5a9dcf2
AB
13418static int nl80211_nan_change_config(struct sk_buff *skb,
13419 struct genl_info *info)
13420{
13421 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13422 struct wireless_dev *wdev = info->user_ptr[1];
13423 struct cfg80211_nan_conf conf = {};
13424 u32 changed = 0;
13425
13426 if (wdev->iftype != NL80211_IFTYPE_NAN)
13427 return -EOPNOTSUPP;
13428
73c7da3d 13429 if (!wdev_running(wdev))
a5a9dcf2
AB
13430 return -ENOTCONN;
13431
13432 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
13433 conf.master_pref =
13434 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
13435 if (conf.master_pref <= 1 || conf.master_pref == 255)
13436 return -EINVAL;
13437
13438 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
13439 }
13440
8585989d
LC
13441 if (info->attrs[NL80211_ATTR_BANDS]) {
13442 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
13443
13444 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
13445 return -EOPNOTSUPP;
13446
13447 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
13448 return -EINVAL;
13449
13450 conf.bands = bands;
13451 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
13452 }
13453
13454 if (!changed)
13455 return -EINVAL;
13456
13457 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
13458}
13459
50bcd31d
AB
13460void cfg80211_nan_match(struct wireless_dev *wdev,
13461 struct cfg80211_nan_match_params *match, gfp_t gfp)
13462{
13463 struct wiphy *wiphy = wdev->wiphy;
13464 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13465 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
13466 struct sk_buff *msg;
13467 void *hdr;
13468
13469 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
13470 return;
13471
13472 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13473 if (!msg)
13474 return;
13475
13476 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
13477 if (!hdr) {
13478 nlmsg_free(msg);
13479 return;
13480 }
13481
13482 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13483 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13484 wdev->netdev->ifindex)) ||
13485 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13486 NL80211_ATTR_PAD))
13487 goto nla_put_failure;
13488
13489 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
13490 NL80211_ATTR_PAD) ||
13491 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
13492 goto nla_put_failure;
13493
ae0be8de 13494 match_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_MATCH);
50bcd31d
AB
13495 if (!match_attr)
13496 goto nla_put_failure;
13497
ae0be8de
MK
13498 local_func_attr = nla_nest_start_noflag(msg,
13499 NL80211_NAN_MATCH_FUNC_LOCAL);
50bcd31d
AB
13500 if (!local_func_attr)
13501 goto nla_put_failure;
13502
13503 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
13504 goto nla_put_failure;
13505
13506 nla_nest_end(msg, local_func_attr);
13507
ae0be8de
MK
13508 peer_func_attr = nla_nest_start_noflag(msg,
13509 NL80211_NAN_MATCH_FUNC_PEER);
50bcd31d
AB
13510 if (!peer_func_attr)
13511 goto nla_put_failure;
13512
13513 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
13514 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
13515 goto nla_put_failure;
13516
13517 if (match->info && match->info_len &&
13518 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
13519 match->info))
13520 goto nla_put_failure;
13521
13522 nla_nest_end(msg, peer_func_attr);
13523 nla_nest_end(msg, match_attr);
13524 genlmsg_end(msg, hdr);
13525
13526 if (!wdev->owner_nlportid)
13527 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
13528 msg, 0, NL80211_MCGRP_NAN, gfp);
13529 else
13530 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
13531 wdev->owner_nlportid);
13532
13533 return;
13534
13535nla_put_failure:
13536 nlmsg_free(msg);
13537}
13538EXPORT_SYMBOL(cfg80211_nan_match);
13539
368e5a7b
AB
13540void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
13541 u8 inst_id,
13542 enum nl80211_nan_func_term_reason reason,
13543 u64 cookie, gfp_t gfp)
13544{
13545 struct wiphy *wiphy = wdev->wiphy;
13546 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13547 struct sk_buff *msg;
13548 struct nlattr *func_attr;
13549 void *hdr;
13550
13551 if (WARN_ON(!inst_id))
13552 return;
13553
13554 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13555 if (!msg)
13556 return;
13557
13558 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
13559 if (!hdr) {
13560 nlmsg_free(msg);
13561 return;
13562 }
13563
13564 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13565 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13566 wdev->netdev->ifindex)) ||
13567 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13568 NL80211_ATTR_PAD))
13569 goto nla_put_failure;
13570
13571 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13572 NL80211_ATTR_PAD))
13573 goto nla_put_failure;
13574
ae0be8de 13575 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
368e5a7b
AB
13576 if (!func_attr)
13577 goto nla_put_failure;
13578
13579 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
13580 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
13581 goto nla_put_failure;
13582
13583 nla_nest_end(msg, func_attr);
13584 genlmsg_end(msg, hdr);
13585
13586 if (!wdev->owner_nlportid)
13587 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
13588 msg, 0, NL80211_MCGRP_NAN, gfp);
13589 else
13590 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
13591 wdev->owner_nlportid);
13592
13593 return;
13594
13595nla_put_failure:
13596 nlmsg_free(msg);
13597}
13598EXPORT_SYMBOL(cfg80211_nan_func_terminated);
13599
3713b4e3
JB
13600static int nl80211_get_protocol_features(struct sk_buff *skb,
13601 struct genl_info *info)
13602{
13603 void *hdr;
13604 struct sk_buff *msg;
13605
13606 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13607 if (!msg)
13608 return -ENOMEM;
13609
13610 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13611 NL80211_CMD_GET_PROTOCOL_FEATURES);
13612 if (!hdr)
13613 goto nla_put_failure;
13614
13615 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
13616 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
13617 goto nla_put_failure;
13618
13619 genlmsg_end(msg, hdr);
13620 return genlmsg_reply(msg, info);
13621
13622 nla_put_failure:
13623 kfree_skb(msg);
13624 return -ENOBUFS;
13625}
13626
355199e0
JM
13627static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
13628{
13629 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13630 struct cfg80211_update_ft_ies_params ft_params;
13631 struct net_device *dev = info->user_ptr[1];
13632
13633 if (!rdev->ops->update_ft_ies)
13634 return -EOPNOTSUPP;
13635
13636 if (!info->attrs[NL80211_ATTR_MDID] ||
3d7af878 13637 !info->attrs[NL80211_ATTR_IE])
355199e0
JM
13638 return -EINVAL;
13639
13640 memset(&ft_params, 0, sizeof(ft_params));
13641 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
13642 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
13643 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
13644
13645 return rdev_update_ft_ies(rdev, dev, &ft_params);
13646}
13647
5de17984
AS
13648static int nl80211_crit_protocol_start(struct sk_buff *skb,
13649 struct genl_info *info)
13650{
13651 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13652 struct wireless_dev *wdev = info->user_ptr[1];
13653 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
13654 u16 duration;
13655 int ret;
13656
13657 if (!rdev->ops->crit_proto_start)
13658 return -EOPNOTSUPP;
13659
13660 if (WARN_ON(!rdev->ops->crit_proto_stop))
13661 return -EINVAL;
13662
13663 if (rdev->crit_proto_nlportid)
13664 return -EBUSY;
13665
13666 /* determine protocol if provided */
13667 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
13668 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
13669
13670 if (proto >= NUM_NL80211_CRIT_PROTO)
13671 return -EINVAL;
13672
13673 /* timeout must be provided */
13674 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
13675 return -EINVAL;
13676
13677 duration =
13678 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
13679
5de17984
AS
13680 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
13681 if (!ret)
13682 rdev->crit_proto_nlportid = info->snd_portid;
13683
13684 return ret;
13685}
13686
13687static int nl80211_crit_protocol_stop(struct sk_buff *skb,
13688 struct genl_info *info)
13689{
13690 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13691 struct wireless_dev *wdev = info->user_ptr[1];
13692
13693 if (!rdev->ops->crit_proto_stop)
13694 return -EOPNOTSUPP;
13695
13696 if (rdev->crit_proto_nlportid) {
13697 rdev->crit_proto_nlportid = 0;
13698 rdev_crit_proto_stop(rdev, wdev);
13699 }
13700 return 0;
13701}
13702
901bb989
JB
13703static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
13704 struct nlattr *attr,
13705 struct netlink_ext_ack *extack)
13706{
13707 if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
13708 if (attr->nla_type & NLA_F_NESTED) {
13709 NL_SET_ERR_MSG_ATTR(extack, attr,
13710 "unexpected nested data");
13711 return -EINVAL;
13712 }
13713
13714 return 0;
13715 }
13716
13717 if (!(attr->nla_type & NLA_F_NESTED)) {
13718 NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
13719 return -EINVAL;
13720 }
13721
32d5109a 13722 return nla_validate_nested(attr, vcmd->maxattr, vcmd->policy, extack);
901bb989
JB
13723}
13724
ad7e718c
JB
13725static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
13726{
13727 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13728 struct wireless_dev *wdev =
a05829a7
JB
13729 __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
13730 info->attrs);
ad7e718c
JB
13731 int i, err;
13732 u32 vid, subcmd;
13733
13734 if (!rdev->wiphy.vendor_commands)
13735 return -EOPNOTSUPP;
13736
13737 if (IS_ERR(wdev)) {
13738 err = PTR_ERR(wdev);
13739 if (err != -EINVAL)
13740 return err;
13741 wdev = NULL;
13742 } else if (wdev->wiphy != &rdev->wiphy) {
13743 return -EINVAL;
13744 }
13745
13746 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
13747 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
13748 return -EINVAL;
13749
13750 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
13751 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
13752 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
13753 const struct wiphy_vendor_command *vcmd;
13754 void *data = NULL;
13755 int len = 0;
13756
13757 vcmd = &rdev->wiphy.vendor_commands[i];
13758
13759 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
13760 continue;
13761
13762 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
13763 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
13764 if (!wdev)
13765 return -EINVAL;
13766 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
13767 !wdev->netdev)
13768 return -EINVAL;
13769
13770 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 13771 if (!wdev_running(wdev))
ad7e718c
JB
13772 return -ENETDOWN;
13773 }
13774 } else {
13775 wdev = NULL;
13776 }
13777
4052d3d2
JS
13778 if (!vcmd->doit)
13779 return -EOPNOTSUPP;
13780
ad7e718c
JB
13781 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
13782 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
13783 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
13784
13785 err = nl80211_vendor_check_policy(vcmd,
13786 info->attrs[NL80211_ATTR_VENDOR_DATA],
13787 info->extack);
13788 if (err)
13789 return err;
ad7e718c
JB
13790 }
13791
13792 rdev->cur_cmd_info = info;
901bb989 13793 err = vcmd->doit(&rdev->wiphy, wdev, data, len);
ad7e718c
JB
13794 rdev->cur_cmd_info = NULL;
13795 return err;
13796 }
13797
13798 return -EOPNOTSUPP;
13799}
13800
7bdbe400
JB
13801static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
13802 struct netlink_callback *cb,
13803 struct cfg80211_registered_device **rdev,
13804 struct wireless_dev **wdev)
13805{
50508d94 13806 struct nlattr **attrbuf;
7bdbe400
JB
13807 u32 vid, subcmd;
13808 unsigned int i;
13809 int vcmd_idx = -1;
13810 int err;
13811 void *data = NULL;
13812 unsigned int data_len = 0;
13813
7bdbe400
JB
13814 if (cb->args[0]) {
13815 /* subtract the 1 again here */
13816 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
13817 struct wireless_dev *tmp;
13818
ea90e0dc
JB
13819 if (!wiphy)
13820 return -ENODEV;
7bdbe400
JB
13821 *rdev = wiphy_to_rdev(wiphy);
13822 *wdev = NULL;
13823
13824 if (cb->args[1]) {
53873f13 13825 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
13826 if (tmp->identifier == cb->args[1] - 1) {
13827 *wdev = tmp;
13828 break;
13829 }
13830 }
13831 }
13832
13833 /* keep rtnl locked in successful case */
13834 return 0;
13835 }
13836
50508d94
JB
13837 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
13838 if (!attrbuf)
13839 return -ENOMEM;
13840
8cb08174
JB
13841 err = nlmsg_parse_deprecated(cb->nlh,
13842 GENL_HDRLEN + nl80211_fam.hdrsize,
13843 attrbuf, nl80211_fam.maxattr,
13844 nl80211_policy, NULL);
7bdbe400 13845 if (err)
50508d94 13846 goto out;
7bdbe400 13847
c90c39da 13848 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
50508d94
JB
13849 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
13850 err = -EINVAL;
13851 goto out;
13852 }
7bdbe400 13853
a05829a7 13854 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(skb->sk), attrbuf);
7bdbe400
JB
13855 if (IS_ERR(*wdev))
13856 *wdev = NULL;
13857
c90c39da 13858 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
50508d94
JB
13859 if (IS_ERR(*rdev)) {
13860 err = PTR_ERR(*rdev);
13861 goto out;
13862 }
7bdbe400 13863
c90c39da
JB
13864 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
13865 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
13866
13867 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
13868 const struct wiphy_vendor_command *vcmd;
13869
13870 vcmd = &(*rdev)->wiphy.vendor_commands[i];
13871
13872 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
13873 continue;
13874
50508d94
JB
13875 if (!vcmd->dumpit) {
13876 err = -EOPNOTSUPP;
13877 goto out;
13878 }
7bdbe400
JB
13879
13880 vcmd_idx = i;
13881 break;
13882 }
13883
50508d94
JB
13884 if (vcmd_idx < 0) {
13885 err = -EOPNOTSUPP;
13886 goto out;
13887 }
7bdbe400 13888
c90c39da
JB
13889 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
13890 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
13891 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
13892
13893 err = nl80211_vendor_check_policy(
13894 &(*rdev)->wiphy.vendor_commands[vcmd_idx],
13895 attrbuf[NL80211_ATTR_VENDOR_DATA],
13896 cb->extack);
13897 if (err)
50508d94 13898 goto out;
7bdbe400
JB
13899 }
13900
13901 /* 0 is the first index - add 1 to parse only once */
13902 cb->args[0] = (*rdev)->wiphy_idx + 1;
13903 /* add 1 to know if it was NULL */
13904 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
13905 cb->args[2] = vcmd_idx;
13906 cb->args[3] = (unsigned long)data;
13907 cb->args[4] = data_len;
13908
13909 /* keep rtnl locked in successful case */
50508d94
JB
13910 err = 0;
13911out:
13912 kfree(attrbuf);
13913 return err;
7bdbe400
JB
13914}
13915
13916static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
13917 struct netlink_callback *cb)
13918{
13919 struct cfg80211_registered_device *rdev;
13920 struct wireless_dev *wdev;
13921 unsigned int vcmd_idx;
13922 const struct wiphy_vendor_command *vcmd;
13923 void *data;
13924 int data_len;
13925 int err;
13926 struct nlattr *vendor_data;
13927
ea90e0dc 13928 rtnl_lock();
7bdbe400
JB
13929 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
13930 if (err)
ea90e0dc 13931 goto out;
7bdbe400
JB
13932
13933 vcmd_idx = cb->args[2];
13934 data = (void *)cb->args[3];
13935 data_len = cb->args[4];
13936 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
13937
13938 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
13939 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
13940 if (!wdev) {
13941 err = -EINVAL;
13942 goto out;
13943 }
7bdbe400 13944 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
13945 !wdev->netdev) {
13946 err = -EINVAL;
13947 goto out;
13948 }
7bdbe400
JB
13949
13950 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
13951 if (!wdev_running(wdev)) {
13952 err = -ENETDOWN;
13953 goto out;
13954 }
7bdbe400
JB
13955 }
13956 }
13957
13958 while (1) {
13959 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
13960 cb->nlh->nlmsg_seq, NLM_F_MULTI,
13961 NL80211_CMD_VENDOR);
13962 if (!hdr)
13963 break;
13964
13965 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
13966 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
13967 wdev_id(wdev),
13968 NL80211_ATTR_PAD))) {
7bdbe400
JB
13969 genlmsg_cancel(skb, hdr);
13970 break;
13971 }
13972
ae0be8de
MK
13973 vendor_data = nla_nest_start_noflag(skb,
13974 NL80211_ATTR_VENDOR_DATA);
7bdbe400
JB
13975 if (!vendor_data) {
13976 genlmsg_cancel(skb, hdr);
13977 break;
13978 }
13979
13980 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
13981 (unsigned long *)&cb->args[5]);
13982 nla_nest_end(skb, vendor_data);
13983
13984 if (err == -ENOBUFS || err == -ENOENT) {
13985 genlmsg_cancel(skb, hdr);
13986 break;
9c167b2d 13987 } else if (err <= 0) {
7bdbe400
JB
13988 genlmsg_cancel(skb, hdr);
13989 goto out;
13990 }
13991
13992 genlmsg_end(skb, hdr);
13993 }
13994
13995 err = skb->len;
13996 out:
13997 rtnl_unlock();
13998 return err;
13999}
14000
ad7e718c
JB
14001struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
14002 enum nl80211_commands cmd,
14003 enum nl80211_attrs attr,
14004 int approxlen)
14005{
f26cbf40 14006 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
14007
14008 if (WARN_ON(!rdev->cur_cmd_info))
14009 return NULL;
14010
6c09e791 14011 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
14012 rdev->cur_cmd_info->snd_portid,
14013 rdev->cur_cmd_info->snd_seq,
567ffc35 14014 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
14015}
14016EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
14017
14018int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
14019{
14020 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
14021 void *hdr = ((void **)skb->cb)[1];
14022 struct nlattr *data = ((void **)skb->cb)[2];
14023
bd8c78e7
JB
14024 /* clear CB data for netlink core to own from now on */
14025 memset(skb->cb, 0, sizeof(skb->cb));
14026
ad7e718c
JB
14027 if (WARN_ON(!rdev->cur_cmd_info)) {
14028 kfree_skb(skb);
14029 return -EINVAL;
14030 }
14031
14032 nla_nest_end(skb, data);
14033 genlmsg_end(skb, hdr);
14034 return genlmsg_reply(skb, rdev->cur_cmd_info);
14035}
14036EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
14037
55c1fdf0
JB
14038unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy)
14039{
14040 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14041
14042 if (WARN_ON(!rdev->cur_cmd_info))
14043 return 0;
14044
14045 return rdev->cur_cmd_info->snd_portid;
14046}
14047EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender);
14048
fa9ffc74
KP
14049static int nl80211_set_qos_map(struct sk_buff *skb,
14050 struct genl_info *info)
14051{
14052 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14053 struct cfg80211_qos_map *qos_map = NULL;
14054 struct net_device *dev = info->user_ptr[1];
14055 u8 *pos, len, num_des, des_len, des;
14056 int ret;
14057
14058 if (!rdev->ops->set_qos_map)
14059 return -EOPNOTSUPP;
14060
14061 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
14062 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
14063 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
14064
c8b82802 14065 if (len % 2)
fa9ffc74
KP
14066 return -EINVAL;
14067
14068 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
14069 if (!qos_map)
14070 return -ENOMEM;
14071
14072 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
14073 if (num_des) {
14074 des_len = num_des *
14075 sizeof(struct cfg80211_dscp_exception);
14076 memcpy(qos_map->dscp_exception, pos, des_len);
14077 qos_map->num_des = num_des;
14078 for (des = 0; des < num_des; des++) {
14079 if (qos_map->dscp_exception[des].up > 7) {
14080 kfree(qos_map);
14081 return -EINVAL;
14082 }
14083 }
14084 pos += des_len;
14085 }
14086 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
14087 }
14088
14089 wdev_lock(dev->ieee80211_ptr);
14090 ret = nl80211_key_allowed(dev->ieee80211_ptr);
14091 if (!ret)
14092 ret = rdev_set_qos_map(rdev, dev, qos_map);
14093 wdev_unlock(dev->ieee80211_ptr);
14094
14095 kfree(qos_map);
14096 return ret;
14097}
14098
960d01ac
JB
14099static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
14100{
14101 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14102 struct net_device *dev = info->user_ptr[1];
14103 struct wireless_dev *wdev = dev->ieee80211_ptr;
14104 const u8 *peer;
14105 u8 tsid, up;
14106 u16 admitted_time = 0;
14107 int err;
14108
723e73ac 14109 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
14110 return -EOPNOTSUPP;
14111
14112 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
14113 !info->attrs[NL80211_ATTR_USER_PRIO])
14114 return -EINVAL;
14115
14116 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
960d01ac 14117 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
960d01ac
JB
14118
14119 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 14120 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 14121 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
14122 * need more attributes for that (e.g. BA session requirement);
14123 * change the WMM adminssion test above to allow both then
960d01ac
JB
14124 */
14125 return -EINVAL;
14126 }
14127
14128 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14129
14130 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
14131 admitted_time =
14132 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
14133 if (!admitted_time)
14134 return -EINVAL;
14135 }
14136
14137 wdev_lock(wdev);
14138 switch (wdev->iftype) {
14139 case NL80211_IFTYPE_STATION:
14140 case NL80211_IFTYPE_P2P_CLIENT:
14141 if (wdev->current_bss)
14142 break;
14143 err = -ENOTCONN;
14144 goto out;
14145 default:
14146 err = -EOPNOTSUPP;
14147 goto out;
14148 }
14149
14150 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
14151
14152 out:
14153 wdev_unlock(wdev);
14154 return err;
14155}
14156
14157static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
14158{
14159 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14160 struct net_device *dev = info->user_ptr[1];
14161 struct wireless_dev *wdev = dev->ieee80211_ptr;
14162 const u8 *peer;
14163 u8 tsid;
14164 int err;
14165
14166 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
14167 return -EINVAL;
14168
14169 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
14170 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14171
14172 wdev_lock(wdev);
14173 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
14174 wdev_unlock(wdev);
14175
14176 return err;
14177}
14178
1057d35e
AN
14179static int nl80211_tdls_channel_switch(struct sk_buff *skb,
14180 struct genl_info *info)
14181{
14182 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14183 struct net_device *dev = info->user_ptr[1];
14184 struct wireless_dev *wdev = dev->ieee80211_ptr;
14185 struct cfg80211_chan_def chandef = {};
14186 const u8 *addr;
14187 u8 oper_class;
14188 int err;
14189
14190 if (!rdev->ops->tdls_channel_switch ||
14191 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
14192 return -EOPNOTSUPP;
14193
14194 switch (dev->ieee80211_ptr->iftype) {
14195 case NL80211_IFTYPE_STATION:
14196 case NL80211_IFTYPE_P2P_CLIENT:
14197 break;
14198 default:
14199 return -EOPNOTSUPP;
14200 }
14201
14202 if (!info->attrs[NL80211_ATTR_MAC] ||
14203 !info->attrs[NL80211_ATTR_OPER_CLASS])
14204 return -EINVAL;
14205
14206 err = nl80211_parse_chandef(rdev, info, &chandef);
14207 if (err)
14208 return err;
14209
14210 /*
14211 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
14212 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
14213 * specification is not defined for them.
14214 */
57fbcce3 14215 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
14216 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
14217 chandef.width != NL80211_CHAN_WIDTH_20)
14218 return -EINVAL;
14219
14220 /* we will be active on the TDLS link */
923b352f
AN
14221 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
14222 wdev->iftype))
1057d35e
AN
14223 return -EINVAL;
14224
14225 /* don't allow switching to DFS channels */
14226 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
14227 return -EINVAL;
14228
14229 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
14230 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
14231
14232 wdev_lock(wdev);
14233 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
14234 wdev_unlock(wdev);
14235
14236 return err;
14237}
14238
14239static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
14240 struct genl_info *info)
14241{
14242 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14243 struct net_device *dev = info->user_ptr[1];
14244 struct wireless_dev *wdev = dev->ieee80211_ptr;
14245 const u8 *addr;
14246
14247 if (!rdev->ops->tdls_channel_switch ||
14248 !rdev->ops->tdls_cancel_channel_switch ||
14249 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
14250 return -EOPNOTSUPP;
14251
14252 switch (dev->ieee80211_ptr->iftype) {
14253 case NL80211_IFTYPE_STATION:
14254 case NL80211_IFTYPE_P2P_CLIENT:
14255 break;
14256 default:
14257 return -EOPNOTSUPP;
14258 }
14259
14260 if (!info->attrs[NL80211_ATTR_MAC])
14261 return -EINVAL;
14262
14263 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
14264
14265 wdev_lock(wdev);
14266 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
14267 wdev_unlock(wdev);
14268
14269 return 0;
14270}
14271
ce0ce13a
MB
14272static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
14273 struct genl_info *info)
14274{
14275 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14276 struct net_device *dev = info->user_ptr[1];
14277 struct wireless_dev *wdev = dev->ieee80211_ptr;
14278 const struct nlattr *nla;
14279 bool enabled;
14280
ce0ce13a
MB
14281 if (!rdev->ops->set_multicast_to_unicast)
14282 return -EOPNOTSUPP;
14283
14284 if (wdev->iftype != NL80211_IFTYPE_AP &&
14285 wdev->iftype != NL80211_IFTYPE_P2P_GO)
14286 return -EOPNOTSUPP;
14287
14288 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
14289 enabled = nla_get_flag(nla);
14290
14291 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
14292}
14293
3a00df57
AS
14294static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
14295{
14296 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14297 struct net_device *dev = info->user_ptr[1];
14298 struct wireless_dev *wdev = dev->ieee80211_ptr;
14299 struct cfg80211_pmk_conf pmk_conf = {};
14300 int ret;
14301
14302 if (wdev->iftype != NL80211_IFTYPE_STATION &&
14303 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
14304 return -EOPNOTSUPP;
14305
14306 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14307 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
14308 return -EOPNOTSUPP;
14309
14310 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
14311 return -EINVAL;
14312
14313 wdev_lock(wdev);
14314 if (!wdev->current_bss) {
14315 ret = -ENOTCONN;
14316 goto out;
14317 }
14318
14319 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
14320 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
14321 ret = -EINVAL;
14322 goto out;
14323 }
14324
14325 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
14326 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
14327 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
14328 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
14329 ret = -EINVAL;
14330 goto out;
14331 }
14332
cb9abd48 14333 if (info->attrs[NL80211_ATTR_PMKR0_NAME])
3a00df57
AS
14334 pmk_conf.pmk_r0_name =
14335 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
3a00df57
AS
14336
14337 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
14338out:
14339 wdev_unlock(wdev);
14340 return ret;
14341}
14342
14343static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
14344{
14345 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14346 struct net_device *dev = info->user_ptr[1];
14347 struct wireless_dev *wdev = dev->ieee80211_ptr;
14348 const u8 *aa;
14349 int ret;
14350
14351 if (wdev->iftype != NL80211_IFTYPE_STATION &&
14352 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
14353 return -EOPNOTSUPP;
14354
14355 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14356 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
14357 return -EOPNOTSUPP;
14358
14359 if (!info->attrs[NL80211_ATTR_MAC])
14360 return -EINVAL;
14361
14362 wdev_lock(wdev);
14363 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
14364 ret = rdev_del_pmk(rdev, dev, aa);
14365 wdev_unlock(wdev);
14366
14367 return ret;
14368}
14369
40cbfa90
SD
14370static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
14371{
14372 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14373 struct net_device *dev = info->user_ptr[1];
14374 struct cfg80211_external_auth_params params;
14375
db8d93a7 14376 if (!rdev->ops->external_auth)
40cbfa90
SD
14377 return -EOPNOTSUPP;
14378
fe494370
SD
14379 if (!info->attrs[NL80211_ATTR_SSID] &&
14380 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
14381 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
40cbfa90
SD
14382 return -EINVAL;
14383
14384 if (!info->attrs[NL80211_ATTR_BSSID])
14385 return -EINVAL;
14386
14387 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
14388 return -EINVAL;
14389
14390 memset(&params, 0, sizeof(params));
14391
fe494370
SD
14392 if (info->attrs[NL80211_ATTR_SSID]) {
14393 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
cb9abd48 14394 if (params.ssid.ssid_len == 0)
fe494370
SD
14395 return -EINVAL;
14396 memcpy(params.ssid.ssid,
14397 nla_data(info->attrs[NL80211_ATTR_SSID]),
14398 params.ssid.ssid_len);
14399 }
40cbfa90
SD
14400
14401 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
14402 ETH_ALEN);
14403
14404 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
14405
fe494370
SD
14406 if (info->attrs[NL80211_ATTR_PMKID])
14407 params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
14408
40cbfa90
SD
14409 return rdev_external_auth(rdev, dev, &params);
14410}
14411
2576a9ac
DK
14412static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
14413{
dca9ca2d 14414 bool dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
2576a9ac
DK
14415 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14416 struct net_device *dev = info->user_ptr[1];
14417 struct wireless_dev *wdev = dev->ieee80211_ptr;
14418 const u8 *buf;
14419 size_t len;
14420 u8 *dest;
14421 u16 proto;
14422 bool noencrypt;
dca9ca2d 14423 u64 cookie = 0;
2576a9ac
DK
14424 int err;
14425
14426 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14427 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
14428 return -EOPNOTSUPP;
14429
14430 if (!rdev->ops->tx_control_port)
14431 return -EOPNOTSUPP;
14432
14433 if (!info->attrs[NL80211_ATTR_FRAME] ||
14434 !info->attrs[NL80211_ATTR_MAC] ||
14435 !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
14436 GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
14437 return -EINVAL;
14438 }
14439
14440 wdev_lock(wdev);
14441
14442 switch (wdev->iftype) {
14443 case NL80211_IFTYPE_AP:
14444 case NL80211_IFTYPE_P2P_GO:
14445 case NL80211_IFTYPE_MESH_POINT:
14446 break;
14447 case NL80211_IFTYPE_ADHOC:
14448 case NL80211_IFTYPE_STATION:
14449 case NL80211_IFTYPE_P2P_CLIENT:
14450 if (wdev->current_bss)
14451 break;
14452 err = -ENOTCONN;
14453 goto out;
14454 default:
14455 err = -EOPNOTSUPP;
14456 goto out;
14457 }
14458
14459 wdev_unlock(wdev);
14460
14461 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
14462 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
14463 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
14464 proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
14465 noencrypt =
14466 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
14467
dca9ca2d
MT
14468 err = rdev_tx_control_port(rdev, dev, buf, len,
14469 dest, cpu_to_be16(proto), noencrypt,
14470 dont_wait_for_ack ? NULL : &cookie);
14471 if (!err && !dont_wait_for_ack)
14472 nl_set_extack_cookie_u64(info->extack, cookie);
14473 return err;
2576a9ac
DK
14474 out:
14475 wdev_unlock(wdev);
14476 return err;
14477}
14478
81e54d08
PKC
14479static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
14480 struct genl_info *info)
14481{
14482 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14483 struct net_device *dev = info->user_ptr[1];
14484 struct wireless_dev *wdev = dev->ieee80211_ptr;
14485 struct cfg80211_ftm_responder_stats ftm_stats = {};
14486 struct sk_buff *msg;
14487 void *hdr;
14488 struct nlattr *ftm_stats_attr;
14489 int err;
14490
14491 if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval)
14492 return -EOPNOTSUPP;
14493
14494 err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
14495 if (err)
14496 return err;
14497
14498 if (!ftm_stats.filled)
14499 return -ENODATA;
14500
14501 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14502 if (!msg)
14503 return -ENOMEM;
14504
14505 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
14506 NL80211_CMD_GET_FTM_RESPONDER_STATS);
14507 if (!hdr)
1399c59f 14508 goto nla_put_failure;
81e54d08
PKC
14509
14510 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
14511 goto nla_put_failure;
14512
ae0be8de
MK
14513 ftm_stats_attr = nla_nest_start_noflag(msg,
14514 NL80211_ATTR_FTM_RESPONDER_STATS);
81e54d08
PKC
14515 if (!ftm_stats_attr)
14516 goto nla_put_failure;
14517
14518#define SET_FTM(field, name, type) \
14519 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
14520 nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name, \
14521 ftm_stats.field)) \
14522 goto nla_put_failure; } while (0)
14523#define SET_FTM_U64(field, name) \
14524 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
14525 nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name, \
14526 ftm_stats.field, NL80211_FTM_STATS_PAD)) \
14527 goto nla_put_failure; } while (0)
14528
14529 SET_FTM(success_num, SUCCESS_NUM, u32);
14530 SET_FTM(partial_num, PARTIAL_NUM, u32);
14531 SET_FTM(failed_num, FAILED_NUM, u32);
14532 SET_FTM(asap_num, ASAP_NUM, u32);
14533 SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
14534 SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
14535 SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
14536 SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
14537 SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
14538#undef SET_FTM
14539
14540 nla_nest_end(msg, ftm_stats_attr);
14541
14542 genlmsg_end(msg, hdr);
14543 return genlmsg_reply(msg, info);
14544
14545nla_put_failure:
14546 nlmsg_free(msg);
14547 return -ENOBUFS;
14548}
14549
cb74e977
SD
14550static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
14551{
14552 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14553 struct cfg80211_update_owe_info owe_info;
14554 struct net_device *dev = info->user_ptr[1];
14555
14556 if (!rdev->ops->update_owe_info)
14557 return -EOPNOTSUPP;
14558
14559 if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
14560 !info->attrs[NL80211_ATTR_MAC])
14561 return -EINVAL;
14562
14563 memset(&owe_info, 0, sizeof(owe_info));
14564 owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
14565 nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
14566
14567 if (info->attrs[NL80211_ATTR_IE]) {
14568 owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
14569 owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
14570 }
14571
14572 return rdev_update_owe_info(rdev, dev, &owe_info);
14573}
14574
5ab92e7f
RM
14575static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
14576{
14577 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14578 struct net_device *dev = info->user_ptr[1];
14579 struct wireless_dev *wdev = dev->ieee80211_ptr;
14580 struct station_info sinfo = {};
14581 const u8 *buf;
14582 size_t len;
14583 u8 *dest;
14584 int err;
14585
14586 if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
14587 return -EOPNOTSUPP;
14588
14589 if (!info->attrs[NL80211_ATTR_MAC] ||
14590 !info->attrs[NL80211_ATTR_FRAME]) {
14591 GENL_SET_ERR_MSG(info, "Frame or MAC missing");
14592 return -EINVAL;
14593 }
14594
14595 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
14596 return -EOPNOTSUPP;
14597
14598 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
14599 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
14600 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
14601
14602 if (len < sizeof(struct ethhdr))
14603 return -EINVAL;
14604
14605 if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
14606 !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
14607 return -EINVAL;
14608
14609 err = rdev_get_station(rdev, dev, dest, &sinfo);
14610 if (err)
14611 return err;
14612
2a279b34
FF
14613 cfg80211_sinfo_release_content(&sinfo);
14614
5ab92e7f
RM
14615 return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
14616}
14617
77f576de
T
14618static int parse_tid_conf(struct cfg80211_registered_device *rdev,
14619 struct nlattr *attrs[], struct net_device *dev,
3710a8a6 14620 struct cfg80211_tid_cfg *tid_conf,
77f576de
T
14621 struct genl_info *info, const u8 *peer)
14622{
14623 struct netlink_ext_ack *extack = info->extack;
3710a8a6 14624 u64 mask;
77f576de
T
14625 int err;
14626
14627 if (!attrs[NL80211_TID_CONFIG_ATTR_TIDS])
14628 return -EINVAL;
14629
14630 tid_conf->config_override =
14631 nla_get_flag(attrs[NL80211_TID_CONFIG_ATTR_OVERRIDE]);
3710a8a6 14632 tid_conf->tids = nla_get_u16(attrs[NL80211_TID_CONFIG_ATTR_TIDS]);
77f576de
T
14633
14634 if (tid_conf->config_override) {
14635 if (rdev->ops->reset_tid_config) {
14636 err = rdev_reset_tid_config(rdev, dev, peer,
3710a8a6 14637 tid_conf->tids);
c0336955 14638 if (err)
77f576de
T
14639 return err;
14640 } else {
14641 return -EINVAL;
14642 }
14643 }
14644
14645 if (attrs[NL80211_TID_CONFIG_ATTR_NOACK]) {
3710a8a6 14646 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_NOACK);
77f576de
T
14647 tid_conf->noack =
14648 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_NOACK]);
14649 }
14650
6a21d16c
T
14651 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]) {
14652 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT);
14653 tid_conf->retry_short =
14654 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]);
14655
14656 if (tid_conf->retry_short > rdev->wiphy.max_data_retry_count)
14657 return -EINVAL;
14658 }
14659
14660 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]) {
14661 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
14662 tid_conf->retry_long =
14663 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]);
14664
14665 if (tid_conf->retry_long > rdev->wiphy.max_data_retry_count)
14666 return -EINVAL;
14667 }
14668
ade274b2
T
14669 if (attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]) {
14670 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
14671 tid_conf->ampdu =
14672 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]);
14673 }
14674
04f7d142
T
14675 if (attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]) {
14676 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
14677 tid_conf->rtscts =
14678 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]);
14679 }
14680
33462e68
SM
14681 if (attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]) {
14682 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL);
14683 tid_conf->amsdu =
14684 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]);
14685 }
14686
9a5f6488
TC
14687 if (attrs[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE]) {
14688 u32 idx = NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, attr;
14689
14690 tid_conf->txrate_type = nla_get_u8(attrs[idx]);
14691
14692 if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) {
14693 attr = NL80211_TID_CONFIG_ATTR_TX_RATE;
14694 err = nl80211_parse_tx_bitrate_mask(info, attrs, attr,
857b34c4
RM
14695 &tid_conf->txrate_mask, dev,
14696 true);
9a5f6488
TC
14697 if (err)
14698 return err;
14699
14700 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE);
14701 }
14702 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);
14703 }
14704
3710a8a6
JB
14705 if (peer)
14706 mask = rdev->wiphy.tid_config_support.peer;
14707 else
14708 mask = rdev->wiphy.tid_config_support.vif;
14709
14710 if (tid_conf->mask & ~mask) {
14711 NL_SET_ERR_MSG(extack, "unsupported TID configuration");
14712 return -ENOTSUPP;
14713 }
14714
77f576de
T
14715 return 0;
14716}
14717
14718static int nl80211_set_tid_config(struct sk_buff *skb,
14719 struct genl_info *info)
14720{
14721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14722 struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1];
14723 struct net_device *dev = info->user_ptr[1];
3710a8a6 14724 struct cfg80211_tid_config *tid_config;
77f576de
T
14725 struct nlattr *tid;
14726 int conf_idx = 0, rem_conf;
14727 int ret = -EINVAL;
14728 u32 num_conf = 0;
14729
14730 if (!info->attrs[NL80211_ATTR_TID_CONFIG])
14731 return -EINVAL;
14732
14733 if (!rdev->ops->set_tid_config)
14734 return -EOPNOTSUPP;
14735
14736 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
14737 rem_conf)
14738 num_conf++;
14739
14740 tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf),
14741 GFP_KERNEL);
14742 if (!tid_config)
14743 return -ENOMEM;
14744
14745 tid_config->n_tid_conf = num_conf;
14746
14747 if (info->attrs[NL80211_ATTR_MAC])
14748 tid_config->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14749
14750 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
14751 rem_conf) {
14752 ret = nla_parse_nested(attrs, NL80211_TID_CONFIG_ATTR_MAX,
14753 tid, NULL, NULL);
14754
14755 if (ret)
14756 goto bad_tid_conf;
14757
14758 ret = parse_tid_conf(rdev, attrs, dev,
14759 &tid_config->tid_conf[conf_idx],
14760 info, tid_config->peer);
14761 if (ret)
14762 goto bad_tid_conf;
14763
14764 conf_idx++;
14765 }
14766
14767 ret = rdev_set_tid_config(rdev, dev, tid_config);
14768
14769bad_tid_conf:
14770 kfree(tid_config);
14771 return ret;
14772}
14773
4c476991
JB
14774#define NL80211_FLAG_NEED_WIPHY 0x01
14775#define NL80211_FLAG_NEED_NETDEV 0x02
14776#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
14777#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
14778#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
14779 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 14780#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 14781/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
14782#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
14783 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 14784#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 14785
f84f771d 14786static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
14787 struct genl_info *info)
14788{
a05829a7 14789 struct cfg80211_registered_device *rdev = NULL;
89a54e48 14790 struct wireless_dev *wdev;
4c476991 14791 struct net_device *dev;
4c476991 14792
a05829a7 14793 rtnl_lock();
4c476991 14794 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 14795 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991 14796 if (IS_ERR(rdev)) {
a05829a7 14797 rtnl_unlock();
4c476991
JB
14798 return PTR_ERR(rdev);
14799 }
14800 info->user_ptr[0] = rdev;
1bf614ef
JB
14801 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
14802 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
a05829a7 14803 wdev = __cfg80211_wdev_from_attrs(NULL, genl_info_net(info),
89a54e48
JB
14804 info->attrs);
14805 if (IS_ERR(wdev)) {
a05829a7 14806 rtnl_unlock();
89a54e48 14807 return PTR_ERR(wdev);
4c476991 14808 }
89a54e48 14809
89a54e48 14810 dev = wdev->netdev;
f26cbf40 14811 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 14812
1bf614ef
JB
14813 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
14814 if (!dev) {
a05829a7 14815 rtnl_unlock();
1bf614ef
JB
14816 return -EINVAL;
14817 }
14818
14819 info->user_ptr[1] = dev;
14820 } else {
14821 info->user_ptr[1] = wdev;
41265714 14822 }
1bf614ef 14823
73c7da3d
AVS
14824 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
14825 !wdev_running(wdev)) {
a05829a7 14826 rtnl_unlock();
73c7da3d
AVS
14827 return -ENETDOWN;
14828 }
1bf614ef 14829
73c7da3d 14830 if (dev)
1bf614ef 14831 dev_hold(dev);
89a54e48 14832
4c476991 14833 info->user_ptr[0] = rdev;
4c476991
JB
14834 }
14835
a05829a7
JB
14836 if (rdev) {
14837 wiphy_lock(&rdev->wiphy);
14838 /* we keep the mutex locked until post_doit */
14839 __release(&rdev->wiphy.mtx);
14840 }
14841 if (!(ops->internal_flags & NL80211_FLAG_NEED_RTNL))
14842 rtnl_unlock();
14843
4c476991
JB
14844 return 0;
14845}
14846
f84f771d 14847static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
14848 struct genl_info *info)
14849{
1bf614ef
JB
14850 if (info->user_ptr[1]) {
14851 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
14852 struct wireless_dev *wdev = info->user_ptr[1];
14853
14854 if (wdev->netdev)
14855 dev_put(wdev->netdev);
14856 } else {
14857 dev_put(info->user_ptr[1]);
14858 }
14859 }
5393b917 14860
a05829a7
JB
14861 if (info->user_ptr[0]) {
14862 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14863
14864 /* we kept the mutex locked since pre_doit */
14865 __acquire(&rdev->wiphy.mtx);
14866 wiphy_unlock(&rdev->wiphy);
14867 }
14868
4c476991
JB
14869 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
14870 rtnl_unlock();
5393b917
JB
14871
14872 /* If needed, clear the netlink message payload from the SKB
14873 * as it might contain key data that shouldn't stick around on
14874 * the heap after the SKB is freed. The netlink message header
14875 * is still needed for further processing, so leave it intact.
14876 */
14877 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
14878 struct nlmsghdr *nlh = nlmsg_hdr(skb);
14879
14880 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
14881 }
4c476991
JB
14882}
14883
6bdb68ce
CH
14884static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
14885 struct cfg80211_sar_specs *sar_specs,
14886 struct nlattr *spec[], int index)
14887{
14888 u32 range_index, i;
14889
14890 if (!sar_specs || !spec)
14891 return -EINVAL;
14892
14893 if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
14894 !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
14895 return -EINVAL;
14896
14897 range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
14898
14899 /* check if range_index exceeds num_freq_ranges */
14900 if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
14901 return -EINVAL;
14902
14903 /* check if range_index duplicates */
14904 for (i = 0; i < index; i++) {
14905 if (sar_specs->sub_specs[i].freq_range_index == range_index)
14906 return -EINVAL;
14907 }
14908
14909 sar_specs->sub_specs[index].power =
14910 nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
14911
14912 sar_specs->sub_specs[index].freq_range_index = range_index;
14913
14914 return 0;
14915}
14916
14917static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
14918{
14919 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14920 struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
14921 struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
14922 struct cfg80211_sar_specs *sar_spec;
14923 enum nl80211_sar_type type;
14924 struct nlattr *spec_list;
14925 u32 specs;
14926 int rem, err;
14927
14928 if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
14929 return -EOPNOTSUPP;
14930
14931 if (!info->attrs[NL80211_ATTR_SAR_SPEC])
14932 return -EINVAL;
14933
14934 nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
14935 info->attrs[NL80211_ATTR_SAR_SPEC],
14936 NULL, NULL);
14937
14938 if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
14939 return -EINVAL;
14940
14941 type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
14942 if (type != rdev->wiphy.sar_capa->type)
14943 return -EINVAL;
14944
14945 specs = 0;
14946 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
14947 specs++;
14948
14949 if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
14950 return -EINVAL;
14951
14952 sar_spec = kzalloc(sizeof(*sar_spec) +
14953 specs * sizeof(struct cfg80211_sar_sub_specs),
14954 GFP_KERNEL);
14955 if (!sar_spec)
14956 return -ENOMEM;
14957
14958 sar_spec->type = type;
14959 specs = 0;
14960 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
14961 nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
14962 spec_list, NULL, NULL);
14963
14964 switch (type) {
14965 case NL80211_SAR_TYPE_POWER:
14966 if (nl80211_set_sar_sub_specs(rdev, sar_spec,
14967 spec, specs)) {
14968 err = -EINVAL;
14969 goto error;
14970 }
14971 break;
14972 default:
14973 err = -EINVAL;
14974 goto error;
14975 }
14976 specs++;
14977 }
14978
14979 sar_spec->num_sub_specs = specs;
14980
14981 rdev->cur_cmd_info = info;
14982 err = rdev_set_sar_specs(rdev, sar_spec);
14983 rdev->cur_cmd_info = NULL;
14984error:
14985 kfree(sar_spec);
14986 return err;
14987}
14988
4534de83 14989static const struct genl_ops nl80211_ops[] = {
55682965
JB
14990 {
14991 .cmd = NL80211_CMD_GET_WIPHY,
ef6243ac 14992 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
14993 .doit = nl80211_get_wiphy,
14994 .dumpit = nl80211_dump_wiphy,
86e8cf98 14995 .done = nl80211_dump_wiphy_done,
55682965 14996 /* can be retrieved by unprivileged users */
a05829a7 14997 .internal_flags = NL80211_FLAG_NEED_WIPHY,
55682965 14998 },
66a9b928
JK
14999};
15000
15001static const struct genl_small_ops nl80211_small_ops[] = {
55682965
JB
15002 {
15003 .cmd = NL80211_CMD_SET_WIPHY,
ef6243ac 15004 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15005 .doit = nl80211_set_wiphy,
5617c6cd 15006 .flags = GENL_UNS_ADMIN_PERM,
55682965
JB
15007 },
15008 {
15009 .cmd = NL80211_CMD_GET_INTERFACE,
ef6243ac 15010 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
15011 .doit = nl80211_get_interface,
15012 .dumpit = nl80211_dump_interface,
55682965 15013 /* can be retrieved by unprivileged users */
a05829a7 15014 .internal_flags = NL80211_FLAG_NEED_WDEV,
55682965
JB
15015 },
15016 {
15017 .cmd = NL80211_CMD_SET_INTERFACE,
ef6243ac 15018 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15019 .doit = nl80211_set_interface,
5617c6cd 15020 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
15021 .internal_flags = NL80211_FLAG_NEED_NETDEV |
15022 NL80211_FLAG_NEED_RTNL,
55682965
JB
15023 },
15024 {
15025 .cmd = NL80211_CMD_NEW_INTERFACE,
ef6243ac 15026 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15027 .doit = nl80211_new_interface,
5617c6cd 15028 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
15029 .internal_flags = NL80211_FLAG_NEED_WIPHY |
15030 NL80211_FLAG_NEED_RTNL,
55682965
JB
15031 },
15032 {
15033 .cmd = NL80211_CMD_DEL_INTERFACE,
ef6243ac 15034 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15035 .doit = nl80211_del_interface,
5617c6cd 15036 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 15037 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 15038 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
15039 },
15040 {
15041 .cmd = NL80211_CMD_GET_KEY,
ef6243ac 15042 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15043 .doit = nl80211_get_key,
5617c6cd 15044 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15045 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
41ade00f
JB
15046 },
15047 {
15048 .cmd = NL80211_CMD_SET_KEY,
ef6243ac 15049 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15050 .doit = nl80211_set_key,
5617c6cd 15051 .flags = GENL_UNS_ADMIN_PERM,
41265714 15052 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917 15053 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
15054 },
15055 {
15056 .cmd = NL80211_CMD_NEW_KEY,
ef6243ac 15057 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15058 .doit = nl80211_new_key,
5617c6cd 15059 .flags = GENL_UNS_ADMIN_PERM,
41265714 15060 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917 15061 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
15062 },
15063 {
15064 .cmd = NL80211_CMD_DEL_KEY,
ef6243ac 15065 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15066 .doit = nl80211_del_key,
5617c6cd 15067 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15068 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
55682965 15069 },
ed1b6cc7
JB
15070 {
15071 .cmd = NL80211_CMD_SET_BEACON,
ef6243ac 15072 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15073 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15074 .doit = nl80211_set_beacon,
a05829a7 15075 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7
JB
15076 },
15077 {
8860020e 15078 .cmd = NL80211_CMD_START_AP,
ef6243ac 15079 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15080 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15081 .doit = nl80211_start_ap,
a05829a7 15082 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7
JB
15083 },
15084 {
8860020e 15085 .cmd = NL80211_CMD_STOP_AP,
ef6243ac 15086 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15087 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15088 .doit = nl80211_stop_ap,
a05829a7 15089 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7 15090 },
5727ef1b
JB
15091 {
15092 .cmd = NL80211_CMD_GET_STATION,
ef6243ac 15093 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15094 .doit = nl80211_get_station,
2ec600d6 15095 .dumpit = nl80211_dump_station,
a05829a7 15096 .internal_flags = NL80211_FLAG_NEED_NETDEV,
5727ef1b
JB
15097 },
15098 {
15099 .cmd = NL80211_CMD_SET_STATION,
ef6243ac 15100 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15101 .doit = nl80211_set_station,
5617c6cd 15102 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15103 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5727ef1b
JB
15104 },
15105 {
15106 .cmd = NL80211_CMD_NEW_STATION,
ef6243ac 15107 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15108 .doit = nl80211_new_station,
5617c6cd 15109 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15110 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5727ef1b
JB
15111 },
15112 {
15113 .cmd = NL80211_CMD_DEL_STATION,
ef6243ac 15114 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15115 .doit = nl80211_del_station,
5617c6cd 15116 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15117 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15118 },
15119 {
15120 .cmd = NL80211_CMD_GET_MPATH,
ef6243ac 15121 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6
LCC
15122 .doit = nl80211_get_mpath,
15123 .dumpit = nl80211_dump_mpath,
5617c6cd 15124 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15125 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6 15126 },
66be7d2b
HR
15127 {
15128 .cmd = NL80211_CMD_GET_MPP,
ef6243ac 15129 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
66be7d2b
HR
15130 .doit = nl80211_get_mpp,
15131 .dumpit = nl80211_dump_mpp,
5617c6cd 15132 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15133 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
66be7d2b 15134 },
2ec600d6
LCC
15135 {
15136 .cmd = NL80211_CMD_SET_MPATH,
ef6243ac 15137 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15138 .doit = nl80211_set_mpath,
5617c6cd 15139 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15140 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15141 },
15142 {
15143 .cmd = NL80211_CMD_NEW_MPATH,
ef6243ac 15144 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15145 .doit = nl80211_new_mpath,
5617c6cd 15146 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15147 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15148 },
15149 {
15150 .cmd = NL80211_CMD_DEL_MPATH,
ef6243ac 15151 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15152 .doit = nl80211_del_mpath,
5617c6cd 15153 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15154 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
9f1ba906
JM
15155 },
15156 {
15157 .cmd = NL80211_CMD_SET_BSS,
ef6243ac 15158 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9f1ba906 15159 .doit = nl80211_set_bss,
5617c6cd 15160 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15161 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
b2e1b302 15162 },
f130347c
LR
15163 {
15164 .cmd = NL80211_CMD_GET_REG,
ef6243ac 15165 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad30ca2c
AN
15166 .doit = nl80211_get_reg_do,
15167 .dumpit = nl80211_get_reg_dump,
a05829a7 15168 .internal_flags = 0,
f130347c
LR
15169 /* can be retrieved by unprivileged users */
15170 },
b6863036 15171#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
15172 {
15173 .cmd = NL80211_CMD_SET_REG,
ef6243ac 15174 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 15175 .doit = nl80211_set_reg,
b2e1b302 15176 .flags = GENL_ADMIN_PERM,
a05829a7 15177 .internal_flags = 0,
b2e1b302 15178 },
b6863036 15179#endif
b2e1b302
LR
15180 {
15181 .cmd = NL80211_CMD_REQ_SET_REG,
ef6243ac 15182 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 15183 .doit = nl80211_req_set_reg,
93da9cc1 15184 .flags = GENL_ADMIN_PERM,
15185 },
1ea4ff3e
JB
15186 {
15187 .cmd = NL80211_CMD_RELOAD_REGDB,
ef6243ac 15188 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1ea4ff3e 15189 .doit = nl80211_reload_regdb,
1ea4ff3e
JB
15190 .flags = GENL_ADMIN_PERM,
15191 },
93da9cc1 15192 {
24bdd9f4 15193 .cmd = NL80211_CMD_GET_MESH_CONFIG,
ef6243ac 15194 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 15195 .doit = nl80211_get_mesh_config,
93da9cc1 15196 /* can be retrieved by unprivileged users */
a05829a7 15197 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
93da9cc1 15198 },
15199 {
24bdd9f4 15200 .cmd = NL80211_CMD_SET_MESH_CONFIG,
ef6243ac 15201 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 15202 .doit = nl80211_update_mesh_config,
5617c6cd 15203 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15204 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
9aed3cc1 15205 },
2a519311
JB
15206 {
15207 .cmd = NL80211_CMD_TRIGGER_SCAN,
ef6243ac 15208 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311 15209 .doit = nl80211_trigger_scan,
5617c6cd 15210 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15211 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
2a519311 15212 },
91d3ab46
VK
15213 {
15214 .cmd = NL80211_CMD_ABORT_SCAN,
ef6243ac 15215 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
91d3ab46 15216 .doit = nl80211_abort_scan,
5617c6cd 15217 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15218 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
91d3ab46 15219 },
2a519311
JB
15220 {
15221 .cmd = NL80211_CMD_GET_SCAN,
ef6243ac 15222 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311
JB
15223 .dumpit = nl80211_dump_scan,
15224 },
807f8a8c
LC
15225 {
15226 .cmd = NL80211_CMD_START_SCHED_SCAN,
ef6243ac 15227 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 15228 .doit = nl80211_start_sched_scan,
5617c6cd 15229 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15230 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
807f8a8c
LC
15231 },
15232 {
15233 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
ef6243ac 15234 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 15235 .doit = nl80211_stop_sched_scan,
5617c6cd 15236 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15237 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
807f8a8c 15238 },
636a5d36
JM
15239 {
15240 .cmd = NL80211_CMD_AUTHENTICATE,
ef6243ac 15241 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15242 .doit = nl80211_authenticate,
5617c6cd 15243 .flags = GENL_UNS_ADMIN_PERM,
41265714 15244 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15245 0 |
5393b917 15246 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
15247 },
15248 {
15249 .cmd = NL80211_CMD_ASSOCIATE,
ef6243ac 15250 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15251 .doit = nl80211_associate,
5617c6cd 15252 .flags = GENL_UNS_ADMIN_PERM,
41265714 15253 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15254 0 |
d6db02a8 15255 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
15256 },
15257 {
15258 .cmd = NL80211_CMD_DEAUTHENTICATE,
ef6243ac 15259 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15260 .doit = nl80211_deauthenticate,
5617c6cd 15261 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15262 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
636a5d36
JM
15263 },
15264 {
15265 .cmd = NL80211_CMD_DISASSOCIATE,
ef6243ac 15266 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15267 .doit = nl80211_disassociate,
5617c6cd 15268 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15269 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
636a5d36 15270 },
04a773ad
JB
15271 {
15272 .cmd = NL80211_CMD_JOIN_IBSS,
ef6243ac 15273 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 15274 .doit = nl80211_join_ibss,
5617c6cd 15275 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15276 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04a773ad
JB
15277 },
15278 {
15279 .cmd = NL80211_CMD_LEAVE_IBSS,
ef6243ac 15280 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 15281 .doit = nl80211_leave_ibss,
5617c6cd 15282 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15283 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04a773ad 15284 },
aff89a9b
JB
15285#ifdef CONFIG_NL80211_TESTMODE
15286 {
15287 .cmd = NL80211_CMD_TESTMODE,
ef6243ac 15288 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
aff89a9b 15289 .doit = nl80211_testmode_do,
71063f0e 15290 .dumpit = nl80211_testmode_dump,
5617c6cd 15291 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15292 .internal_flags = NL80211_FLAG_NEED_WIPHY,
aff89a9b
JB
15293 },
15294#endif
b23aa676
SO
15295 {
15296 .cmd = NL80211_CMD_CONNECT,
ef6243ac 15297 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 15298 .doit = nl80211_connect,
5617c6cd 15299 .flags = GENL_UNS_ADMIN_PERM,
41265714 15300 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15301 0 |
d6db02a8 15302 NL80211_FLAG_CLEAR_SKB,
b23aa676 15303 },
088e8df8 15304 {
15305 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
ef6243ac 15306 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
088e8df8 15307 .doit = nl80211_update_connect_params,
088e8df8 15308 .flags = GENL_ADMIN_PERM,
15309 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15310 0 |
d6db02a8 15311 NL80211_FLAG_CLEAR_SKB,
088e8df8 15312 },
b23aa676
SO
15313 {
15314 .cmd = NL80211_CMD_DISCONNECT,
ef6243ac 15315 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 15316 .doit = nl80211_disconnect,
5617c6cd 15317 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15318 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
b23aa676 15319 },
463d0183
JB
15320 {
15321 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
ef6243ac 15322 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
463d0183 15323 .doit = nl80211_wiphy_netns,
5617c6cd 15324 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15325 .internal_flags = NL80211_FLAG_NEED_WIPHY,
463d0183 15326 },
61fa713c
HS
15327 {
15328 .cmd = NL80211_CMD_GET_SURVEY,
ef6243ac 15329 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
61fa713c
HS
15330 .dumpit = nl80211_dump_survey,
15331 },
67fbb16b
SO
15332 {
15333 .cmd = NL80211_CMD_SET_PMKSA,
ef6243ac 15334 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15335 .doit = nl80211_setdel_pmksa,
5617c6cd 15336 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 15337 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15338 0 |
d6db02a8 15339 NL80211_FLAG_CLEAR_SKB,
67fbb16b
SO
15340 },
15341 {
15342 .cmd = NL80211_CMD_DEL_PMKSA,
ef6243ac 15343 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15344 .doit = nl80211_setdel_pmksa,
5617c6cd 15345 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15346 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
67fbb16b
SO
15347 },
15348 {
15349 .cmd = NL80211_CMD_FLUSH_PMKSA,
ef6243ac 15350 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15351 .doit = nl80211_flush_pmksa,
5617c6cd 15352 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15353 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
67fbb16b 15354 },
9588bbd5
JM
15355 {
15356 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
ef6243ac 15357 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 15358 .doit = nl80211_remain_on_channel,
5617c6cd 15359 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15360 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9588bbd5
JM
15361 },
15362 {
15363 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
ef6243ac 15364 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 15365 .doit = nl80211_cancel_remain_on_channel,
5617c6cd 15366 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15367 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9588bbd5 15368 },
13ae75b1
JM
15369 {
15370 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
ef6243ac 15371 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
13ae75b1 15372 .doit = nl80211_set_tx_bitrate_mask,
5617c6cd 15373 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15374 .internal_flags = NL80211_FLAG_NEED_NETDEV,
13ae75b1 15375 },
026331c4 15376 {
2e161f78 15377 .cmd = NL80211_CMD_REGISTER_FRAME,
ef6243ac 15378 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 15379 .doit = nl80211_register_mgmt,
5617c6cd 15380 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15381 .internal_flags = NL80211_FLAG_NEED_WDEV,
026331c4
JM
15382 },
15383 {
2e161f78 15384 .cmd = NL80211_CMD_FRAME,
ef6243ac 15385 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 15386 .doit = nl80211_tx_mgmt,
5617c6cd 15387 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15388 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
f7ca38df
JB
15389 },
15390 {
15391 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
ef6243ac 15392 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f7ca38df 15393 .doit = nl80211_tx_mgmt_cancel_wait,
5617c6cd 15394 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15395 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
026331c4 15396 },
ffb9eb3d
KV
15397 {
15398 .cmd = NL80211_CMD_SET_POWER_SAVE,
ef6243ac 15399 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 15400 .doit = nl80211_set_power_save,
5617c6cd 15401 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15402 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ffb9eb3d
KV
15403 },
15404 {
15405 .cmd = NL80211_CMD_GET_POWER_SAVE,
ef6243ac 15406 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 15407 .doit = nl80211_get_power_save,
ffb9eb3d 15408 /* can be retrieved by unprivileged users */
a05829a7 15409 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ffb9eb3d 15410 },
d6dc1a38
JO
15411 {
15412 .cmd = NL80211_CMD_SET_CQM,
ef6243ac 15413 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
d6dc1a38 15414 .doit = nl80211_set_cqm,
5617c6cd 15415 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15416 .internal_flags = NL80211_FLAG_NEED_NETDEV,
d6dc1a38 15417 },
f444de05
JB
15418 {
15419 .cmd = NL80211_CMD_SET_CHANNEL,
ef6243ac 15420 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f444de05 15421 .doit = nl80211_set_channel,
5617c6cd 15422 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15423 .internal_flags = NL80211_FLAG_NEED_NETDEV,
f444de05 15424 },
29cbe68c
JB
15425 {
15426 .cmd = NL80211_CMD_JOIN_MESH,
ef6243ac 15427 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 15428 .doit = nl80211_join_mesh,
5617c6cd 15429 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15430 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
29cbe68c
JB
15431 },
15432 {
15433 .cmd = NL80211_CMD_LEAVE_MESH,
ef6243ac 15434 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 15435 .doit = nl80211_leave_mesh,
5617c6cd 15436 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15437 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
29cbe68c 15438 },
6e0bd6c3
RL
15439 {
15440 .cmd = NL80211_CMD_JOIN_OCB,
ef6243ac 15441 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 15442 .doit = nl80211_join_ocb,
5617c6cd 15443 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15444 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
6e0bd6c3
RL
15445 },
15446 {
15447 .cmd = NL80211_CMD_LEAVE_OCB,
ef6243ac 15448 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 15449 .doit = nl80211_leave_ocb,
5617c6cd 15450 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15451 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
6e0bd6c3 15452 },
dfb89c56 15453#ifdef CONFIG_PM
ff1b6e69
JB
15454 {
15455 .cmd = NL80211_CMD_GET_WOWLAN,
ef6243ac 15456 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 15457 .doit = nl80211_get_wowlan,
ff1b6e69 15458 /* can be retrieved by unprivileged users */
a05829a7 15459 .internal_flags = NL80211_FLAG_NEED_WIPHY,
ff1b6e69
JB
15460 },
15461 {
15462 .cmd = NL80211_CMD_SET_WOWLAN,
ef6243ac 15463 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 15464 .doit = nl80211_set_wowlan,
5617c6cd 15465 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15466 .internal_flags = NL80211_FLAG_NEED_WIPHY,
ff1b6e69 15467 },
dfb89c56 15468#endif
e5497d76
JB
15469 {
15470 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
ef6243ac 15471 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
e5497d76 15472 .doit = nl80211_set_rekey_data,
5617c6cd 15473 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 15474 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15475 0 |
5393b917 15476 NL80211_FLAG_CLEAR_SKB,
e5497d76 15477 },
109086ce
AN
15478 {
15479 .cmd = NL80211_CMD_TDLS_MGMT,
ef6243ac 15480 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 15481 .doit = nl80211_tdls_mgmt,
5617c6cd 15482 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15483 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
109086ce
AN
15484 },
15485 {
15486 .cmd = NL80211_CMD_TDLS_OPER,
ef6243ac 15487 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 15488 .doit = nl80211_tdls_oper,
5617c6cd 15489 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15490 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
109086ce 15491 },
28946da7
JB
15492 {
15493 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
ef6243ac 15494 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
28946da7 15495 .doit = nl80211_register_unexpected_frame,
5617c6cd 15496 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15497 .internal_flags = NL80211_FLAG_NEED_NETDEV,
28946da7 15498 },
7f6cf311
JB
15499 {
15500 .cmd = NL80211_CMD_PROBE_CLIENT,
ef6243ac 15501 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7f6cf311 15502 .doit = nl80211_probe_client,
5617c6cd 15503 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15504 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
7f6cf311 15505 },
5e760230
JB
15506 {
15507 .cmd = NL80211_CMD_REGISTER_BEACONS,
ef6243ac 15508 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5e760230 15509 .doit = nl80211_register_beacons,
5617c6cd 15510 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15511 .internal_flags = NL80211_FLAG_NEED_WIPHY,
5e760230 15512 },
1d9d9213
SW
15513 {
15514 .cmd = NL80211_CMD_SET_NOACK_MAP,
ef6243ac 15515 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1d9d9213 15516 .doit = nl80211_set_noack_map,
5617c6cd 15517 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15518 .internal_flags = NL80211_FLAG_NEED_NETDEV,
1d9d9213 15519 },
98104fde
JB
15520 {
15521 .cmd = NL80211_CMD_START_P2P_DEVICE,
ef6243ac 15522 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 15523 .doit = nl80211_start_p2p_device,
5617c6cd 15524 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
15525 .internal_flags = NL80211_FLAG_NEED_WDEV |
15526 NL80211_FLAG_NEED_RTNL,
15527 },
15528 {
15529 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
ef6243ac 15530 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 15531 .doit = nl80211_stop_p2p_device,
5617c6cd 15532 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
15533 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
15534 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
15535 },
15536 {
15537 .cmd = NL80211_CMD_START_NAN,
ef6243ac 15538 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 15539 .doit = nl80211_start_nan,
cb3b7d87
AB
15540 .flags = GENL_ADMIN_PERM,
15541 .internal_flags = NL80211_FLAG_NEED_WDEV |
15542 NL80211_FLAG_NEED_RTNL,
15543 },
15544 {
15545 .cmd = NL80211_CMD_STOP_NAN,
ef6243ac 15546 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 15547 .doit = nl80211_stop_nan,
cb3b7d87
AB
15548 .flags = GENL_ADMIN_PERM,
15549 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
15550 NL80211_FLAG_NEED_RTNL,
a442b761
AB
15551 },
15552 {
15553 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
ef6243ac 15554 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 15555 .doit = nl80211_nan_add_func,
a442b761 15556 .flags = GENL_ADMIN_PERM,
a05829a7 15557 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
a442b761
AB
15558 },
15559 {
15560 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
ef6243ac 15561 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 15562 .doit = nl80211_nan_del_func,
a442b761 15563 .flags = GENL_ADMIN_PERM,
a05829a7 15564 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
a5a9dcf2
AB
15565 },
15566 {
15567 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
ef6243ac 15568 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a5a9dcf2 15569 .doit = nl80211_nan_change_config,
a5a9dcf2 15570 .flags = GENL_ADMIN_PERM,
a05829a7 15571 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
98104fde 15572 },
f4e583c8
AQ
15573 {
15574 .cmd = NL80211_CMD_SET_MCAST_RATE,
ef6243ac 15575 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f4e583c8 15576 .doit = nl80211_set_mcast_rate,
5617c6cd 15577 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15578 .internal_flags = NL80211_FLAG_NEED_NETDEV,
77765eaf
VT
15579 },
15580 {
15581 .cmd = NL80211_CMD_SET_MAC_ACL,
ef6243ac 15582 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
77765eaf 15583 .doit = nl80211_set_mac_acl,
5617c6cd 15584 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15585 .internal_flags = NL80211_FLAG_NEED_NETDEV,
f4e583c8 15586 },
04f39047
SW
15587 {
15588 .cmd = NL80211_CMD_RADAR_DETECT,
ef6243ac 15589 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04f39047 15590 .doit = nl80211_start_radar_detection,
5617c6cd 15591 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15592 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04f39047 15593 },
3713b4e3
JB
15594 {
15595 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
ef6243ac 15596 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3713b4e3 15597 .doit = nl80211_get_protocol_features,
3713b4e3 15598 },
355199e0
JM
15599 {
15600 .cmd = NL80211_CMD_UPDATE_FT_IES,
ef6243ac 15601 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
355199e0 15602 .doit = nl80211_update_ft_ies,
5617c6cd 15603 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15604 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
355199e0 15605 },
5de17984
AS
15606 {
15607 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
ef6243ac 15608 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 15609 .doit = nl80211_crit_protocol_start,
5617c6cd 15610 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15611 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
5de17984
AS
15612 },
15613 {
15614 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
ef6243ac 15615 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 15616 .doit = nl80211_crit_protocol_stop,
5617c6cd 15617 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15618 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
be29b99a
AK
15619 },
15620 {
15621 .cmd = NL80211_CMD_GET_COALESCE,
ef6243ac 15622 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 15623 .doit = nl80211_get_coalesce,
a05829a7 15624 .internal_flags = NL80211_FLAG_NEED_WIPHY,
be29b99a
AK
15625 },
15626 {
15627 .cmd = NL80211_CMD_SET_COALESCE,
ef6243ac 15628 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 15629 .doit = nl80211_set_coalesce,
5617c6cd 15630 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15631 .internal_flags = NL80211_FLAG_NEED_WIPHY,
16ef1fe2
SW
15632 },
15633 {
15634 .cmd = NL80211_CMD_CHANNEL_SWITCH,
ef6243ac 15635 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16ef1fe2 15636 .doit = nl80211_channel_switch,
5617c6cd 15637 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15638 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
16ef1fe2 15639 },
ad7e718c
JB
15640 {
15641 .cmd = NL80211_CMD_VENDOR,
ef6243ac 15642 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad7e718c 15643 .doit = nl80211_vendor_cmd,
7bdbe400 15644 .dumpit = nl80211_vendor_cmd_dump,
5617c6cd 15645 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c 15646 .internal_flags = NL80211_FLAG_NEED_WIPHY |
a05829a7 15647 0 |
d6db02a8 15648 NL80211_FLAG_CLEAR_SKB,
ad7e718c 15649 },
fa9ffc74
KP
15650 {
15651 .cmd = NL80211_CMD_SET_QOS_MAP,
ef6243ac 15652 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
fa9ffc74 15653 .doit = nl80211_set_qos_map,
5617c6cd 15654 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15655 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
fa9ffc74 15656 },
960d01ac
JB
15657 {
15658 .cmd = NL80211_CMD_ADD_TX_TS,
ef6243ac 15659 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 15660 .doit = nl80211_add_tx_ts,
5617c6cd 15661 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15662 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
960d01ac
JB
15663 },
15664 {
15665 .cmd = NL80211_CMD_DEL_TX_TS,
ef6243ac 15666 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 15667 .doit = nl80211_del_tx_ts,
5617c6cd 15668 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15669 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
960d01ac 15670 },
1057d35e
AN
15671 {
15672 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
ef6243ac 15673 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 15674 .doit = nl80211_tdls_channel_switch,
5617c6cd 15675 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15676 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
1057d35e
AN
15677 },
15678 {
15679 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
ef6243ac 15680 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 15681 .doit = nl80211_tdls_cancel_channel_switch,
5617c6cd 15682 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15683 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
1057d35e 15684 },
ce0ce13a
MB
15685 {
15686 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
ef6243ac 15687 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ce0ce13a 15688 .doit = nl80211_set_multicast_to_unicast,
ce0ce13a 15689 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15690 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ce0ce13a 15691 },
3a00df57
AS
15692 {
15693 .cmd = NL80211_CMD_SET_PMK,
ef6243ac 15694 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 15695 .doit = nl80211_set_pmk,
3a00df57 15696 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15697 0 |
d6db02a8 15698 NL80211_FLAG_CLEAR_SKB,
3a00df57
AS
15699 },
15700 {
15701 .cmd = NL80211_CMD_DEL_PMK,
ef6243ac 15702 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 15703 .doit = nl80211_del_pmk,
a05829a7 15704 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
3a00df57 15705 },
40cbfa90
SD
15706 {
15707 .cmd = NL80211_CMD_EXTERNAL_AUTH,
ef6243ac 15708 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
40cbfa90 15709 .doit = nl80211_external_auth,
40cbfa90 15710 .flags = GENL_ADMIN_PERM,
a05829a7 15711 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
40cbfa90 15712 },
2576a9ac
DK
15713 {
15714 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
ef6243ac 15715 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2576a9ac 15716 .doit = nl80211_tx_control_port,
2576a9ac 15717 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15718 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2576a9ac 15719 },
81e54d08
PKC
15720 {
15721 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
ef6243ac 15722 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
81e54d08 15723 .doit = nl80211_get_ftm_responder_stats,
a05829a7 15724 .internal_flags = NL80211_FLAG_NEED_NETDEV,
81e54d08 15725 },
9bb7e0f2
JB
15726 {
15727 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
ef6243ac 15728 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9bb7e0f2 15729 .doit = nl80211_pmsr_start,
9bb7e0f2 15730 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15731 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9bb7e0f2 15732 },
30c63115
S
15733 {
15734 .cmd = NL80211_CMD_NOTIFY_RADAR,
ef6243ac 15735 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
30c63115 15736 .doit = nl80211_notify_radar_detection,
30c63115 15737 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15738 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
30c63115 15739 },
cb74e977
SD
15740 {
15741 .cmd = NL80211_CMD_UPDATE_OWE_INFO,
15742 .doit = nl80211_update_owe_info,
15743 .flags = GENL_ADMIN_PERM,
a05829a7 15744 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5ab92e7f
RM
15745 },
15746 {
15747 .cmd = NL80211_CMD_PROBE_MESH_LINK,
15748 .doit = nl80211_probe_mesh_link,
15749 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15750 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
cb74e977 15751 },
77f576de
T
15752 {
15753 .cmd = NL80211_CMD_SET_TID_CONFIG,
15754 .doit = nl80211_set_tid_config,
15755 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15756 .internal_flags = NL80211_FLAG_NEED_NETDEV,
77f576de 15757 },
6bdb68ce
CH
15758 {
15759 .cmd = NL80211_CMD_SET_SAR_SPECS,
15760 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
15761 .doit = nl80211_set_sar_specs,
15762 .flags = GENL_UNS_ADMIN_PERM,
15763 .internal_flags = NL80211_FLAG_NEED_WIPHY |
15764 NL80211_FLAG_NEED_RTNL,
15765 },
55682965 15766};
9588bbd5 15767
56989f6d 15768static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
15769 .name = NL80211_GENL_NAME, /* have users key off the name instead */
15770 .hdrsize = 0, /* no private header */
15771 .version = 1, /* no particular meaning now */
15772 .maxattr = NL80211_ATTR_MAX,
3b0f31f2 15773 .policy = nl80211_policy,
489111e5
JB
15774 .netnsok = true,
15775 .pre_doit = nl80211_pre_doit,
15776 .post_doit = nl80211_post_doit,
15777 .module = THIS_MODULE,
15778 .ops = nl80211_ops,
15779 .n_ops = ARRAY_SIZE(nl80211_ops),
66a9b928
JK
15780 .small_ops = nl80211_small_ops,
15781 .n_small_ops = ARRAY_SIZE(nl80211_small_ops),
489111e5
JB
15782 .mcgrps = nl80211_mcgrps,
15783 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
50508d94 15784 .parallel_ops = true,
489111e5
JB
15785};
15786
55682965
JB
15787/* notification functions */
15788
3bb20556
JB
15789void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
15790 enum nl80211_commands cmd)
55682965
JB
15791{
15792 struct sk_buff *msg;
86e8cf98 15793 struct nl80211_dump_wiphy_state state = {};
55682965 15794
3bb20556
JB
15795 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
15796 cmd != NL80211_CMD_DEL_WIPHY);
15797
fd2120ca 15798 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
15799 if (!msg)
15800 return;
15801
3bb20556 15802 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
15803 nlmsg_free(msg);
15804 return;
15805 }
15806
68eb5503 15807 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15808 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
15809}
15810
896ff063
DK
15811void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
15812 struct wireless_dev *wdev,
15813 enum nl80211_commands cmd)
15814{
15815 struct sk_buff *msg;
15816
896ff063
DK
15817 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15818 if (!msg)
15819 return;
15820
3d1a5bbf 15821 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
896ff063
DK
15822 nlmsg_free(msg);
15823 return;
15824 }
15825
15826 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
15827 NL80211_MCGRP_CONFIG, GFP_KERNEL);
15828}
15829
362a415d
JB
15830static int nl80211_add_scan_req(struct sk_buff *msg,
15831 struct cfg80211_registered_device *rdev)
15832{
15833 struct cfg80211_scan_request *req = rdev->scan_req;
15834 struct nlattr *nest;
15835 int i;
c8cb5b85 15836 struct cfg80211_scan_info *info;
362a415d
JB
15837
15838 if (WARN_ON(!req))
15839 return 0;
15840
ae0be8de 15841 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_SSIDS);
362a415d
JB
15842 if (!nest)
15843 goto nla_put_failure;
9360ffd1
DM
15844 for (i = 0; i < req->n_ssids; i++) {
15845 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
15846 goto nla_put_failure;
15847 }
362a415d
JB
15848 nla_nest_end(msg, nest);
15849
2032f3b2
TP
15850 if (req->flags & NL80211_SCAN_FLAG_FREQ_KHZ) {
15851 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQ_KHZ);
15852 if (!nest)
15853 goto nla_put_failure;
15854 for (i = 0; i < req->n_channels; i++) {
15855 if (nla_put_u32(msg, i,
15856 ieee80211_channel_to_khz(req->channels[i])))
15857 goto nla_put_failure;
15858 }
15859 nla_nest_end(msg, nest);
15860 } else {
15861 nest = nla_nest_start_noflag(msg,
15862 NL80211_ATTR_SCAN_FREQUENCIES);
15863 if (!nest)
9360ffd1 15864 goto nla_put_failure;
2032f3b2
TP
15865 for (i = 0; i < req->n_channels; i++) {
15866 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
15867 goto nla_put_failure;
15868 }
15869 nla_nest_end(msg, nest);
9360ffd1 15870 }
362a415d 15871
9360ffd1
DM
15872 if (req->ie &&
15873 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
15874 goto nla_put_failure;
362a415d 15875
ae917c9f
JB
15876 if (req->flags &&
15877 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
15878 goto nla_put_failure;
ed473771 15879
c8cb5b85
TM
15880 info = rdev->int_scan_req ? &rdev->int_scan_req->info :
15881 &rdev->scan_req->info;
15882 if (info->scan_start_tsf &&
1d76250b 15883 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
c8cb5b85 15884 info->scan_start_tsf, NL80211_BSS_PAD) ||
1d76250b 15885 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
c8cb5b85 15886 info->tsf_bssid)))
1d76250b
AS
15887 goto nla_put_failure;
15888
362a415d
JB
15889 return 0;
15890 nla_put_failure:
15891 return -ENOBUFS;
15892}
15893
505a2e88 15894static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 15895 struct cfg80211_registered_device *rdev,
fd014284 15896 struct wireless_dev *wdev,
15e47304 15897 u32 portid, u32 seq, int flags,
a538e2d5 15898 u32 cmd)
2a519311
JB
15899{
15900 void *hdr;
15901
15e47304 15902 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
15903 if (!hdr)
15904 return -1;
15905
9360ffd1 15906 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
15907 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15908 wdev->netdev->ifindex)) ||
2dad624e
ND
15909 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15910 NL80211_ATTR_PAD))
9360ffd1 15911 goto nla_put_failure;
2a519311 15912
362a415d
JB
15913 /* ignore errors and send incomplete event anyway */
15914 nl80211_add_scan_req(msg, rdev);
2a519311 15915
053c095a
JB
15916 genlmsg_end(msg, hdr);
15917 return 0;
2a519311
JB
15918
15919 nla_put_failure:
15920 genlmsg_cancel(msg, hdr);
15921 return -EMSGSIZE;
15922}
15923
807f8a8c 15924static int
505a2e88 15925nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 15926 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
15927{
15928 void *hdr;
15929
96b08fd6 15930 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
15931 if (!hdr)
15932 return -1;
15933
96b08fd6
AVS
15934 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
15935 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
15936 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
15937 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
15938 NL80211_ATTR_PAD))
9360ffd1 15939 goto nla_put_failure;
807f8a8c 15940
053c095a
JB
15941 genlmsg_end(msg, hdr);
15942 return 0;
807f8a8c
LC
15943
15944 nla_put_failure:
15945 genlmsg_cancel(msg, hdr);
15946 return -EMSGSIZE;
15947}
15948
a538e2d5 15949void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 15950 struct wireless_dev *wdev)
a538e2d5
JB
15951{
15952 struct sk_buff *msg;
15953
58050fce 15954 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
15955 if (!msg)
15956 return;
15957
505a2e88 15958 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
15959 NL80211_CMD_TRIGGER_SCAN) < 0) {
15960 nlmsg_free(msg);
15961 return;
15962 }
15963
68eb5503 15964 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15965 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
15966}
15967
f9d15d16
JB
15968struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
15969 struct wireless_dev *wdev, bool aborted)
2a519311
JB
15970{
15971 struct sk_buff *msg;
15972
fd2120ca 15973 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 15974 if (!msg)
f9d15d16 15975 return NULL;
2a519311 15976
505a2e88 15977 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
15978 aborted ? NL80211_CMD_SCAN_ABORTED :
15979 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 15980 nlmsg_free(msg);
f9d15d16 15981 return NULL;
2a519311
JB
15982 }
15983
f9d15d16 15984 return msg;
2a519311
JB
15985}
15986
505a2e88
AVS
15987/* send message created by nl80211_build_scan_msg() */
15988void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
15989 struct sk_buff *msg)
807f8a8c 15990{
807f8a8c
LC
15991 if (!msg)
15992 return;
15993
68eb5503 15994 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15995 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
15996}
15997
96b08fd6 15998void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
15999{
16000 struct sk_buff *msg;
16001
58050fce 16002 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
16003 if (!msg)
16004 return;
16005
96b08fd6 16006 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
16007 nlmsg_free(msg);
16008 return;
16009 }
16010
96b08fd6 16011 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 16012 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
16013}
16014
b0d7aa59
JD
16015static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
16016 struct regulatory_request *request)
73d54c9e 16017{
73d54c9e 16018 /* Userspace can always count this one always being set */
9360ffd1
DM
16019 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
16020 goto nla_put_failure;
16021
16022 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
16023 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16024 NL80211_REGDOM_TYPE_WORLD))
16025 goto nla_put_failure;
16026 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
16027 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16028 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
16029 goto nla_put_failure;
16030 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
16031 request->intersect) {
16032 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16033 NL80211_REGDOM_TYPE_INTERSECTION))
16034 goto nla_put_failure;
16035 } else {
16036 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16037 NL80211_REGDOM_TYPE_COUNTRY) ||
16038 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
16039 request->alpha2))
16040 goto nla_put_failure;
16041 }
16042
ad30ca2c
AN
16043 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
16044 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
16045
16046 if (wiphy &&
16047 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
16048 goto nla_put_failure;
1bdd716c
AN
16049
16050 if (wiphy &&
16051 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
16052 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
16053 goto nla_put_failure;
ad30ca2c 16054 }
73d54c9e 16055
b0d7aa59
JD
16056 return true;
16057
16058nla_put_failure:
16059 return false;
16060}
16061
16062/*
16063 * This can happen on global regulatory changes or device specific settings
16064 * based on custom regulatory domains.
16065 */
16066void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
16067 struct regulatory_request *request)
16068{
16069 struct sk_buff *msg;
16070 void *hdr;
16071
16072 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16073 if (!msg)
16074 return;
16075
16076 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
24f6d765 16077 if (!hdr)
16078 goto nla_put_failure;
b0d7aa59 16079
24f6d765 16080 if (!nl80211_reg_change_event_fill(msg, request))
b0d7aa59
JD
16081 goto nla_put_failure;
16082
3b7b72ee 16083 genlmsg_end(msg, hdr);
73d54c9e 16084
bc43b28c 16085 rcu_read_lock();
68eb5503 16086 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 16087 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 16088 rcu_read_unlock();
73d54c9e
LR
16089
16090 return;
16091
16092nla_put_failure:
73d54c9e
LR
16093 nlmsg_free(msg);
16094}
16095
6039f6d2
JM
16096static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
16097 struct net_device *netdev,
16098 const u8 *buf, size_t len,
b0b6aa2c 16099 enum nl80211_commands cmd, gfp_t gfp,
4d9ec73d 16100 int uapsd_queues, const u8 *req_ies,
3bb02143 16101 size_t req_ies_len, bool reconnect)
6039f6d2
JM
16102{
16103 struct sk_buff *msg;
16104 void *hdr;
16105
4d9ec73d 16106 msg = nlmsg_new(100 + len + req_ies_len, gfp);
6039f6d2
JM
16107 if (!msg)
16108 return;
16109
16110 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16111 if (!hdr) {
16112 nlmsg_free(msg);
16113 return;
16114 }
16115
9360ffd1
DM
16116 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16117 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
4d9ec73d
JM
16118 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
16119 (req_ies &&
16120 nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
9360ffd1 16121 goto nla_put_failure;
6039f6d2 16122
3bb02143
JB
16123 if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
16124 goto nla_put_failure;
16125
b0b6aa2c
EP
16126 if (uapsd_queues >= 0) {
16127 struct nlattr *nla_wmm =
ae0be8de 16128 nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
b0b6aa2c
EP
16129 if (!nla_wmm)
16130 goto nla_put_failure;
16131
16132 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
16133 uapsd_queues))
16134 goto nla_put_failure;
16135
16136 nla_nest_end(msg, nla_wmm);
16137 }
16138
3b7b72ee 16139 genlmsg_end(msg, hdr);
6039f6d2 16140
68eb5503 16141 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16142 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
16143 return;
16144
16145 nla_put_failure:
6039f6d2
JM
16146 nlmsg_free(msg);
16147}
16148
16149void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16150 struct net_device *netdev, const u8 *buf,
16151 size_t len, gfp_t gfp)
6039f6d2
JM
16152{
16153 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16154 NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0,
16155 false);
6039f6d2
JM
16156}
16157
16158void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
16159 struct net_device *netdev, const u8 *buf,
4d9ec73d
JM
16160 size_t len, gfp_t gfp, int uapsd_queues,
16161 const u8 *req_ies, size_t req_ies_len)
6039f6d2 16162{
e6d6e342 16163 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 16164 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
3bb02143 16165 req_ies, req_ies_len, false);
6039f6d2
JM
16166}
16167
53b46b84 16168void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342 16169 struct net_device *netdev, const u8 *buf,
3bb02143 16170 size_t len, bool reconnect, gfp_t gfp)
6039f6d2
JM
16171{
16172 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16173 NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0,
16174 reconnect);
6039f6d2
JM
16175}
16176
53b46b84
JM
16177void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
16178 struct net_device *netdev, const u8 *buf,
3bb02143 16179 size_t len, bool reconnect, gfp_t gfp)
6039f6d2
JM
16180{
16181 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16182 NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0,
16183 reconnect);
6039f6d2
JM
16184}
16185
6ff57cf8
JB
16186void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
16187 size_t len)
cf4e594e 16188{
947add36
JB
16189 struct wireless_dev *wdev = dev->ieee80211_ptr;
16190 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16191 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
16192 const struct ieee80211_mgmt *mgmt = (void *)buf;
16193 u32 cmd;
947add36 16194
6ff57cf8
JB
16195 if (WARN_ON(len < 2))
16196 return;
cf4e594e 16197
4d797fce 16198 if (ieee80211_is_deauth(mgmt->frame_control)) {
6ff57cf8 16199 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
4d797fce 16200 } else if (ieee80211_is_disassoc(mgmt->frame_control)) {
6ff57cf8 16201 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
4d797fce
JM
16202 } else if (ieee80211_is_beacon(mgmt->frame_control)) {
16203 if (wdev->unprot_beacon_reported &&
16204 elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
16205 return;
16206 cmd = NL80211_CMD_UNPROT_BEACON;
16207 wdev->unprot_beacon_reported = jiffies;
16208 } else {
16209 return;
16210 }
947add36 16211
6ff57cf8 16212 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
4d9ec73d 16213 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
3bb02143 16214 NULL, 0, false);
cf4e594e 16215}
6ff57cf8 16216EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 16217
1b06bb40
LR
16218static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
16219 struct net_device *netdev, int cmd,
e6d6e342 16220 const u8 *addr, gfp_t gfp)
1965c853
JM
16221{
16222 struct sk_buff *msg;
16223 void *hdr;
16224
e6d6e342 16225 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
16226 if (!msg)
16227 return;
16228
16229 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16230 if (!hdr) {
16231 nlmsg_free(msg);
16232 return;
16233 }
16234
9360ffd1
DM
16235 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16236 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16237 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
16238 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
16239 goto nla_put_failure;
1965c853 16240
3b7b72ee 16241 genlmsg_end(msg, hdr);
1965c853 16242
68eb5503 16243 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16244 NL80211_MCGRP_MLME, gfp);
1965c853
JM
16245 return;
16246
16247 nla_put_failure:
1965c853
JM
16248 nlmsg_free(msg);
16249}
16250
16251void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16252 struct net_device *netdev, const u8 *addr,
16253 gfp_t gfp)
1965c853
JM
16254{
16255 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 16256 addr, gfp);
1965c853
JM
16257}
16258
16259void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16260 struct net_device *netdev, const u8 *addr,
16261 gfp_t gfp)
1965c853 16262{
e6d6e342
JB
16263 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
16264 addr, gfp);
1965c853
JM
16265}
16266
b23aa676 16267void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
16268 struct net_device *netdev,
16269 struct cfg80211_connect_resp_params *cr,
3093ebbe 16270 gfp_t gfp)
b23aa676
SO
16271{
16272 struct sk_buff *msg;
16273 void *hdr;
16274
a3caf744 16275 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
76804d28
AVS
16276 cr->fils.kek_len + cr->fils.pmk_len +
16277 (cr->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
16278 if (!msg)
16279 return;
16280
16281 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
16282 if (!hdr) {
16283 nlmsg_free(msg);
16284 return;
16285 }
16286
9360ffd1
DM
16287 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16288 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
16289 (cr->bssid &&
16290 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 16291 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
16292 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
16293 cr->status) ||
16294 (cr->status < 0 &&
3093ebbe 16295 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
16296 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
16297 cr->timeout_reason))) ||
16298 (cr->req_ie &&
16299 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
16300 (cr->resp_ie &&
16301 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744 16302 cr->resp_ie)) ||
76804d28 16303 (cr->fils.update_erp_next_seq_num &&
a3caf744 16304 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
76804d28 16305 cr->fils.erp_next_seq_num)) ||
a3caf744 16306 (cr->status == WLAN_STATUS_SUCCESS &&
76804d28
AVS
16307 ((cr->fils.kek &&
16308 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
16309 cr->fils.kek)) ||
16310 (cr->fils.pmk &&
16311 nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
16312 (cr->fils.pmkid &&
16313 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
9360ffd1 16314 goto nla_put_failure;
b23aa676 16315
3b7b72ee 16316 genlmsg_end(msg, hdr);
b23aa676 16317
68eb5503 16318 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16319 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
16320 return;
16321
16322 nla_put_failure:
b23aa676 16323 nlmsg_free(msg);
b23aa676
SO
16324}
16325
16326void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
16327 struct net_device *netdev,
16328 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
16329{
16330 struct sk_buff *msg;
16331 void *hdr;
29ce6ecb 16332 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 16333
e841b7b1
AVS
16334 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
16335 info->fils.kek_len + info->fils.pmk_len +
16336 (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
16337 if (!msg)
16338 return;
16339
16340 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
16341 if (!hdr) {
16342 nlmsg_free(msg);
16343 return;
16344 }
16345
9360ffd1
DM
16346 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16347 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16348 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
16349 (info->req_ie &&
16350 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
16351 info->req_ie)) ||
16352 (info->resp_ie &&
16353 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
e841b7b1
AVS
16354 info->resp_ie)) ||
16355 (info->fils.update_erp_next_seq_num &&
16356 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
16357 info->fils.erp_next_seq_num)) ||
16358 (info->fils.kek &&
16359 nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
16360 info->fils.kek)) ||
16361 (info->fils.pmk &&
16362 nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
16363 (info->fils.pmkid &&
16364 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
9360ffd1 16365 goto nla_put_failure;
b23aa676 16366
3b7b72ee 16367 genlmsg_end(msg, hdr);
b23aa676 16368
68eb5503 16369 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16370 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
16371 return;
16372
503c1fb9 16373 nla_put_failure:
503c1fb9
AS
16374 nlmsg_free(msg);
16375}
16376
16377void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
16378 struct net_device *netdev, const u8 *bssid)
16379{
16380 struct sk_buff *msg;
16381 void *hdr;
16382
16383 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16384 if (!msg)
16385 return;
16386
16387 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
16388 if (!hdr) {
16389 nlmsg_free(msg);
16390 return;
16391 }
16392
f4d75993
CHH
16393 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16394 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16395 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
503c1fb9
AS
16396 goto nla_put_failure;
16397
16398 genlmsg_end(msg, hdr);
16399
16400 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16401 NL80211_MCGRP_MLME, GFP_KERNEL);
16402 return;
16403
b23aa676 16404 nla_put_failure:
b23aa676 16405 nlmsg_free(msg);
b23aa676
SO
16406}
16407
16408void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
16409 struct net_device *netdev, u16 reason,
667503dd 16410 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
16411{
16412 struct sk_buff *msg;
16413 void *hdr;
16414
4ef8c1c9 16415 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
16416 if (!msg)
16417 return;
16418
16419 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
16420 if (!hdr) {
16421 nlmsg_free(msg);
16422 return;
16423 }
16424
9360ffd1
DM
16425 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16426 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
86b6c465 16427 (reason &&
9360ffd1
DM
16428 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
16429 (from_ap &&
16430 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
16431 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
16432 goto nla_put_failure;
b23aa676 16433
3b7b72ee 16434 genlmsg_end(msg, hdr);
b23aa676 16435
68eb5503 16436 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16437 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
16438 return;
16439
16440 nla_put_failure:
b23aa676 16441 nlmsg_free(msg);
b23aa676
SO
16442}
16443
04a773ad
JB
16444void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
16445 struct net_device *netdev, const u8 *bssid,
16446 gfp_t gfp)
16447{
16448 struct sk_buff *msg;
16449 void *hdr;
16450
fd2120ca 16451 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
16452 if (!msg)
16453 return;
16454
16455 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
16456 if (!hdr) {
16457 nlmsg_free(msg);
16458 return;
16459 }
16460
9360ffd1
DM
16461 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16462 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16463 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
16464 goto nla_put_failure;
04a773ad 16465
3b7b72ee 16466 genlmsg_end(msg, hdr);
04a773ad 16467
68eb5503 16468 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16469 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
16470 return;
16471
16472 nla_put_failure:
04a773ad
JB
16473 nlmsg_free(msg);
16474}
16475
947add36 16476void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
ecbc12ad
BC
16477 const u8 *ie, u8 ie_len,
16478 int sig_dbm, gfp_t gfp)
c93b5e71 16479{
947add36 16480 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16481 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
16482 struct sk_buff *msg;
16483 void *hdr;
16484
947add36
JB
16485 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
16486 return;
16487
16488 trace_cfg80211_notify_new_peer_candidate(dev, addr);
16489
4ef8c1c9 16490 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
16491 if (!msg)
16492 return;
16493
16494 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
16495 if (!hdr) {
16496 nlmsg_free(msg);
16497 return;
16498 }
16499
9360ffd1 16500 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
16501 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16502 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1 16503 (ie_len && ie &&
ecbc12ad
BC
16504 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
16505 (sig_dbm &&
16506 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
9360ffd1 16507 goto nla_put_failure;
c93b5e71 16508
3b7b72ee 16509 genlmsg_end(msg, hdr);
c93b5e71 16510
68eb5503 16511 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16512 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
16513 return;
16514
16515 nla_put_failure:
c93b5e71
JC
16516 nlmsg_free(msg);
16517}
947add36 16518EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 16519
a3b8b056
JM
16520void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
16521 struct net_device *netdev, const u8 *addr,
16522 enum nl80211_key_type key_type, int key_id,
e6d6e342 16523 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
16524{
16525 struct sk_buff *msg;
16526 void *hdr;
16527
e6d6e342 16528 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
16529 if (!msg)
16530 return;
16531
16532 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
16533 if (!hdr) {
16534 nlmsg_free(msg);
16535 return;
16536 }
16537
9360ffd1
DM
16538 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16539 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16540 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
16541 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
16542 (key_id != -1 &&
16543 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
16544 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
16545 goto nla_put_failure;
a3b8b056 16546
3b7b72ee 16547 genlmsg_end(msg, hdr);
a3b8b056 16548
68eb5503 16549 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16550 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
16551 return;
16552
16553 nla_put_failure:
a3b8b056
JM
16554 nlmsg_free(msg);
16555}
16556
6bad8766
LR
16557void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
16558 struct ieee80211_channel *channel_before,
16559 struct ieee80211_channel *channel_after)
16560{
16561 struct sk_buff *msg;
16562 void *hdr;
16563 struct nlattr *nl_freq;
16564
fd2120ca 16565 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
16566 if (!msg)
16567 return;
16568
16569 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
16570 if (!hdr) {
16571 nlmsg_free(msg);
16572 return;
16573 }
16574
16575 /*
16576 * Since we are applying the beacon hint to a wiphy we know its
16577 * wiphy_idx is valid
16578 */
9360ffd1
DM
16579 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
16580 goto nla_put_failure;
6bad8766
LR
16581
16582 /* Before */
ae0be8de 16583 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_BEFORE);
6bad8766
LR
16584 if (!nl_freq)
16585 goto nla_put_failure;
50f32718
HD
16586
16587 if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
6bad8766
LR
16588 goto nla_put_failure;
16589 nla_nest_end(msg, nl_freq);
16590
16591 /* After */
ae0be8de 16592 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_AFTER);
6bad8766
LR
16593 if (!nl_freq)
16594 goto nla_put_failure;
50f32718
HD
16595
16596 if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
6bad8766
LR
16597 goto nla_put_failure;
16598 nla_nest_end(msg, nl_freq);
16599
3b7b72ee 16600 genlmsg_end(msg, hdr);
6bad8766 16601
463d0183 16602 rcu_read_lock();
68eb5503 16603 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 16604 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 16605 rcu_read_unlock();
6bad8766
LR
16606
16607 return;
16608
16609nla_put_failure:
6bad8766
LR
16610 nlmsg_free(msg);
16611}
16612
9588bbd5
JM
16613static void nl80211_send_remain_on_chan_event(
16614 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 16615 struct wireless_dev *wdev, u64 cookie,
9588bbd5 16616 struct ieee80211_channel *chan,
9588bbd5
JM
16617 unsigned int duration, gfp_t gfp)
16618{
16619 struct sk_buff *msg;
16620 void *hdr;
16621
16622 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16623 if (!msg)
16624 return;
16625
16626 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16627 if (!hdr) {
16628 nlmsg_free(msg);
16629 return;
16630 }
16631
9360ffd1 16632 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16633 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16634 wdev->netdev->ifindex)) ||
2dad624e
ND
16635 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16636 NL80211_ATTR_PAD) ||
9360ffd1 16637 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
16638 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
16639 NL80211_CHAN_NO_HT) ||
2dad624e
ND
16640 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
16641 NL80211_ATTR_PAD))
9360ffd1 16642 goto nla_put_failure;
9588bbd5 16643
9360ffd1
DM
16644 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
16645 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
16646 goto nla_put_failure;
9588bbd5 16647
3b7b72ee 16648 genlmsg_end(msg, hdr);
9588bbd5 16649
68eb5503 16650 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16651 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
16652 return;
16653
16654 nla_put_failure:
9588bbd5
JM
16655 nlmsg_free(msg);
16656}
16657
947add36
JB
16658void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
16659 struct ieee80211_channel *chan,
16660 unsigned int duration, gfp_t gfp)
9588bbd5 16661{
947add36 16662 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16663 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
16664
16665 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 16666 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 16667 rdev, wdev, cookie, chan,
42d97a59 16668 duration, gfp);
9588bbd5 16669}
947add36 16670EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 16671
947add36
JB
16672void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
16673 struct ieee80211_channel *chan,
16674 gfp_t gfp)
9588bbd5 16675{
947add36 16676 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16677 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
16678
16679 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 16680 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 16681 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 16682}
947add36 16683EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 16684
1c38c7f2
JP
16685void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
16686 struct ieee80211_channel *chan,
16687 gfp_t gfp)
16688{
16689 struct wiphy *wiphy = wdev->wiphy;
16690 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
16691
16692 trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
16693 nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
16694 rdev, wdev, cookie, chan, 0, gfp);
16695}
16696EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
16697
947add36
JB
16698void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
16699 struct station_info *sinfo, gfp_t gfp)
98b62183 16700{
947add36 16701 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16702 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
16703 struct sk_buff *msg;
16704
947add36
JB
16705 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
16706
58050fce 16707 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
16708 if (!msg)
16709 return;
16710
cf5ead82 16711 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 16712 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
16713 nlmsg_free(msg);
16714 return;
16715 }
16716
68eb5503 16717 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16718 NL80211_MCGRP_MLME, gfp);
98b62183 16719}
947add36 16720EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 16721
cf5ead82
JB
16722void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
16723 struct station_info *sinfo, gfp_t gfp)
ec15e68b 16724{
947add36 16725 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16726 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 16727 struct sk_buff *msg;
73887fd9 16728 struct station_info empty_sinfo = {};
cf5ead82 16729
73887fd9
JB
16730 if (!sinfo)
16731 sinfo = &empty_sinfo;
ec15e68b 16732
947add36
JB
16733 trace_cfg80211_del_sta(dev, mac_addr);
16734
58050fce 16735 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7ea3e110
JB
16736 if (!msg) {
16737 cfg80211_sinfo_release_content(sinfo);
73887fd9 16738 return;
7ea3e110 16739 }
ec15e68b 16740
cf5ead82 16741 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 16742 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b 16743 nlmsg_free(msg);
73887fd9 16744 return;
ec15e68b
JM
16745 }
16746
68eb5503 16747 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16748 NL80211_MCGRP_MLME, gfp);
ec15e68b 16749}
cf5ead82 16750EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 16751
947add36
JB
16752void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
16753 enum nl80211_connect_failed_reason reason,
16754 gfp_t gfp)
ed44a951 16755{
947add36 16756 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16757 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
16758 struct sk_buff *msg;
16759 void *hdr;
16760
16761 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
16762 if (!msg)
16763 return;
16764
16765 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
16766 if (!hdr) {
16767 nlmsg_free(msg);
16768 return;
16769 }
16770
16771 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16772 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
16773 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
16774 goto nla_put_failure;
16775
16776 genlmsg_end(msg, hdr);
16777
68eb5503 16778 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16779 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
16780 return;
16781
16782 nla_put_failure:
ed44a951
PP
16783 nlmsg_free(msg);
16784}
947add36 16785EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 16786
b92ab5d8
JB
16787static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
16788 const u8 *addr, gfp_t gfp)
28946da7
JB
16789{
16790 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16791 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
16792 struct sk_buff *msg;
16793 void *hdr;
6aa7de05 16794 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 16795
15e47304 16796 if (!nlportid)
28946da7
JB
16797 return false;
16798
16799 msg = nlmsg_new(100, gfp);
16800 if (!msg)
16801 return true;
16802
b92ab5d8 16803 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
16804 if (!hdr) {
16805 nlmsg_free(msg);
16806 return true;
16807 }
16808
9360ffd1
DM
16809 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16810 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16811 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
16812 goto nla_put_failure;
28946da7 16813
9c90a9f6 16814 genlmsg_end(msg, hdr);
15e47304 16815 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
16816 return true;
16817
16818 nla_put_failure:
28946da7
JB
16819 nlmsg_free(msg);
16820 return true;
16821}
16822
947add36
JB
16823bool cfg80211_rx_spurious_frame(struct net_device *dev,
16824 const u8 *addr, gfp_t gfp)
b92ab5d8 16825{
947add36
JB
16826 struct wireless_dev *wdev = dev->ieee80211_ptr;
16827 bool ret;
16828
16829 trace_cfg80211_rx_spurious_frame(dev, addr);
16830
16831 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
16832 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
16833 trace_cfg80211_return_bool(false);
16834 return false;
16835 }
16836 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
16837 addr, gfp);
16838 trace_cfg80211_return_bool(ret);
16839 return ret;
b92ab5d8 16840}
947add36 16841EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 16842
947add36
JB
16843bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
16844 const u8 *addr, gfp_t gfp)
b92ab5d8 16845{
947add36
JB
16846 struct wireless_dev *wdev = dev->ieee80211_ptr;
16847 bool ret;
16848
16849 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
16850
16851 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
16852 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
16853 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
16854 trace_cfg80211_return_bool(false);
16855 return false;
16856 }
16857 ret = __nl80211_unexpected_frame(dev,
16858 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
16859 addr, gfp);
16860 trace_cfg80211_return_bool(ret);
16861 return ret;
b92ab5d8 16862}
947add36 16863EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 16864
2e161f78 16865int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 16866 struct wireless_dev *wdev, u32 nlportid,
804483e9 16867 int freq, int sig_dbm,
19504cf5 16868 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 16869{
71bbc994 16870 struct net_device *netdev = wdev->netdev;
026331c4
JM
16871 struct sk_buff *msg;
16872 void *hdr;
026331c4 16873
4ef8c1c9 16874 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
16875 if (!msg)
16876 return -ENOMEM;
16877
2e161f78 16878 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
16879 if (!hdr) {
16880 nlmsg_free(msg);
16881 return -ENOMEM;
16882 }
16883
9360ffd1 16884 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16885 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16886 netdev->ifindex)) ||
2dad624e
ND
16887 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16888 NL80211_ATTR_PAD) ||
e76fede8 16889 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(freq)) ||
942ba88b 16890 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq % 1000) ||
9360ffd1
DM
16891 (sig_dbm &&
16892 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
16893 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
16894 (flags &&
16895 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 16896 goto nla_put_failure;
026331c4 16897
3b7b72ee 16898 genlmsg_end(msg, hdr);
026331c4 16899
15e47304 16900 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
16901
16902 nla_put_failure:
026331c4
JM
16903 nlmsg_free(msg);
16904 return -ENOBUFS;
16905}
16906
dca9ca2d
MT
16907static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
16908 const u8 *buf, size_t len, bool ack,
16909 gfp_t gfp, enum nl80211_commands command)
026331c4 16910{
947add36 16911 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16912 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 16913 struct net_device *netdev = wdev->netdev;
026331c4
JM
16914 struct sk_buff *msg;
16915 void *hdr;
16916
dca9ca2d
MT
16917 if (command == NL80211_CMD_FRAME_TX_STATUS)
16918 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
16919 else
16920 trace_cfg80211_control_port_tx_status(wdev, cookie, ack);
947add36 16921
4ef8c1c9 16922 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
16923 if (!msg)
16924 return;
16925
dca9ca2d 16926 hdr = nl80211hdr_put(msg, 0, 0, 0, command);
026331c4
JM
16927 if (!hdr) {
16928 nlmsg_free(msg);
16929 return;
16930 }
16931
9360ffd1 16932 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16933 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16934 netdev->ifindex)) ||
2dad624e
ND
16935 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16936 NL80211_ATTR_PAD) ||
9360ffd1 16937 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
16938 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
16939 NL80211_ATTR_PAD) ||
9360ffd1
DM
16940 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
16941 goto nla_put_failure;
026331c4 16942
3b7b72ee 16943 genlmsg_end(msg, hdr);
026331c4 16944
68eb5503 16945 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16946 NL80211_MCGRP_MLME, gfp);
026331c4
JM
16947 return;
16948
dca9ca2d 16949nla_put_failure:
026331c4
JM
16950 nlmsg_free(msg);
16951}
dca9ca2d
MT
16952
16953void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
16954 const u8 *buf, size_t len, bool ack,
16955 gfp_t gfp)
16956{
16957 nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
16958 NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS);
16959}
16960EXPORT_SYMBOL(cfg80211_control_port_tx_status);
16961
16962void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
16963 const u8 *buf, size_t len, bool ack, gfp_t gfp)
16964{
16965 nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
16966 NL80211_CMD_FRAME_TX_STATUS);
16967}
947add36 16968EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 16969
6a671a50 16970static int __nl80211_rx_control_port(struct net_device *dev,
a948f713 16971 struct sk_buff *skb,
6a671a50
DK
16972 bool unencrypted, gfp_t gfp)
16973{
16974 struct wireless_dev *wdev = dev->ieee80211_ptr;
16975 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
a948f713 16976 struct ethhdr *ehdr = eth_hdr(skb);
8d74a623 16977 const u8 *addr = ehdr->h_source;
a948f713 16978 u16 proto = be16_to_cpu(skb->protocol);
6a671a50
DK
16979 struct sk_buff *msg;
16980 void *hdr;
a948f713
DK
16981 struct nlattr *frame;
16982
6a671a50
DK
16983 u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
16984
16985 if (!nlportid)
16986 return -ENOENT;
16987
a948f713 16988 msg = nlmsg_new(100 + skb->len, gfp);
6a671a50
DK
16989 if (!msg)
16990 return -ENOMEM;
16991
16992 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
16993 if (!hdr) {
16994 nlmsg_free(msg);
16995 return -ENOBUFS;
16996 }
16997
16998 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16999 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17000 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17001 NL80211_ATTR_PAD) ||
8d74a623 17002 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
6a671a50
DK
17003 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
17004 (unencrypted && nla_put_flag(msg,
17005 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
17006 goto nla_put_failure;
17007
a948f713
DK
17008 frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
17009 if (!frame)
17010 goto nla_put_failure;
17011
17012 skb_copy_bits(skb, 0, nla_data(frame), skb->len);
6a671a50
DK
17013 genlmsg_end(msg, hdr);
17014
17015 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
17016
17017 nla_put_failure:
17018 nlmsg_free(msg);
17019 return -ENOBUFS;
17020}
17021
17022bool cfg80211_rx_control_port(struct net_device *dev,
a948f713 17023 struct sk_buff *skb, bool unencrypted)
6a671a50
DK
17024{
17025 int ret;
17026
a948f713
DK
17027 trace_cfg80211_rx_control_port(dev, skb, unencrypted);
17028 ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC);
6a671a50
DK
17029 trace_cfg80211_return_bool(ret == 0);
17030 return ret == 0;
17031}
17032EXPORT_SYMBOL(cfg80211_rx_control_port);
17033
5b97f49d
JB
17034static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
17035 const char *mac, gfp_t gfp)
d6dc1a38 17036{
947add36 17037 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
17038 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
17039 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17040 void **cb;
947add36 17041
d6dc1a38 17042 if (!msg)
5b97f49d 17043 return NULL;
d6dc1a38 17044
5b97f49d
JB
17045 cb = (void **)msg->cb;
17046
17047 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
17048 if (!cb[0]) {
d6dc1a38 17049 nlmsg_free(msg);
5b97f49d 17050 return NULL;
d6dc1a38
JO
17051 }
17052
9360ffd1 17053 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 17054 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 17055 goto nla_put_failure;
d6dc1a38 17056
5b97f49d 17057 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
17058 goto nla_put_failure;
17059
ae0be8de 17060 cb[1] = nla_nest_start_noflag(msg, NL80211_ATTR_CQM);
5b97f49d 17061 if (!cb[1])
9360ffd1 17062 goto nla_put_failure;
d6dc1a38 17063
5b97f49d 17064 cb[2] = rdev;
d6dc1a38 17065
5b97f49d
JB
17066 return msg;
17067 nla_put_failure:
17068 nlmsg_free(msg);
17069 return NULL;
17070}
17071
17072static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
17073{
17074 void **cb = (void **)msg->cb;
17075 struct cfg80211_registered_device *rdev = cb[2];
17076
17077 nla_nest_end(msg, cb[1]);
17078 genlmsg_end(msg, cb[0]);
17079
17080 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 17081
68eb5503 17082 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17083 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
17084}
17085
17086void cfg80211_cqm_rssi_notify(struct net_device *dev,
17087 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 17088 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
17089{
17090 struct sk_buff *msg;
4a4b8169
AZ
17091 struct wireless_dev *wdev = dev->ieee80211_ptr;
17092 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 17093
bee427b8 17094 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 17095
98f03342
JB
17096 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
17097 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
17098 return;
17099
4a4b8169
AZ
17100 if (wdev->cqm_config) {
17101 wdev->cqm_config->last_rssi_event_value = rssi_level;
17102
17103 cfg80211_cqm_rssi_update(rdev, dev);
17104
17105 if (rssi_level == 0)
17106 rssi_level = wdev->cqm_config->last_rssi_event_value;
17107 }
17108
5b97f49d
JB
17109 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
17110 if (!msg)
17111 return;
17112
17113 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
17114 rssi_event))
17115 goto nla_put_failure;
17116
bee427b8
AZ
17117 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
17118 rssi_level))
17119 goto nla_put_failure;
17120
5b97f49d
JB
17121 cfg80211_send_cqm(msg, gfp);
17122
d6dc1a38
JO
17123 return;
17124
17125 nla_put_failure:
d6dc1a38
JO
17126 nlmsg_free(msg);
17127}
947add36 17128EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 17129
5b97f49d
JB
17130void cfg80211_cqm_txe_notify(struct net_device *dev,
17131 const u8 *peer, u32 num_packets,
17132 u32 rate, u32 intvl, gfp_t gfp)
17133{
17134 struct sk_buff *msg;
17135
17136 msg = cfg80211_prepare_cqm(dev, peer, gfp);
17137 if (!msg)
17138 return;
17139
17140 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
17141 goto nla_put_failure;
17142
17143 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
17144 goto nla_put_failure;
17145
17146 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
17147 goto nla_put_failure;
17148
17149 cfg80211_send_cqm(msg, gfp);
17150 return;
17151
17152 nla_put_failure:
17153 nlmsg_free(msg);
17154}
17155EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
17156
17157void cfg80211_cqm_pktloss_notify(struct net_device *dev,
17158 const u8 *peer, u32 num_packets, gfp_t gfp)
17159{
17160 struct sk_buff *msg;
17161
17162 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
17163
17164 msg = cfg80211_prepare_cqm(dev, peer, gfp);
17165 if (!msg)
17166 return;
17167
17168 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
17169 goto nla_put_failure;
17170
17171 cfg80211_send_cqm(msg, gfp);
17172 return;
17173
17174 nla_put_failure:
17175 nlmsg_free(msg);
17176}
17177EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
17178
98f03342
JB
17179void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
17180{
17181 struct sk_buff *msg;
17182
17183 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
17184 if (!msg)
17185 return;
17186
17187 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
17188 goto nla_put_failure;
17189
17190 cfg80211_send_cqm(msg, gfp);
17191 return;
17192
17193 nla_put_failure:
17194 nlmsg_free(msg);
17195}
17196EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
17197
947add36
JB
17198static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
17199 struct net_device *netdev, const u8 *bssid,
17200 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
17201{
17202 struct sk_buff *msg;
17203 struct nlattr *rekey_attr;
17204 void *hdr;
17205
58050fce 17206 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
17207 if (!msg)
17208 return;
17209
17210 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
17211 if (!hdr) {
17212 nlmsg_free(msg);
17213 return;
17214 }
17215
9360ffd1
DM
17216 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17217 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17218 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
17219 goto nla_put_failure;
e5497d76 17220
ae0be8de 17221 rekey_attr = nla_nest_start_noflag(msg, NL80211_ATTR_REKEY_DATA);
e5497d76
JB
17222 if (!rekey_attr)
17223 goto nla_put_failure;
17224
9360ffd1
DM
17225 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
17226 NL80211_REPLAY_CTR_LEN, replay_ctr))
17227 goto nla_put_failure;
e5497d76
JB
17228
17229 nla_nest_end(msg, rekey_attr);
17230
3b7b72ee 17231 genlmsg_end(msg, hdr);
e5497d76 17232
68eb5503 17233 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17234 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
17235 return;
17236
17237 nla_put_failure:
e5497d76
JB
17238 nlmsg_free(msg);
17239}
17240
947add36
JB
17241void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
17242 const u8 *replay_ctr, gfp_t gfp)
17243{
17244 struct wireless_dev *wdev = dev->ieee80211_ptr;
17245 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17246 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17247
17248 trace_cfg80211_gtk_rekey_notify(dev, bssid);
17249 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
17250}
17251EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
17252
17253static void
17254nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
17255 struct net_device *netdev, int index,
17256 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
17257{
17258 struct sk_buff *msg;
17259 struct nlattr *attr;
17260 void *hdr;
17261
58050fce 17262 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
17263 if (!msg)
17264 return;
17265
17266 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
17267 if (!hdr) {
17268 nlmsg_free(msg);
17269 return;
17270 }
17271
9360ffd1
DM
17272 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17273 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
17274 goto nla_put_failure;
c9df56b4 17275
ae0be8de 17276 attr = nla_nest_start_noflag(msg, NL80211_ATTR_PMKSA_CANDIDATE);
c9df56b4
JM
17277 if (!attr)
17278 goto nla_put_failure;
17279
9360ffd1
DM
17280 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
17281 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
17282 (preauth &&
17283 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
17284 goto nla_put_failure;
c9df56b4
JM
17285
17286 nla_nest_end(msg, attr);
17287
3b7b72ee 17288 genlmsg_end(msg, hdr);
c9df56b4 17289
68eb5503 17290 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17291 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
17292 return;
17293
17294 nla_put_failure:
c9df56b4
JM
17295 nlmsg_free(msg);
17296}
17297
947add36
JB
17298void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
17299 const u8 *bssid, bool preauth, gfp_t gfp)
17300{
17301 struct wireless_dev *wdev = dev->ieee80211_ptr;
17302 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17303 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17304
17305 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
17306 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
17307}
17308EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
17309
17310static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
17311 struct net_device *netdev,
17312 struct cfg80211_chan_def *chandef,
f8d7552e
LC
17313 gfp_t gfp,
17314 enum nl80211_commands notif,
669b8413 17315 u8 count, bool quiet)
5314526b
TP
17316{
17317 struct sk_buff *msg;
17318 void *hdr;
17319
58050fce 17320 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
17321 if (!msg)
17322 return;
17323
f8d7552e 17324 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
17325 if (!hdr) {
17326 nlmsg_free(msg);
17327 return;
17328 }
17329
683b6d3b
JB
17330 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
17331 goto nla_put_failure;
17332
17333 if (nl80211_send_chandef(msg, chandef))
7eab0f64 17334 goto nla_put_failure;
5314526b 17335
669b8413
JB
17336 if (notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) {
17337 if (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count))
f8d7552e 17338 goto nla_put_failure;
669b8413
JB
17339 if (quiet &&
17340 nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX))
f8d7552e 17341 goto nla_put_failure;
669b8413 17342 }
f8d7552e 17343
5314526b
TP
17344 genlmsg_end(msg, hdr);
17345
68eb5503 17346 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17347 NL80211_MCGRP_MLME, gfp);
5314526b
TP
17348 return;
17349
17350 nla_put_failure:
5314526b
TP
17351 nlmsg_free(msg);
17352}
17353
947add36
JB
17354void cfg80211_ch_switch_notify(struct net_device *dev,
17355 struct cfg80211_chan_def *chandef)
84f10708 17356{
947add36
JB
17357 struct wireless_dev *wdev = dev->ieee80211_ptr;
17358 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17359 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 17360
e487eaeb 17361 ASSERT_WDEV_LOCK(wdev);
947add36 17362
e487eaeb 17363 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 17364
9e0e2961 17365 wdev->chandef = *chandef;
96f55f12 17366 wdev->preset_chandef = *chandef;
5dc8cdce
SM
17367
17368 if (wdev->iftype == NL80211_IFTYPE_STATION &&
17369 !WARN_ON(!wdev->current_bss))
0afd425b 17370 cfg80211_update_assoc_bss_entry(wdev, chandef->chan);
5dc8cdce 17371
d34990bb
MV
17372 cfg80211_sched_dfs_chan_update(rdev);
17373
f8d7552e 17374 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
669b8413 17375 NL80211_CMD_CH_SWITCH_NOTIFY, 0, false);
947add36
JB
17376}
17377EXPORT_SYMBOL(cfg80211_ch_switch_notify);
17378
f8d7552e
LC
17379void cfg80211_ch_switch_started_notify(struct net_device *dev,
17380 struct cfg80211_chan_def *chandef,
669b8413 17381 u8 count, bool quiet)
f8d7552e
LC
17382{
17383 struct wireless_dev *wdev = dev->ieee80211_ptr;
17384 struct wiphy *wiphy = wdev->wiphy;
17385 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
17386
17387 trace_cfg80211_ch_switch_started_notify(dev, chandef);
17388
17389 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
669b8413
JB
17390 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
17391 count, quiet);
f8d7552e
LC
17392}
17393EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
17394
04f39047
SW
17395void
17396nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 17397 const struct cfg80211_chan_def *chandef,
04f39047
SW
17398 enum nl80211_radar_event event,
17399 struct net_device *netdev, gfp_t gfp)
17400{
17401 struct sk_buff *msg;
17402 void *hdr;
17403
17404 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17405 if (!msg)
17406 return;
17407
17408 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
17409 if (!hdr) {
17410 nlmsg_free(msg);
17411 return;
17412 }
17413
17414 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
17415 goto nla_put_failure;
17416
17417 /* NOP and radar events don't need a netdev parameter */
17418 if (netdev) {
17419 struct wireless_dev *wdev = netdev->ieee80211_ptr;
17420
17421 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
17422 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17423 NL80211_ATTR_PAD))
04f39047
SW
17424 goto nla_put_failure;
17425 }
17426
17427 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
17428 goto nla_put_failure;
17429
17430 if (nl80211_send_chandef(msg, chandef))
17431 goto nla_put_failure;
17432
9c90a9f6 17433 genlmsg_end(msg, hdr);
04f39047 17434
68eb5503 17435 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17436 NL80211_MCGRP_MLME, gfp);
04f39047
SW
17437 return;
17438
17439 nla_put_failure:
04f39047
SW
17440 nlmsg_free(msg);
17441}
17442
466b9936 17443void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
17444 struct sta_opmode_info *sta_opmode,
17445 gfp_t gfp)
17446{
17447 struct sk_buff *msg;
17448 struct wireless_dev *wdev = dev->ieee80211_ptr;
17449 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
17450 void *hdr;
17451
17452 if (WARN_ON(!mac))
17453 return;
17454
17455 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17456 if (!msg)
17457 return;
17458
17459 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
17460 if (!hdr) {
17461 nlmsg_free(msg);
17462 return;
17463 }
17464
17465 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
17466 goto nla_put_failure;
17467
17468 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
17469 goto nla_put_failure;
17470
17471 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
17472 goto nla_put_failure;
17473
17474 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
17475 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
17476 goto nla_put_failure;
17477
17478 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
0016d320 17479 nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
466b9936 17480 goto nla_put_failure;
17481
17482 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
17483 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
17484 goto nla_put_failure;
17485
17486 genlmsg_end(msg, hdr);
17487
17488 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17489 NL80211_MCGRP_MLME, gfp);
17490
17491 return;
17492
17493nla_put_failure:
17494 nlmsg_free(msg);
17495}
17496EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
17497
7f6cf311 17498void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
c4b50cd3
VN
17499 u64 cookie, bool acked, s32 ack_signal,
17500 bool is_valid_ack_signal, gfp_t gfp)
7f6cf311
JB
17501{
17502 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 17503 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
17504 struct sk_buff *msg;
17505 void *hdr;
7f6cf311 17506
4ee3e063
BL
17507 trace_cfg80211_probe_status(dev, addr, cookie, acked);
17508
58050fce 17509 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 17510
7f6cf311
JB
17511 if (!msg)
17512 return;
17513
17514 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
17515 if (!hdr) {
17516 nlmsg_free(msg);
17517 return;
17518 }
17519
9360ffd1
DM
17520 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17521 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17522 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
17523 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
17524 NL80211_ATTR_PAD) ||
c4b50cd3
VN
17525 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
17526 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
17527 ack_signal)))
9360ffd1 17528 goto nla_put_failure;
7f6cf311 17529
9c90a9f6 17530 genlmsg_end(msg, hdr);
7f6cf311 17531
68eb5503 17532 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17533 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
17534 return;
17535
17536 nla_put_failure:
7f6cf311
JB
17537 nlmsg_free(msg);
17538}
17539EXPORT_SYMBOL(cfg80211_probe_status);
17540
e76fede8
TP
17541void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame,
17542 size_t len, int freq, int sig_dbm)
5e760230 17543{
f26cbf40 17544 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
17545 struct sk_buff *msg;
17546 void *hdr;
37c73b5f 17547 struct cfg80211_beacon_registration *reg;
5e760230 17548
4ee3e063
BL
17549 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
17550
37c73b5f
BG
17551 spin_lock_bh(&rdev->beacon_registrations_lock);
17552 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
17553 msg = nlmsg_new(len + 100, GFP_ATOMIC);
17554 if (!msg) {
17555 spin_unlock_bh(&rdev->beacon_registrations_lock);
17556 return;
17557 }
5e760230 17558
37c73b5f
BG
17559 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
17560 if (!hdr)
17561 goto nla_put_failure;
5e760230 17562
37c73b5f
BG
17563 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17564 (freq &&
942ba88b
TP
17565 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
17566 KHZ_TO_MHZ(freq)) ||
17567 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
17568 freq % 1000))) ||
37c73b5f
BG
17569 (sig_dbm &&
17570 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
17571 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
17572 goto nla_put_failure;
5e760230 17573
37c73b5f 17574 genlmsg_end(msg, hdr);
5e760230 17575
37c73b5f
BG
17576 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
17577 }
17578 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
17579 return;
17580
17581 nla_put_failure:
37c73b5f 17582 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
17583 nlmsg_free(msg);
17584}
e76fede8 17585EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz);
5e760230 17586
cd8f7cb4 17587#ifdef CONFIG_PM
8cd4d456
LC
17588static int cfg80211_net_detect_results(struct sk_buff *msg,
17589 struct cfg80211_wowlan_wakeup *wakeup)
17590{
17591 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
17592 struct nlattr *nl_results, *nl_match, *nl_freqs;
17593 int i, j;
17594
ae0be8de
MK
17595 nl_results = nla_nest_start_noflag(msg,
17596 NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
8cd4d456
LC
17597 if (!nl_results)
17598 return -EMSGSIZE;
17599
17600 for (i = 0; i < nd->n_matches; i++) {
17601 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
17602
ae0be8de 17603 nl_match = nla_nest_start_noflag(msg, i);
8cd4d456
LC
17604 if (!nl_match)
17605 break;
17606
17607 /* The SSID attribute is optional in nl80211, but for
17608 * simplicity reasons it's always present in the
17609 * cfg80211 structure. If a driver can't pass the
17610 * SSID, that needs to be changed. A zero length SSID
17611 * is still a valid SSID (wildcard), so it cannot be
17612 * used for this purpose.
17613 */
17614 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
17615 match->ssid.ssid)) {
17616 nla_nest_cancel(msg, nl_match);
17617 goto out;
17618 }
17619
17620 if (match->n_channels) {
ae0be8de
MK
17621 nl_freqs = nla_nest_start_noflag(msg,
17622 NL80211_ATTR_SCAN_FREQUENCIES);
8cd4d456
LC
17623 if (!nl_freqs) {
17624 nla_nest_cancel(msg, nl_match);
17625 goto out;
17626 }
17627
17628 for (j = 0; j < match->n_channels; j++) {
5528fae8 17629 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
17630 nla_nest_cancel(msg, nl_freqs);
17631 nla_nest_cancel(msg, nl_match);
17632 goto out;
17633 }
17634 }
17635
17636 nla_nest_end(msg, nl_freqs);
17637 }
17638
17639 nla_nest_end(msg, nl_match);
17640 }
17641
17642out:
17643 nla_nest_end(msg, nl_results);
17644 return 0;
17645}
17646
cd8f7cb4
JB
17647void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
17648 struct cfg80211_wowlan_wakeup *wakeup,
17649 gfp_t gfp)
17650{
f26cbf40 17651 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
17652 struct sk_buff *msg;
17653 void *hdr;
9c90a9f6 17654 int size = 200;
cd8f7cb4
JB
17655
17656 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
17657
17658 if (wakeup)
17659 size += wakeup->packet_present_len;
17660
17661 msg = nlmsg_new(size, gfp);
17662 if (!msg)
17663 return;
17664
17665 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
17666 if (!hdr)
17667 goto free_msg;
17668
17669 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
17670 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17671 NL80211_ATTR_PAD))
cd8f7cb4
JB
17672 goto free_msg;
17673
17674 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
17675 wdev->netdev->ifindex))
17676 goto free_msg;
17677
17678 if (wakeup) {
17679 struct nlattr *reasons;
17680
ae0be8de
MK
17681 reasons = nla_nest_start_noflag(msg,
17682 NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
17683 if (!reasons)
17684 goto free_msg;
cd8f7cb4
JB
17685
17686 if (wakeup->disconnect &&
17687 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
17688 goto free_msg;
17689 if (wakeup->magic_pkt &&
17690 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
17691 goto free_msg;
17692 if (wakeup->gtk_rekey_failure &&
17693 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
17694 goto free_msg;
17695 if (wakeup->eap_identity_req &&
17696 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
17697 goto free_msg;
17698 if (wakeup->four_way_handshake &&
17699 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
17700 goto free_msg;
17701 if (wakeup->rfkill_release &&
17702 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
17703 goto free_msg;
17704
17705 if (wakeup->pattern_idx >= 0 &&
17706 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
17707 wakeup->pattern_idx))
17708 goto free_msg;
17709
ae917c9f
JB
17710 if (wakeup->tcp_match &&
17711 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
17712 goto free_msg;
2a0e047e 17713
ae917c9f
JB
17714 if (wakeup->tcp_connlost &&
17715 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
17716 goto free_msg;
2a0e047e 17717
ae917c9f
JB
17718 if (wakeup->tcp_nomoretokens &&
17719 nla_put_flag(msg,
17720 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
17721 goto free_msg;
2a0e047e 17722
cd8f7cb4
JB
17723 if (wakeup->packet) {
17724 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
17725 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
17726
17727 if (!wakeup->packet_80211) {
17728 pkt_attr =
17729 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
17730 len_attr =
17731 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
17732 }
17733
17734 if (wakeup->packet_len &&
17735 nla_put_u32(msg, len_attr, wakeup->packet_len))
17736 goto free_msg;
17737
17738 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
17739 wakeup->packet))
17740 goto free_msg;
17741 }
17742
8cd4d456
LC
17743 if (wakeup->net_detect &&
17744 cfg80211_net_detect_results(msg, wakeup))
17745 goto free_msg;
17746
cd8f7cb4
JB
17747 nla_nest_end(msg, reasons);
17748 }
17749
9c90a9f6 17750 genlmsg_end(msg, hdr);
cd8f7cb4 17751
68eb5503 17752 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17753 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
17754 return;
17755
17756 free_msg:
17757 nlmsg_free(msg);
17758}
17759EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
17760#endif
17761
3475b094
JM
17762void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
17763 enum nl80211_tdls_operation oper,
17764 u16 reason_code, gfp_t gfp)
17765{
17766 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 17767 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
17768 struct sk_buff *msg;
17769 void *hdr;
3475b094
JM
17770
17771 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
17772 reason_code);
17773
17774 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17775 if (!msg)
17776 return;
17777
17778 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
17779 if (!hdr) {
17780 nlmsg_free(msg);
17781 return;
17782 }
17783
17784 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17785 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17786 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
17787 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
17788 (reason_code > 0 &&
17789 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
17790 goto nla_put_failure;
17791
9c90a9f6 17792 genlmsg_end(msg, hdr);
3475b094 17793
68eb5503 17794 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17795 NL80211_MCGRP_MLME, gfp);
3475b094
JM
17796 return;
17797
17798 nla_put_failure:
3475b094
JM
17799 nlmsg_free(msg);
17800}
17801EXPORT_SYMBOL(cfg80211_tdls_oper_request);
17802
026331c4
JM
17803static int nl80211_netlink_notify(struct notifier_block * nb,
17804 unsigned long state,
17805 void *_notify)
17806{
17807 struct netlink_notify *notify = _notify;
17808 struct cfg80211_registered_device *rdev;
17809 struct wireless_dev *wdev;
37c73b5f 17810 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 17811
8f815cdd 17812 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
17813 return NOTIFY_DONE;
17814
17815 rcu_read_lock();
17816
5e760230 17817 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 17818 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 17819
ca986ad9
AVS
17820 list_for_each_entry_rcu(sched_scan_req,
17821 &rdev->sched_scan_req_list,
17822 list) {
17823 if (sched_scan_req->owner_nlportid == notify->portid) {
17824 sched_scan_req->nl_owner_dead = true;
753aacfd 17825 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 17826 }
753aacfd 17827 }
78f22b6a 17828
53873f13 17829 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 17830 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 17831
ab81007a
JB
17832 if (wdev->owner_nlportid == notify->portid) {
17833 wdev->nl_owner_dead = true;
17834 schedule_work(&rdev->destroy_work);
17835 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 17836 schedule_work(&wdev->disconnect_wk);
ab81007a 17837 }
9bb7e0f2
JB
17838
17839 cfg80211_release_pmsr(wdev, notify->portid);
78f22b6a
JB
17840 }
17841
37c73b5f
BG
17842 spin_lock_bh(&rdev->beacon_registrations_lock);
17843 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
17844 list) {
17845 if (reg->nlportid == notify->portid) {
17846 list_del(&reg->list);
17847 kfree(reg);
17848 break;
17849 }
17850 }
17851 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 17852 }
026331c4
JM
17853
17854 rcu_read_unlock();
17855
05050753
I
17856 /*
17857 * It is possible that the user space process that is controlling the
17858 * indoor setting disappeared, so notify the regulatory core.
17859 */
17860 regulatory_netlink_notify(notify->portid);
6784c7db 17861 return NOTIFY_OK;
026331c4
JM
17862}
17863
17864static struct notifier_block nl80211_netlink_notifier = {
17865 .notifier_call = nl80211_netlink_notify,
17866};
17867
355199e0
JM
17868void cfg80211_ft_event(struct net_device *netdev,
17869 struct cfg80211_ft_event_params *ft_event)
17870{
17871 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 17872 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
17873 struct sk_buff *msg;
17874 void *hdr;
355199e0
JM
17875
17876 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
17877
17878 if (!ft_event->target_ap)
17879 return;
17880
1039d081
DL
17881 msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
17882 GFP_KERNEL);
355199e0
JM
17883 if (!msg)
17884 return;
17885
17886 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
17887 if (!hdr)
17888 goto out;
355199e0 17889
ae917c9f
JB
17890 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17891 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17892 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
17893 goto out;
355199e0 17894
ae917c9f
JB
17895 if (ft_event->ies &&
17896 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
17897 goto out;
17898 if (ft_event->ric_ies &&
17899 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
17900 ft_event->ric_ies))
17901 goto out;
355199e0 17902
9c90a9f6 17903 genlmsg_end(msg, hdr);
355199e0 17904
68eb5503 17905 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17906 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
17907 return;
17908 out:
17909 nlmsg_free(msg);
355199e0
JM
17910}
17911EXPORT_SYMBOL(cfg80211_ft_event);
17912
5de17984
AS
17913void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
17914{
17915 struct cfg80211_registered_device *rdev;
17916 struct sk_buff *msg;
17917 void *hdr;
17918 u32 nlportid;
17919
f26cbf40 17920 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
17921 if (!rdev->crit_proto_nlportid)
17922 return;
17923
17924 nlportid = rdev->crit_proto_nlportid;
17925 rdev->crit_proto_nlportid = 0;
17926
17927 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17928 if (!msg)
17929 return;
17930
17931 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
17932 if (!hdr)
17933 goto nla_put_failure;
17934
17935 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
17936 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17937 NL80211_ATTR_PAD))
5de17984
AS
17938 goto nla_put_failure;
17939
17940 genlmsg_end(msg, hdr);
17941
17942 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
17943 return;
17944
17945 nla_put_failure:
5de17984 17946 nlmsg_free(msg);
5de17984
AS
17947}
17948EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
17949
348baf0e
JB
17950void nl80211_send_ap_stopped(struct wireless_dev *wdev)
17951{
17952 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17953 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
17954 struct sk_buff *msg;
17955 void *hdr;
17956
17957 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17958 if (!msg)
17959 return;
17960
17961 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
17962 if (!hdr)
17963 goto out;
17964
17965 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17966 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
17967 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17968 NL80211_ATTR_PAD))
348baf0e
JB
17969 goto out;
17970
17971 genlmsg_end(msg, hdr);
17972
17973 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
17974 NL80211_MCGRP_MLME, GFP_KERNEL);
17975 return;
17976 out:
17977 nlmsg_free(msg);
17978}
17979
40cbfa90
SD
17980int cfg80211_external_auth_request(struct net_device *dev,
17981 struct cfg80211_external_auth_params *params,
17982 gfp_t gfp)
17983{
17984 struct wireless_dev *wdev = dev->ieee80211_ptr;
17985 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
17986 struct sk_buff *msg;
17987 void *hdr;
17988
17989 if (!wdev->conn_owner_nlportid)
17990 return -EINVAL;
17991
17992 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17993 if (!msg)
17994 return -ENOMEM;
17995
17996 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
17997 if (!hdr)
17998 goto nla_put_failure;
17999
18000 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18001 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18002 nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
18003 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
18004 params->action) ||
18005 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
18006 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
18007 params->ssid.ssid))
18008 goto nla_put_failure;
18009
18010 genlmsg_end(msg, hdr);
18011 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
18012 wdev->conn_owner_nlportid);
18013 return 0;
18014
18015 nla_put_failure:
18016 nlmsg_free(msg);
18017 return -ENOBUFS;
18018}
18019EXPORT_SYMBOL(cfg80211_external_auth_request);
18020
cb74e977
SD
18021void cfg80211_update_owe_info_event(struct net_device *netdev,
18022 struct cfg80211_update_owe_info *owe_info,
18023 gfp_t gfp)
18024{
18025 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
18026 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18027 struct sk_buff *msg;
18028 void *hdr;
18029
18030 trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
18031
18032 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18033 if (!msg)
18034 return;
18035
18036 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
18037 if (!hdr)
18038 goto nla_put_failure;
18039
18040 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18041 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18042 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
18043 goto nla_put_failure;
18044
18045 if (!owe_info->ie_len ||
18046 nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
18047 goto nla_put_failure;
18048
18049 genlmsg_end(msg, hdr);
18050
18051 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18052 NL80211_MCGRP_MLME, gfp);
18053 return;
18054
18055nla_put_failure:
18056 genlmsg_cancel(msg, hdr);
18057 nlmsg_free(msg);
18058}
18059EXPORT_SYMBOL(cfg80211_update_owe_info_event);
18060
55682965
JB
18061/* initialisation/exit functions */
18062
56989f6d 18063int __init nl80211_init(void)
55682965 18064{
0d63cbb5 18065 int err;
55682965 18066
489111e5 18067 err = genl_register_family(&nl80211_fam);
55682965
JB
18068 if (err)
18069 return err;
18070
026331c4
JM
18071 err = netlink_register_notifier(&nl80211_netlink_notifier);
18072 if (err)
18073 goto err_out;
18074
55682965
JB
18075 return 0;
18076 err_out:
18077 genl_unregister_family(&nl80211_fam);
18078 return err;
18079}
18080
18081void nl80211_exit(void)
18082{
026331c4 18083 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
18084 genl_unregister_family(&nl80211_fam);
18085}