mac80211: introduce BSS color collision detection
[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
ea05fd35 8 * Copyright (C) 2018-2022 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];
239729a2 73 u64 wdev_id = 0;
89a54e48
JB
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 232 unsigned int fixedlen, hdrlen;
9a6847ba 233 bool s1g_bcn;
1d47f119 234
9a6847ba
JB
235 if (len < offsetofend(typeof(*mgmt), frame_control))
236 goto err;
237
238 s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
1d47f119
TP
239 if (s1g_bcn) {
240 fixedlen = offsetof(struct ieee80211_ext,
241 u.s1g_beacon.variable);
242 hdrlen = offsetof(struct ieee80211_ext, u.s1g_beacon);
243 } else {
244 fixedlen = offsetof(struct ieee80211_mgmt,
245 u.beacon.variable);
246 hdrlen = offsetof(struct ieee80211_mgmt, u.beacon);
247 }
f88eb7c0
JB
248
249 if (len < fixedlen)
250 goto err;
251
1d47f119 252 if (ieee80211_hdrlen(mgmt->frame_control) != hdrlen)
f88eb7c0
JB
253 goto err;
254
255 data += fixedlen;
256 len -= fixedlen;
257
258 for_each_element(elem, data, len) {
259 /* nothing */
260 }
261
262 if (for_each_element_completed(elem, data, len))
263 return 0;
264
265err:
266 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
267 return -EINVAL;
268}
269
3d7af878
JB
270static int validate_ie_attr(const struct nlattr *attr,
271 struct netlink_ext_ack *extack)
272{
9f308616
JB
273 const u8 *data = nla_data(attr);
274 unsigned int len = nla_len(attr);
7388afe0 275 const struct element *elem;
3d7af878 276
9f308616
JB
277 for_each_element(elem, data, len) {
278 /* nothing */
3d7af878
JB
279 }
280
9f308616
JB
281 if (for_each_element_completed(elem, data, len))
282 return 0;
283
3d7af878
JB
284 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed information elements");
285 return -EINVAL;
286}
287
a3a20feb
JB
288static int validate_he_capa(const struct nlattr *attr,
289 struct netlink_ext_ack *extack)
290{
291 if (!ieee80211_he_capa_size_ok(nla_data(attr), nla_len(attr)))
292 return -EINVAL;
293
294 return 0;
295}
296
55682965 297/* policy for the attributes */
d15da2a2
JB
298static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
299
81e54d08
PKC
300static const struct nla_policy
301nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
302 [NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
303 [NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
304 .len = U8_MAX },
305 [NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
306 .len = U8_MAX },
307};
308
9bb7e0f2
JB
309static const struct nla_policy
310nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
311 [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
312 [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
313 [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
314 NLA_POLICY_MAX(NLA_U8, 15),
315 [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
316 [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
317 NLA_POLICY_MAX(NLA_U8, 15),
318 [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
ea18709a 319 NLA_POLICY_MAX(NLA_U8, 31),
9bb7e0f2
JB
320 [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
321 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
322 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
efb5520d
AS
323 [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG },
324 [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG },
73807523 325 [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG },
9bb7e0f2
JB
326};
327
328static const struct nla_policy
329nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
330 [NL80211_PMSR_TYPE_FTM] =
23323289 331 NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
9bb7e0f2
JB
332};
333
334static const struct nla_policy
335nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
336 [NL80211_PMSR_REQ_ATTR_DATA] =
23323289 337 NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
9bb7e0f2
JB
338 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
339};
340
341static const struct nla_policy
aeddc05f 342nl80211_pmsr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
9bb7e0f2 343 [NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
d15da2a2 344 [NL80211_PMSR_PEER_ATTR_CHAN] = NLA_POLICY_NESTED(nl80211_policy),
9bb7e0f2 345 [NL80211_PMSR_PEER_ATTR_REQ] =
23323289 346 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
9bb7e0f2
JB
347 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
348};
349
350static const struct nla_policy
351nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
352 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
353 [NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
354 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
355 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
356 [NL80211_PMSR_ATTR_PEERS] =
aeddc05f 357 NLA_POLICY_NESTED_ARRAY(nl80211_pmsr_peer_attr_policy),
9bb7e0f2
JB
358};
359
796e90f4
JC
360static const struct nla_policy
361he_obss_pd_policy[NL80211_HE_OBSS_PD_ATTR_MAX + 1] = {
362 [NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] =
363 NLA_POLICY_RANGE(NLA_U8, 1, 20),
364 [NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET] =
365 NLA_POLICY_RANGE(NLA_U8, 1, 20),
f5bec330
RM
366 [NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET] =
367 NLA_POLICY_RANGE(NLA_U8, 1, 20),
368 [NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP] =
369 NLA_POLICY_EXACT_LEN(8),
370 [NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP] =
371 NLA_POLICY_EXACT_LEN(8),
372 [NL80211_HE_OBSS_PD_ATTR_SR_CTRL] = { .type = NLA_U8 },
796e90f4
JC
373};
374
5c5e52d1
JC
375static const struct nla_policy
376he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
377 [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63),
378 [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG },
379 [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
380};
381
9a5f6488
TC
382static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
383 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
384 .len = NL80211_MAX_SUPP_RATES },
385 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
386 .len = NL80211_MAX_SUPP_HT_RATES },
387 [NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)),
388 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
eb89a6a6
MH
389 [NL80211_TXRATE_HE] = NLA_POLICY_EXACT_LEN(sizeof(struct nl80211_txrate_he)),
390 [NL80211_TXRATE_HE_GI] = NLA_POLICY_RANGE(NLA_U8,
391 NL80211_RATE_INFO_HE_GI_0_8,
392 NL80211_RATE_INFO_HE_GI_3_2),
393 [NL80211_TXRATE_HE_LTF] = NLA_POLICY_RANGE(NLA_U8,
394 NL80211_RATE_INFO_HE_1XLTF,
395 NL80211_RATE_INFO_HE_4XLTF),
9a5f6488
TC
396};
397
77f576de
T
398static const struct nla_policy
399nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
3710a8a6
JB
400 [NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
401 [NL80211_TID_CONFIG_ATTR_PEER_SUPP] = { .type = NLA_U64 },
77f576de 402 [NL80211_TID_CONFIG_ATTR_OVERRIDE] = { .type = NLA_FLAG },
3710a8a6 403 [NL80211_TID_CONFIG_ATTR_TIDS] = NLA_POLICY_RANGE(NLA_U16, 1, 0xff),
77f576de
T
404 [NL80211_TID_CONFIG_ATTR_NOACK] =
405 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
6a21d16c
T
406 [NL80211_TID_CONFIG_ATTR_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
407 [NL80211_TID_CONFIG_ATTR_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
ade274b2
T
408 [NL80211_TID_CONFIG_ATTR_AMPDU_CTRL] =
409 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
04f7d142
T
410 [NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] =
411 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
33462e68
SM
412 [NL80211_TID_CONFIG_ATTR_AMSDU_CTRL] =
413 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
9a5f6488
TC
414 [NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE] =
415 NLA_POLICY_MAX(NLA_U8, NL80211_TX_RATE_FIXED),
416 [NL80211_TID_CONFIG_ATTR_TX_RATE] =
417 NLA_POLICY_NESTED(nl80211_txattr_policy),
77f576de
T
418};
419
291c49de
AD
420static const struct nla_policy
421nl80211_fils_discovery_policy[NL80211_FILS_DISCOVERY_ATTR_MAX + 1] = {
422 [NL80211_FILS_DISCOVERY_ATTR_INT_MIN] = NLA_POLICY_MAX(NLA_U32, 10000),
423 [NL80211_FILS_DISCOVERY_ATTR_INT_MAX] = NLA_POLICY_MAX(NLA_U32, 10000),
272cd0e8
AD
424 [NL80211_FILS_DISCOVERY_ATTR_TMPL] =
425 NLA_POLICY_RANGE(NLA_BINARY,
426 NL80211_FILS_DISCOVERY_TMPL_MIN_LEN,
427 IEEE80211_MAX_DATA_LEN),
291c49de
AD
428};
429
7443dcd1
AD
430static const struct nla_policy
431nl80211_unsol_bcast_probe_resp_policy[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1] = {
432 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] = NLA_POLICY_MAX(NLA_U32, 20),
433 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL] = { .type = NLA_BINARY,
434 .len = IEEE80211_MAX_DATA_LEN }
435};
436
6bdb68ce
CH
437static const struct nla_policy
438sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
439 [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
440 [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
441};
442
443static const struct nla_policy
444sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
445 [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
446 [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
447};
448
dc1e3cb8
JC
449static const struct nla_policy
450nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = {
451 [NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES] = NLA_POLICY_MIN(NLA_U8, 2),
452 [NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY] =
453 NLA_POLICY_MIN(NLA_U8, 1),
454 [NL80211_MBSSID_CONFIG_ATTR_INDEX] = { .type = NLA_U8 },
455 [NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 },
456 [NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
457};
458
d15da2a2 459static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
6d4dd4ef 460 [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
55682965
JB
461 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
462 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 463 .len = 20-1 },
31888487 464 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 465
72bdcf34 466 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 467 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
2a38075c
AAL
468 [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
469 NL80211_EDMG_CHANNELS_MIN,
470 NL80211_EDMG_CHANNELS_MAX),
471 [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
472 NL80211_EDMG_BW_CONFIG_MIN,
473 NL80211_EDMG_BW_CONFIG_MAX),
474
3d9d1d66
JB
475 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
476 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
942ba88b 477 [NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
3d9d1d66
JB
478 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
479
ab0d76f6
JB
480 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
481 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
b9a5f8ca
JM
482 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
483 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 484 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 485 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965 486
ab0d76f6 487 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
55682965
JB
488 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
489 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 490
c7721c05
JB
491 [NL80211_ATTR_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
492 [NL80211_ATTR_PREV_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
41ade00f 493
b9454e83 494 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
495 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
496 .len = WLAN_MAX_KEY_LEN },
56be393f 497 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
41ade00f
JB
498 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
499 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 500 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
ab0d76f6
JB
501 [NL80211_ATTR_KEY_TYPE] =
502 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
ed1b6cc7
JB
503
504 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
505 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
f88eb7c0
JB
506 [NL80211_ATTR_BEACON_HEAD] =
507 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
508 IEEE80211_MAX_DATA_LEN),
3d7af878
JB
509 [NL80211_ATTR_BEACON_TAIL] =
510 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
511 IEEE80211_MAX_DATA_LEN),
ab0d76f6
JB
512 [NL80211_ATTR_STA_AID] =
513 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
5727ef1b
JB
514 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
515 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
516 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
517 .len = NL80211_MAX_SUPP_RATES },
ab0d76f6
JB
518 [NL80211_ATTR_STA_PLINK_ACTION] =
519 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
e96d1cd2
ARN
520 [NL80211_ATTR_STA_TX_POWER_SETTING] =
521 NLA_POLICY_RANGE(NLA_U8,
522 NL80211_TX_POWER_AUTOMATIC,
523 NL80211_TX_POWER_FIXED),
524 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
5727ef1b 525 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 526 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 527 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 528 .len = IEEE80211_MAX_MESH_ID_LEN },
1fab1b89 529 [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
9f1ba906 530
b2e1b302
LR
531 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
532 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
533
9f1ba906
JM
534 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
535 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
536 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
537 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
538 .len = NL80211_MAX_SUPP_RATES },
50b12f59 539 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 540
24bdd9f4 541 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 542 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 543
c7721c05 544 [NL80211_ATTR_HT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_HT_CAPABILITY_LEN),
9aed3cc1
JM
545
546 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
3d7af878
JB
547 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
548 validate_ie_attr,
549 IEEE80211_MAX_DATA_LEN),
2a519311
JB
550 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
551 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
552
553 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
554 .len = IEEE80211_MAX_SSID_LEN },
555 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
556 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 557 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 558 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
ab0d76f6
JB
559 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
560 NL80211_MFP_NO,
561 NL80211_MFP_OPTIONAL),
eccb8e8f
JB
562 [NL80211_ATTR_STA_FLAGS2] = {
563 .len = sizeof(struct nl80211_sta_flag_update),
564 },
3f77316c 565 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
566 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
567 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
64bf3d4b 568 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
b23aa676 569 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
ea750801 570 [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
b23aa676
SO
571 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
572 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 573 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 574 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
c7721c05 575 [NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
9588bbd5
JM
576 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
577 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 578 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
579 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
580 .len = IEEE80211_MAX_DATA_LEN },
581 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ab0d76f6
JB
582 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
583 NL80211_PS_DISABLED,
584 NL80211_PS_ENABLED),
d6dc1a38 585 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 586 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 587 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
588 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
589 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 590 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
591 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
592 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 593 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 594 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 595 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 596 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
ab0d76f6
JB
597 [NL80211_ATTR_STA_PLINK_STATE] =
598 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
056e9375
JK
599 [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
600 [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
ab0d76f6
JB
601 [NL80211_ATTR_MESH_PEER_AID] =
602 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
bbe6ad6d 603 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 604 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 605 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
ab0d76f6
JB
606 [NL80211_ATTR_HIDDEN_SSID] =
607 NLA_POLICY_RANGE(NLA_U32,
608 NL80211_HIDDEN_SSID_NOT_IN_USE,
609 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
3d7af878
JB
610 [NL80211_ATTR_IE_PROBE_RESP] =
611 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
612 IEEE80211_MAX_DATA_LEN),
613 [NL80211_ATTR_IE_ASSOC_RESP] =
614 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
615 IEEE80211_MAX_DATA_LEN),
f4b34b55 616 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 617 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 618 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
619 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
620 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
621 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
622 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
623 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 624 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 625 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
626 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
627 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 628 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
629 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
630 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
631 .len = NL80211_HT_CAPABILITY_LEN
632 },
1d9d9213 633 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 634 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 635 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 636 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 637 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
cb9abd48
JB
638
639 /* need to include at least Auth Transaction and Status Code */
640 [NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
641
c7721c05 642 [NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
ed473771 643 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
ab0d76f6
JB
644 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
645 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
646 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
647 NLA_POLICY_RANGE(NLA_U32,
648 NL80211_MESH_POWER_UNKNOWN + 1,
649 NL80211_MESH_POWER_MAX),
77765eaf
VT
650 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
651 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
652 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
653 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 654 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
655 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
656 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
657 .len = NL80211_VHT_CAPABILITY_LEN,
658 },
355199e0
JM
659 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
660 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
661 .len = IEEE80211_MAX_DATA_LEN },
0e1a1d85 662 [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
cb9abd48
JB
663 [NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
664 NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
ab0d76f6
JB
665 [NL80211_ATTR_PEER_AID] =
666 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
16ef1fe2
SW
667 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
668 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
669 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
00c207ed
JC
670 [NL80211_ATTR_CNTDWN_OFFS_BEACON] = { .type = NLA_BINARY },
671 [NL80211_ATTR_CNTDWN_OFFS_PRESP] = { .type = NLA_BINARY },
cb9abd48 672 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
c8b82802
JB
673 /*
674 * The value of the Length field of the Supported Operating
675 * Classes element is between 2 and 253.
676 */
677 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] =
678 NLA_POLICY_RANGE(NLA_BINARY, 2, 253),
5336fa88 679 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 680 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
681 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
682 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
683 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
c8b82802
JB
684 [NL80211_ATTR_QOS_MAP] = NLA_POLICY_RANGE(NLA_BINARY,
685 IEEE80211_QOS_MAP_LEN_MIN,
686 IEEE80211_QOS_MAP_LEN_MAX),
c7721c05 687 [NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
1df4a510 688 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 689 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 690 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 691 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 692 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
ab0d76f6
JB
693 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
694 [NL80211_ATTR_USER_PRIO] =
695 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
960d01ac 696 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 697 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
5cde05c6 698 [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
c7721c05 699 [NL80211_ATTR_MAC_MASK] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
1bdd716c 700 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 701 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 702 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 703 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 704 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 705 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
ab0d76f6
JB
706 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
707 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
c6e6a0c8
AE
708 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
709 .len = VHT_MUMIMO_GROUPS_DATA_LEN
710 },
c7721c05 711 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
ab0d76f6 712 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
8585989d 713 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
a442b761 714 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
348bd456
JM
715 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
716 .len = FILS_MAX_KEK_LEN },
c7721c05 717 [NL80211_ATTR_FILS_NONCES] = NLA_POLICY_EXACT_LEN_WARN(2 * FILS_NONCE_LEN),
ce0ce13a 718 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
c7721c05 719 [NL80211_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
bf95ecdb 720 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
721 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
722 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
723 },
3093ebbe 724 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
a3caf744
VK
725 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
726 .len = FILS_ERP_MAX_USERNAME_LEN },
727 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
728 .len = FILS_ERP_MAX_REALM_LEN },
729 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
730 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
731 .len = FILS_ERP_MAX_RRK_LEN },
c7721c05 732 [NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
a3caf744 733 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
cb9abd48 734 [NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
ca986ad9 735 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
40cbfa90 736 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
52539ca8
THJ
737
738 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
739 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
740 [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
c8b82802 741 [NL80211_ATTR_HE_CAPABILITY] =
a3a20feb
JB
742 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa,
743 NL80211_HE_MAX_CAPABILITY_LEN),
0e012b4e
JB
744 [NL80211_ATTR_FTM_RESPONDER] =
745 NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
9bb7e0f2
JB
746 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
747 [NL80211_ATTR_PEER_MEASUREMENTS] =
23323289 748 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
36647055 749 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
26f7044e
CHH
750 [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
751 .len = SAE_PASSWORD_MAX_LEN },
a0de1ca3 752 [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
796e90f4 753 [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
14f34e36 754 [NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
5c5e52d1 755 [NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
77f576de
T
756 [NL80211_ATTR_TID_CONFIG] =
757 NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
5631d96a 758 [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
7fc82af8
VJ
759 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
760 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
9dba48a6 761 [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
942ba88b 762 [NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
2032f3b2 763 [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
8140860c
JB
764 [NL80211_ATTR_HE_6GHZ_CAPABILITY] =
765 NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
291c49de
AD
766 [NL80211_ATTR_FILS_DISCOVERY] =
767 NLA_POLICY_NESTED(nl80211_fils_discovery_policy),
7443dcd1
AD
768 [NL80211_ATTR_UNSOL_BCAST_PROBE_RESP] =
769 NLA_POLICY_NESTED(nl80211_unsol_bcast_probe_resp_policy),
d2b7588a
TP
770 [NL80211_ATTR_S1G_CAPABILITY] =
771 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
772 [NL80211_ATTR_S1G_CAPABILITY_MASK] =
773 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
9f0ffa41
RD
774 [NL80211_ATTR_SAE_PWE] =
775 NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
776 NL80211_SAE_PWE_BOTH),
3bb02143 777 [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
6bdb68ce 778 [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
b6db0f89 779 [NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
0d2ab3ae
JC
780 [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 },
781 [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
782 [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
783 [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
dc1e3cb8
JC
784 [NL80211_ATTR_MBSSID_CONFIG] =
785 NLA_POLICY_NESTED(nl80211_mbssid_config_policy),
786 [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED },
a95bfb87 787 [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG },
47301a74 788 [NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 },
ea05fd35
IP
789 [NL80211_ATTR_EHT_CAPABILITY] =
790 NLA_POLICY_RANGE(NLA_BINARY,
791 NL80211_EHT_MIN_CAPABILITY_LEN,
792 NL80211_EHT_MAX_CAPABILITY_LEN),
55682965
JB
793};
794
e31b8213 795/* policy for the key attributes */
b54452b0 796static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 797 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
798 [NL80211_KEY_IDX] = { .type = NLA_U8 },
799 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 800 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
801 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
802 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
ab0d76f6 803 [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
dbd2fd65 804 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
6cdd3979 805 [NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
dbd2fd65
JB
806};
807
808/* policy for the key default flags */
809static const struct nla_policy
810nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
811 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
812 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
813};
814
f83ace3b 815#ifdef CONFIG_PM
ff1b6e69
JB
816/* policy for WoWLAN attributes */
817static const struct nla_policy
818nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
819 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
820 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
821 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
822 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
823 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
824 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
825 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
826 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 827 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 828 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
829};
830
831static const struct nla_policy
832nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
833 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
834 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
c7721c05 835 [NL80211_WOWLAN_TCP_DST_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
2a0e047e
JB
836 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
837 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
bc043585 838 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
2a0e047e
JB
839 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
840 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
841 },
842 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
843 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
844 },
845 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
bc043585
JB
846 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
847 [NL80211_WOWLAN_TCP_WAKE_MASK] = NLA_POLICY_MIN_LEN(1),
ff1b6e69 848};
f83ace3b 849#endif /* CONFIG_PM */
ff1b6e69 850
be29b99a
AK
851/* policy for coalesce rule attributes */
852static const struct nla_policy
853nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
854 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
ab0d76f6
JB
855 [NL80211_ATTR_COALESCE_RULE_CONDITION] =
856 NLA_POLICY_RANGE(NLA_U32,
857 NL80211_COALESCE_CONDITION_MATCH,
858 NL80211_COALESCE_CONDITION_NO_MATCH),
be29b99a
AK
859 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
860};
861
e5497d76
JB
862/* policy for GTK rekey offload attributes */
863static const struct nla_policy
864nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
093a48d2
NE
865 [NL80211_REKEY_DATA_KEK] = {
866 .type = NLA_BINARY,
867 .len = NL80211_KEK_EXT_LEN
868 },
869 [NL80211_REKEY_DATA_KCK] = {
870 .type = NLA_BINARY,
871 .len = NL80211_KCK_EXT_LEN
872 },
cb9abd48 873 [NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN(NL80211_REPLAY_CTR_LEN),
093a48d2 874 [NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
e5497d76
JB
875};
876
1e1b11b6 877static const struct nla_policy
878nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
879 [NL80211_BAND_2GHZ] = { .type = NLA_S32 },
880 [NL80211_BAND_5GHZ] = { .type = NLA_S32 },
e548a1c3 881 [NL80211_BAND_6GHZ] = { .type = NLA_S32 },
1e1b11b6 882 [NL80211_BAND_60GHZ] = { .type = NLA_S32 },
63fa0426 883 [NL80211_BAND_LC] = { .type = NLA_S32 },
1e1b11b6 884};
885
a1f1c21c
LC
886static const struct nla_policy
887nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 888 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 889 .len = IEEE80211_MAX_SSID_LEN },
c7721c05 890 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
88e920b4 891 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
1e1b11b6 892 [NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
893 NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
a1f1c21c
LC
894};
895
3b06d277
AS
896static const struct nla_policy
897nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
898 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
899 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
900};
901
38de03d2
AS
902static const struct nla_policy
903nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
904 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
905 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
906 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
907 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
908 },
909};
910
a442b761
AB
911/* policy for NAN function attributes */
912static const struct nla_policy
913nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
cb9abd48
JB
914 [NL80211_NAN_FUNC_TYPE] =
915 NLA_POLICY_MAX(NLA_U8, NL80211_NAN_FUNC_MAX_TYPE),
0a27844c 916 [NL80211_NAN_FUNC_SERVICE_ID] = {
a442b761
AB
917 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
918 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
919 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
920 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
921 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
922 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
c7721c05 923 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
a442b761
AB
924 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
925 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
926 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
927 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
928 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
929 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
930 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
931 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
932 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
933};
934
935/* policy for Service Response Filter attributes */
936static const struct nla_policy
937nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
938 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
939 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
940 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
941 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
942 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
943};
944
ad670233
PX
945/* policy for packet pattern attributes */
946static const struct nla_policy
947nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
948 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
949 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
950 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
951};
952
ce6b6974
JB
953static int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
954 struct cfg80211_registered_device **rdev,
955 struct wireless_dev **wdev,
956 struct nlattr **attrbuf)
a043897a 957{
97990a06 958 int err;
a043897a 959
97990a06 960 if (!cb->args[0]) {
ce6b6974
JB
961 struct nlattr **attrbuf_free = NULL;
962
963 if (!attrbuf) {
964 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
965 GFP_KERNEL);
966 if (!attrbuf)
967 return -ENOMEM;
968 attrbuf_free = attrbuf;
969 }
50508d94 970
8cb08174
JB
971 err = nlmsg_parse_deprecated(cb->nlh,
972 GENL_HDRLEN + nl80211_fam.hdrsize,
50508d94 973 attrbuf, nl80211_fam.maxattr,
8cb08174 974 nl80211_policy, NULL);
50508d94 975 if (err) {
ce6b6974 976 kfree(attrbuf_free);
ea90e0dc 977 return err;
50508d94 978 }
67748893 979
a05829a7
JB
980 rtnl_lock();
981 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(cb->skb->sk),
50508d94 982 attrbuf);
ce6b6974 983 kfree(attrbuf_free);
a05829a7
JB
984 if (IS_ERR(*wdev)) {
985 rtnl_unlock();
ea90e0dc 986 return PTR_ERR(*wdev);
a05829a7 987 }
f26cbf40 988 *rdev = wiphy_to_rdev((*wdev)->wiphy);
a05829a7
JB
989 mutex_lock(&(*rdev)->wiphy.mtx);
990 rtnl_unlock();
c319d50b
JB
991 /* 0 is the first index - add 1 to parse only once */
992 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
993 cb->args[1] = (*wdev)->identifier;
994 } else {
c319d50b 995 /* subtract the 1 again here */
a05829a7 996 struct wiphy *wiphy;
97990a06 997 struct wireless_dev *tmp;
67748893 998
a05829a7
JB
999 rtnl_lock();
1000 wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
1001 if (!wiphy) {
1002 rtnl_unlock();
ea90e0dc 1003 return -ENODEV;
a05829a7 1004 }
f26cbf40 1005 *rdev = wiphy_to_rdev(wiphy);
97990a06 1006 *wdev = NULL;
67748893 1007
53873f13 1008 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
1009 if (tmp->identifier == cb->args[1]) {
1010 *wdev = tmp;
1011 break;
1012 }
1013 }
67748893 1014
a05829a7
JB
1015 if (!*wdev) {
1016 rtnl_unlock();
ea90e0dc 1017 return -ENODEV;
a05829a7
JB
1018 }
1019 mutex_lock(&(*rdev)->wiphy.mtx);
1020 rtnl_unlock();
67748893
JB
1021 }
1022
67748893 1023 return 0;
67748893
JB
1024}
1025
55682965 1026/* message building helper */
9bb7e0f2
JB
1027void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
1028 int flags, u8 cmd)
55682965
JB
1029{
1030 /* since there is no private header just add the generic one */
15e47304 1031 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
1032}
1033
50f32718
HD
1034static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
1035 const struct ieee80211_reg_rule *rule)
1036{
1037 int j;
1038 struct nlattr *nl_wmm_rules =
ae0be8de 1039 nla_nest_start_noflag(msg, NL80211_FREQUENCY_ATTR_WMM);
50f32718
HD
1040
1041 if (!nl_wmm_rules)
1042 goto nla_put_failure;
1043
1044 for (j = 0; j < IEEE80211_NUM_ACS; j++) {
ae0be8de 1045 struct nlattr *nl_wmm_rule = nla_nest_start_noflag(msg, j);
50f32718
HD
1046
1047 if (!nl_wmm_rule)
1048 goto nla_put_failure;
1049
1050 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
38cb87ee 1051 rule->wmm_rule.client[j].cw_min) ||
50f32718 1052 nla_put_u16(msg, NL80211_WMMR_CW_MAX,
38cb87ee 1053 rule->wmm_rule.client[j].cw_max) ||
50f32718 1054 nla_put_u8(msg, NL80211_WMMR_AIFSN,
38cb87ee 1055 rule->wmm_rule.client[j].aifsn) ||
d3c89bbc
HD
1056 nla_put_u16(msg, NL80211_WMMR_TXOP,
1057 rule->wmm_rule.client[j].cot))
50f32718
HD
1058 goto nla_put_failure;
1059
1060 nla_nest_end(msg, nl_wmm_rule);
1061 }
1062 nla_nest_end(msg, nl_wmm_rules);
1063
1064 return 0;
1065
1066nla_put_failure:
1067 return -ENOBUFS;
1068}
1069
1070static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
cdc89b97
JB
1071 struct ieee80211_channel *chan,
1072 bool large)
5dab3b8a 1073{
ea077c1c
RL
1074 /* Some channels must be completely excluded from the
1075 * list to protect old user-space tools from breaking
1076 */
1077 if (!large && chan->flags &
1078 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
1079 return 0;
f8d504ca
JB
1080 if (!large && chan->freq_offset)
1081 return 0;
ea077c1c 1082
9360ffd1
DM
1083 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
1084 chan->center_freq))
1085 goto nla_put_failure;
5dab3b8a 1086
942ba88b
TP
1087 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset))
1088 goto nla_put_failure;
1089
9360ffd1
DM
1090 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
1091 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
1092 goto nla_put_failure;
8fe02e16
LR
1093 if (chan->flags & IEEE80211_CHAN_NO_IR) {
1094 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
1095 goto nla_put_failure;
1096 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
1097 goto nla_put_failure;
1098 }
cdc89b97
JB
1099 if (chan->flags & IEEE80211_CHAN_RADAR) {
1100 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
1101 goto nla_put_failure;
1102 if (large) {
1103 u32 time;
1104
1105 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
1106
1107 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
1108 chan->dfs_state))
1109 goto nla_put_failure;
1110 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
1111 time))
1112 goto nla_put_failure;
089027e5
JD
1113 if (nla_put_u32(msg,
1114 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
1115 chan->dfs_cac_ms))
1116 goto nla_put_failure;
cdc89b97
JB
1117 }
1118 }
5dab3b8a 1119
fe1abafd
JB
1120 if (large) {
1121 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
1122 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
1123 goto nla_put_failure;
1124 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
1125 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
1126 goto nla_put_failure;
1127 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
1128 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
1129 goto nla_put_failure;
1130 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
1131 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
1132 goto nla_put_failure;
570dbde1
DS
1133 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
1134 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
1135 goto nla_put_failure;
06f207fc
AN
1136 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
1137 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 1138 goto nla_put_failure;
ea077c1c
RL
1139 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
1140 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
1141 goto nla_put_failure;
1142 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
1143 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
1144 goto nla_put_failure;
1e61d82c
HD
1145 if ((chan->flags & IEEE80211_CHAN_NO_HE) &&
1146 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE))
1147 goto nla_put_failure;
d65a9770
TP
1148 if ((chan->flags & IEEE80211_CHAN_1MHZ) &&
1149 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_1MHZ))
1150 goto nla_put_failure;
1151 if ((chan->flags & IEEE80211_CHAN_2MHZ) &&
1152 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_2MHZ))
1153 goto nla_put_failure;
1154 if ((chan->flags & IEEE80211_CHAN_4MHZ) &&
1155 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_4MHZ))
1156 goto nla_put_failure;
1157 if ((chan->flags & IEEE80211_CHAN_8MHZ) &&
1158 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_8MHZ))
1159 goto nla_put_failure;
1160 if ((chan->flags & IEEE80211_CHAN_16MHZ) &&
1161 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_16MHZ))
1162 goto nla_put_failure;
c2b3d769
S
1163 if ((chan->flags & IEEE80211_CHAN_NO_320MHZ) &&
1164 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_320MHZ))
1165 goto nla_put_failure;
31846b65
IP
1166 if ((chan->flags & IEEE80211_CHAN_NO_EHT) &&
1167 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_EHT))
1168 goto nla_put_failure;
fe1abafd
JB
1169 }
1170
9360ffd1
DM
1171 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
1172 DBM_TO_MBM(chan->max_power)))
1173 goto nla_put_failure;
5dab3b8a 1174
50f32718
HD
1175 if (large) {
1176 const struct ieee80211_reg_rule *rule =
b88d26d9 1177 freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
50f32718 1178
38cb87ee 1179 if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
50f32718
HD
1180 if (nl80211_msg_put_wmm_rules(msg, rule))
1181 goto nla_put_failure;
1182 }
1183 }
1184
5dab3b8a
LR
1185 return 0;
1186
1187 nla_put_failure:
1188 return -ENOBUFS;
1189}
1190
52539ca8
THJ
1191static bool nl80211_put_txq_stats(struct sk_buff *msg,
1192 struct cfg80211_txq_stats *txqstats,
1193 int attrtype)
1194{
1195 struct nlattr *txqattr;
1196
1197#define PUT_TXQVAL_U32(attr, memb) do { \
1198 if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) && \
1199 nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
1200 return false; \
1201 } while (0)
1202
ae0be8de 1203 txqattr = nla_nest_start_noflag(msg, attrtype);
52539ca8
THJ
1204 if (!txqattr)
1205 return false;
1206
1207 PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
1208 PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
1209 PUT_TXQVAL_U32(FLOWS, flows);
1210 PUT_TXQVAL_U32(DROPS, drops);
1211 PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
1212 PUT_TXQVAL_U32(OVERLIMIT, overlimit);
1213 PUT_TXQVAL_U32(OVERMEMORY, overmemory);
1214 PUT_TXQVAL_U32(COLLISIONS, collisions);
1215 PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
1216 PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
1217 PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
1218 nla_nest_end(msg, txqattr);
1219
1220#undef PUT_TXQVAL_U32
1221 return true;
1222}
1223
55682965
JB
1224/* netlink command implementations */
1225
b9454e83
JB
1226struct key_parse {
1227 struct key_params p;
1228 int idx;
e31b8213 1229 int type;
56be393f 1230 bool def, defmgmt, defbeacon;
dbd2fd65 1231 bool def_uni, def_multi;
b9454e83
JB
1232};
1233
768075eb
JB
1234static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
1235 struct key_parse *k)
b9454e83
JB
1236{
1237 struct nlattr *tb[NL80211_KEY_MAX + 1];
8cb08174
JB
1238 int err = nla_parse_nested_deprecated(tb, NL80211_KEY_MAX, key,
1239 nl80211_key_policy,
1240 info->extack);
b9454e83
JB
1241 if (err)
1242 return err;
1243
1244 k->def = !!tb[NL80211_KEY_DEFAULT];
1245 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
56be393f 1246 k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
b9454e83 1247
dbd2fd65
JB
1248 if (k->def) {
1249 k->def_uni = true;
1250 k->def_multi = true;
1251 }
56be393f 1252 if (k->defmgmt || k->defbeacon)
dbd2fd65
JB
1253 k->def_multi = true;
1254
b9454e83
JB
1255 if (tb[NL80211_KEY_IDX])
1256 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
1257
1258 if (tb[NL80211_KEY_DATA]) {
1259 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
1260 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
1261 }
1262
1263 if (tb[NL80211_KEY_SEQ]) {
1264 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
1265 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
1266 }
1267
1268 if (tb[NL80211_KEY_CIPHER])
1269 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
1270
ab0d76f6 1271 if (tb[NL80211_KEY_TYPE])
e31b8213 1272 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
e31b8213 1273
dbd2fd65
JB
1274 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
1275 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 1276
8cb08174
JB
1277 err = nla_parse_nested_deprecated(kdt,
1278 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1279 tb[NL80211_KEY_DEFAULT_TYPES],
1280 nl80211_key_default_policy,
1281 info->extack);
dbd2fd65
JB
1282 if (err)
1283 return err;
1284
1285 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1286 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1287 }
1288
6cdd3979
AW
1289 if (tb[NL80211_KEY_MODE])
1290 k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
1291
b9454e83
JB
1292 return 0;
1293}
1294
1295static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
1296{
1297 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
1298 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
1299 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1300 }
1301
1302 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1303 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1304 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1305 }
1306
1307 if (info->attrs[NL80211_ATTR_KEY_IDX])
1308 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1309
1310 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
1311 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1312
1313 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
1314 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
1315
dbd2fd65
JB
1316 if (k->def) {
1317 k->def_uni = true;
1318 k->def_multi = true;
1319 }
1320 if (k->defmgmt)
1321 k->def_multi = true;
1322
ab0d76f6 1323 if (info->attrs[NL80211_ATTR_KEY_TYPE])
e31b8213 1324 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
e31b8213 1325
dbd2fd65
JB
1326 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
1327 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
8cb08174
JB
1328 int err = nla_parse_nested_deprecated(kdt,
1329 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1330 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
1331 nl80211_key_default_policy,
1332 info->extack);
dbd2fd65
JB
1333 if (err)
1334 return err;
1335
1336 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1337 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1338 }
1339
b9454e83
JB
1340 return 0;
1341}
1342
1343static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
1344{
1345 int err;
1346
1347 memset(k, 0, sizeof(*k));
1348 k->idx = -1;
e31b8213 1349 k->type = -1;
b9454e83
JB
1350
1351 if (info->attrs[NL80211_ATTR_KEY])
768075eb 1352 err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
b9454e83
JB
1353 else
1354 err = nl80211_parse_key_old(info, k);
1355
1356 if (err)
1357 return err;
1358
56be393f
JM
1359 if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
1360 (k->defbeacon ? 1 : 0) > 1) {
1361 GENL_SET_ERR_MSG(info,
1362 "key with multiple default flags is invalid");
b9454e83 1363 return -EINVAL;
768075eb 1364 }
b9454e83 1365
56be393f 1366 if (k->defmgmt || k->defbeacon) {
768075eb 1367 if (k->def_uni || !k->def_multi) {
56be393f
JM
1368 GENL_SET_ERR_MSG(info,
1369 "defmgmt/defbeacon key must be mcast");
dbd2fd65 1370 return -EINVAL;
768075eb 1371 }
dbd2fd65
JB
1372 }
1373
b9454e83
JB
1374 if (k->idx != -1) {
1375 if (k->defmgmt) {
768075eb
JB
1376 if (k->idx < 4 || k->idx > 5) {
1377 GENL_SET_ERR_MSG(info,
1378 "defmgmt key idx not 4 or 5");
b9454e83 1379 return -EINVAL;
768075eb 1380 }
56be393f
JM
1381 } else if (k->defbeacon) {
1382 if (k->idx < 6 || k->idx > 7) {
1383 GENL_SET_ERR_MSG(info,
1384 "defbeacon key idx not 6 or 7");
1385 return -EINVAL;
1386 }
b9454e83 1387 } else if (k->def) {
768075eb
JB
1388 if (k->idx < 0 || k->idx > 3) {
1389 GENL_SET_ERR_MSG(info, "def key idx not 0-3");
b9454e83 1390 return -EINVAL;
768075eb 1391 }
b9454e83 1392 } else {
56be393f
JM
1393 if (k->idx < 0 || k->idx > 7) {
1394 GENL_SET_ERR_MSG(info, "key idx not 0-7");
b9454e83 1395 return -EINVAL;
768075eb 1396 }
b9454e83
JB
1397 }
1398 }
1399
1400 return 0;
1401}
1402
fffd0934
JB
1403static struct cfg80211_cached_keys *
1404nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
768075eb 1405 struct genl_info *info, bool *no_ht)
fffd0934 1406{
768075eb 1407 struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
fffd0934
JB
1408 struct key_parse parse;
1409 struct nlattr *key;
1410 struct cfg80211_cached_keys *result;
1411 int rem, err, def = 0;
f1c1f17a
JB
1412 bool have_key = false;
1413
1414 nla_for_each_nested(key, keys, rem) {
1415 have_key = true;
1416 break;
1417 }
1418
1419 if (!have_key)
1420 return NULL;
fffd0934
JB
1421
1422 result = kzalloc(sizeof(*result), GFP_KERNEL);
1423 if (!result)
1424 return ERR_PTR(-ENOMEM);
1425
1426 result->def = -1;
fffd0934
JB
1427
1428 nla_for_each_nested(key, keys, rem) {
1429 memset(&parse, 0, sizeof(parse));
1430 parse.idx = -1;
1431
768075eb 1432 err = nl80211_parse_key_new(info, key, &parse);
fffd0934
JB
1433 if (err)
1434 goto error;
1435 err = -EINVAL;
1436 if (!parse.p.key)
1437 goto error;
768075eb
JB
1438 if (parse.idx < 0 || parse.idx > 3) {
1439 GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
fffd0934 1440 goto error;
768075eb 1441 }
fffd0934 1442 if (parse.def) {
768075eb
JB
1443 if (def) {
1444 GENL_SET_ERR_MSG(info,
1445 "only one key can be default");
fffd0934 1446 goto error;
768075eb 1447 }
fffd0934
JB
1448 def = 1;
1449 result->def = parse.idx;
dbd2fd65
JB
1450 if (!parse.def_uni || !parse.def_multi)
1451 goto error;
fffd0934
JB
1452 } else if (parse.defmgmt)
1453 goto error;
1454 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 1455 parse.idx, false, NULL);
fffd0934
JB
1456 if (err)
1457 goto error;
386b1f27
JB
1458 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1459 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
768075eb 1460 GENL_SET_ERR_MSG(info, "connect key must be WEP");
386b1f27
JB
1461 err = -EINVAL;
1462 goto error;
1463 }
fffd0934
JB
1464 result->params[parse.idx].cipher = parse.p.cipher;
1465 result->params[parse.idx].key_len = parse.p.key_len;
1466 result->params[parse.idx].key = result->data[parse.idx];
1467 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 1468
386b1f27
JB
1469 /* must be WEP key if we got here */
1470 if (no_ht)
1471 *no_ht = true;
fffd0934
JB
1472 }
1473
f1c1f17a
JB
1474 if (result->def < 0) {
1475 err = -EINVAL;
768075eb 1476 GENL_SET_ERR_MSG(info, "need a default/TX key");
f1c1f17a
JB
1477 goto error;
1478 }
1479
fffd0934
JB
1480 return result;
1481 error:
1482 kfree(result);
1483 return ERR_PTR(err);
1484}
1485
1486static int nl80211_key_allowed(struct wireless_dev *wdev)
1487{
1488 ASSERT_WDEV_LOCK(wdev);
1489
fffd0934
JB
1490 switch (wdev->iftype) {
1491 case NL80211_IFTYPE_AP:
1492 case NL80211_IFTYPE_AP_VLAN:
074ac8df 1493 case NL80211_IFTYPE_P2P_GO:
ff973af7 1494 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
1495 break;
1496 case NL80211_IFTYPE_ADHOC:
fffd0934 1497 case NL80211_IFTYPE_STATION:
074ac8df 1498 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 1499 if (!wdev->current_bss)
fffd0934
JB
1500 return -ENOLINK;
1501 break;
de4fcbad 1502 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 1503 case NL80211_IFTYPE_OCB:
de4fcbad 1504 case NL80211_IFTYPE_MONITOR:
cb3b7d87 1505 case NL80211_IFTYPE_NAN:
de4fcbad
JB
1506 case NL80211_IFTYPE_P2P_DEVICE:
1507 case NL80211_IFTYPE_WDS:
1508 case NUM_NL80211_IFTYPES:
fffd0934
JB
1509 return -EINVAL;
1510 }
1511
1512 return 0;
1513}
1514
664834de 1515static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
942ba88b 1516 u32 freq)
664834de
JM
1517{
1518 struct ieee80211_channel *chan;
1519
942ba88b 1520 chan = ieee80211_get_channel_khz(wiphy, freq);
664834de
JM
1521 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1522 return NULL;
1523 return chan;
1524}
1525
7527a782
JB
1526static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1527{
ae0be8de 1528 struct nlattr *nl_modes = nla_nest_start_noflag(msg, attr);
7527a782
JB
1529 int i;
1530
1531 if (!nl_modes)
1532 goto nla_put_failure;
1533
1534 i = 0;
1535 while (ifmodes) {
9360ffd1
DM
1536 if ((ifmodes & 1) && nla_put_flag(msg, i))
1537 goto nla_put_failure;
7527a782
JB
1538 ifmodes >>= 1;
1539 i++;
1540 }
1541
1542 nla_nest_end(msg, nl_modes);
1543 return 0;
1544
1545nla_put_failure:
1546 return -ENOBUFS;
1547}
1548
1549static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1550 struct sk_buff *msg,
1551 bool large)
7527a782
JB
1552{
1553 struct nlattr *nl_combis;
1554 int i, j;
1555
ae0be8de
MK
1556 nl_combis = nla_nest_start_noflag(msg,
1557 NL80211_ATTR_INTERFACE_COMBINATIONS);
7527a782
JB
1558 if (!nl_combis)
1559 goto nla_put_failure;
1560
1561 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1562 const struct ieee80211_iface_combination *c;
1563 struct nlattr *nl_combi, *nl_limits;
1564
1565 c = &wiphy->iface_combinations[i];
1566
ae0be8de 1567 nl_combi = nla_nest_start_noflag(msg, i + 1);
7527a782
JB
1568 if (!nl_combi)
1569 goto nla_put_failure;
1570
ae0be8de
MK
1571 nl_limits = nla_nest_start_noflag(msg,
1572 NL80211_IFACE_COMB_LIMITS);
7527a782
JB
1573 if (!nl_limits)
1574 goto nla_put_failure;
1575
1576 for (j = 0; j < c->n_limits; j++) {
1577 struct nlattr *nl_limit;
1578
ae0be8de 1579 nl_limit = nla_nest_start_noflag(msg, j + 1);
7527a782
JB
1580 if (!nl_limit)
1581 goto nla_put_failure;
9360ffd1
DM
1582 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1583 c->limits[j].max))
1584 goto nla_put_failure;
7527a782
JB
1585 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1586 c->limits[j].types))
1587 goto nla_put_failure;
1588 nla_nest_end(msg, nl_limit);
1589 }
1590
1591 nla_nest_end(msg, nl_limits);
1592
9360ffd1
DM
1593 if (c->beacon_int_infra_match &&
1594 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1595 goto nla_put_failure;
1596 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1597 c->num_different_channels) ||
1598 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1599 c->max_interfaces))
1600 goto nla_put_failure;
cdc89b97 1601 if (large &&
8c48b50a
FF
1602 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1603 c->radar_detect_widths) ||
1604 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1605 c->radar_detect_regions)))
cdc89b97 1606 goto nla_put_failure;
0c317a02
PK
1607 if (c->beacon_int_min_gcd &&
1608 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1609 c->beacon_int_min_gcd))
1610 goto nla_put_failure;
7527a782
JB
1611
1612 nla_nest_end(msg, nl_combi);
1613 }
1614
1615 nla_nest_end(msg, nl_combis);
1616
1617 return 0;
1618nla_put_failure:
1619 return -ENOBUFS;
1620}
1621
3713b4e3 1622#ifdef CONFIG_PM
b56cf720
JB
1623static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1624 struct sk_buff *msg)
1625{
964dc9e2 1626 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1627 struct nlattr *nl_tcp;
1628
1629 if (!tcp)
1630 return 0;
1631
ae0be8de
MK
1632 nl_tcp = nla_nest_start_noflag(msg,
1633 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
b56cf720
JB
1634 if (!nl_tcp)
1635 return -ENOBUFS;
1636
1637 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1638 tcp->data_payload_max))
1639 return -ENOBUFS;
1640
1641 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1642 tcp->data_payload_max))
1643 return -ENOBUFS;
1644
1645 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1646 return -ENOBUFS;
1647
1648 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1649 sizeof(*tcp->tok), tcp->tok))
1650 return -ENOBUFS;
1651
1652 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1653 tcp->data_interval_max))
1654 return -ENOBUFS;
1655
1656 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1657 tcp->wake_payload_max))
1658 return -ENOBUFS;
1659
1660 nla_nest_end(msg, nl_tcp);
1661 return 0;
1662}
1663
3713b4e3 1664static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1665 struct cfg80211_registered_device *rdev,
b56cf720 1666 bool large)
55682965 1667{
3713b4e3 1668 struct nlattr *nl_wowlan;
55682965 1669
1b8ec87a 1670 if (!rdev->wiphy.wowlan)
3713b4e3 1671 return 0;
55682965 1672
ae0be8de
MK
1673 nl_wowlan = nla_nest_start_noflag(msg,
1674 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
3713b4e3
JB
1675 if (!nl_wowlan)
1676 return -ENOBUFS;
9360ffd1 1677
1b8ec87a 1678 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1679 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1680 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1681 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1682 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1683 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1684 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1685 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1686 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1687 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1688 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1689 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1690 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1691 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1692 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1693 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1694 return -ENOBUFS;
9360ffd1 1695
1b8ec87a 1696 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1697 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1698 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1699 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1700 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1701 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1702 };
9360ffd1 1703
3713b4e3
JB
1704 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1705 sizeof(pat), &pat))
1706 return -ENOBUFS;
1707 }
9360ffd1 1708
75453ccb
LC
1709 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1710 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1711 rdev->wiphy.wowlan->max_nd_match_sets))
1712 return -ENOBUFS;
1713
1b8ec87a 1714 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1715 return -ENOBUFS;
1716
3713b4e3 1717 nla_nest_end(msg, nl_wowlan);
9360ffd1 1718
3713b4e3
JB
1719 return 0;
1720}
1721#endif
9360ffd1 1722
be29b99a 1723static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1724 struct cfg80211_registered_device *rdev)
be29b99a
AK
1725{
1726 struct nl80211_coalesce_rule_support rule;
1727
1b8ec87a 1728 if (!rdev->wiphy.coalesce)
be29b99a
AK
1729 return 0;
1730
1b8ec87a
ZG
1731 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1732 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1733 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1734 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1735 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1736 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1737
1738 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1739 return -ENOBUFS;
1740
1741 return 0;
1742}
1743
c4cbaf79
LC
1744static int
1745nl80211_send_iftype_data(struct sk_buff *msg,
22395217 1746 const struct ieee80211_supported_band *sband,
c4cbaf79
LC
1747 const struct ieee80211_sband_iftype_data *iftdata)
1748{
1749 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
5cd5a8a3 1750 const struct ieee80211_sta_eht_cap *eht_cap = &iftdata->eht_cap;
c4cbaf79
LC
1751
1752 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
1753 iftdata->types_mask))
1754 return -ENOBUFS;
1755
1756 if (he_cap->has_he) {
1757 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
1758 sizeof(he_cap->he_cap_elem.mac_cap_info),
1759 he_cap->he_cap_elem.mac_cap_info) ||
1760 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
1761 sizeof(he_cap->he_cap_elem.phy_cap_info),
1762 he_cap->he_cap_elem.phy_cap_info) ||
1763 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
1764 sizeof(he_cap->he_mcs_nss_supp),
1765 &he_cap->he_mcs_nss_supp) ||
1766 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
1767 sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
1768 return -ENOBUFS;
1769 }
1770
5cd5a8a3
IP
1771 if (eht_cap->has_eht && he_cap->has_he) {
1772 u8 mcs_nss_size, ppe_thresh_size;
1773 u16 ppe_thres_hdr;
1774
1775 mcs_nss_size =
1776 ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem,
1777 &eht_cap->eht_cap_elem);
1778
1779 ppe_thres_hdr = get_unaligned_le16(&eht_cap->eht_ppe_thres[0]);
1780 ppe_thresh_size =
1781 ieee80211_eht_ppe_size(ppe_thres_hdr,
1782 eht_cap->eht_cap_elem.phy_cap_info);
1783
1784 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC,
1785 sizeof(eht_cap->eht_cap_elem.mac_cap_info),
1786 eht_cap->eht_cap_elem.mac_cap_info) ||
1787 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
1788 sizeof(eht_cap->eht_cap_elem.phy_cap_info),
1789 eht_cap->eht_cap_elem.phy_cap_info) ||
1790 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
1791 mcs_nss_size, &eht_cap->eht_mcs_nss_supp) ||
1792 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
1793 ppe_thresh_size, eht_cap->eht_ppe_thres))
1794 return -ENOBUFS;
1795 }
1796
22395217
JB
1797 if (sband->band == NL80211_BAND_6GHZ &&
1798 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
1799 sizeof(iftdata->he_6ghz_capa),
1800 &iftdata->he_6ghz_capa))
1801 return -ENOBUFS;
1802
f4f86505
JB
1803 if (iftdata->vendor_elems.data && iftdata->vendor_elems.len &&
1804 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
1805 iftdata->vendor_elems.len, iftdata->vendor_elems.data))
1806 return -ENOBUFS;
1807
c4cbaf79
LC
1808 return 0;
1809}
1810
3713b4e3 1811static int nl80211_send_band_rateinfo(struct sk_buff *msg,
f8d504ca
JB
1812 struct ieee80211_supported_band *sband,
1813 bool large)
3713b4e3
JB
1814{
1815 struct nlattr *nl_rates, *nl_rate;
1816 struct ieee80211_rate *rate;
1817 int i;
87bbbe22 1818
3713b4e3
JB
1819 /* add HT info */
1820 if (sband->ht_cap.ht_supported &&
1821 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1822 sizeof(sband->ht_cap.mcs),
1823 &sband->ht_cap.mcs) ||
1824 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1825 sband->ht_cap.cap) ||
1826 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1827 sband->ht_cap.ampdu_factor) ||
1828 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1829 sband->ht_cap.ampdu_density)))
1830 return -ENOBUFS;
afe0cbf8 1831
3713b4e3
JB
1832 /* add VHT info */
1833 if (sband->vht_cap.vht_supported &&
1834 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1835 sizeof(sband->vht_cap.vht_mcs),
1836 &sband->vht_cap.vht_mcs) ||
1837 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1838 sband->vht_cap.cap)))
1839 return -ENOBUFS;
f59ac048 1840
f8d504ca 1841 if (large && sband->n_iftype_data) {
c4cbaf79 1842 struct nlattr *nl_iftype_data =
ae0be8de
MK
1843 nla_nest_start_noflag(msg,
1844 NL80211_BAND_ATTR_IFTYPE_DATA);
c4cbaf79
LC
1845 int err;
1846
1847 if (!nl_iftype_data)
1848 return -ENOBUFS;
1849
1850 for (i = 0; i < sband->n_iftype_data; i++) {
1851 struct nlattr *iftdata;
1852
ae0be8de 1853 iftdata = nla_nest_start_noflag(msg, i + 1);
c4cbaf79
LC
1854 if (!iftdata)
1855 return -ENOBUFS;
1856
22395217 1857 err = nl80211_send_iftype_data(msg, sband,
c4cbaf79
LC
1858 &sband->iftype_data[i]);
1859 if (err)
1860 return err;
1861
1862 nla_nest_end(msg, iftdata);
1863 }
1864
1865 nla_nest_end(msg, nl_iftype_data);
1866 }
1867
2a38075c 1868 /* add EDMG info */
f8d504ca 1869 if (large && sband->edmg_cap.channels &&
2a38075c
AAL
1870 (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
1871 sband->edmg_cap.channels) ||
1872 nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
1873 sband->edmg_cap.bw_config)))
1874
1875 return -ENOBUFS;
1876
3713b4e3 1877 /* add bitrates */
ae0be8de 1878 nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
3713b4e3
JB
1879 if (!nl_rates)
1880 return -ENOBUFS;
ee688b00 1881
3713b4e3 1882 for (i = 0; i < sband->n_bitrates; i++) {
ae0be8de 1883 nl_rate = nla_nest_start_noflag(msg, i);
3713b4e3
JB
1884 if (!nl_rate)
1885 return -ENOBUFS;
ee688b00 1886
3713b4e3
JB
1887 rate = &sband->bitrates[i];
1888 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1889 rate->bitrate))
1890 return -ENOBUFS;
1891 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1892 nla_put_flag(msg,
1893 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1894 return -ENOBUFS;
ee688b00 1895
3713b4e3
JB
1896 nla_nest_end(msg, nl_rate);
1897 }
d51626df 1898
3713b4e3 1899 nla_nest_end(msg, nl_rates);
bf0c111e 1900
3713b4e3
JB
1901 return 0;
1902}
ee688b00 1903
3713b4e3
JB
1904static int
1905nl80211_send_mgmt_stypes(struct sk_buff *msg,
1906 const struct ieee80211_txrx_stypes *mgmt_stypes)
1907{
1908 u16 stypes;
1909 struct nlattr *nl_ftypes, *nl_ifs;
1910 enum nl80211_iftype ift;
1911 int i;
ee688b00 1912
3713b4e3
JB
1913 if (!mgmt_stypes)
1914 return 0;
5dab3b8a 1915
ae0be8de 1916 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_TX_FRAME_TYPES);
3713b4e3
JB
1917 if (!nl_ifs)
1918 return -ENOBUFS;
e2f367f2 1919
3713b4e3 1920 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1921 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1922 if (!nl_ftypes)
1923 return -ENOBUFS;
1924 i = 0;
1925 stypes = mgmt_stypes[ift].tx;
1926 while (stypes) {
1927 if ((stypes & 1) &&
1928 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1929 (i << 4) | IEEE80211_FTYPE_MGMT))
1930 return -ENOBUFS;
1931 stypes >>= 1;
1932 i++;
ee688b00 1933 }
3713b4e3
JB
1934 nla_nest_end(msg, nl_ftypes);
1935 }
ee688b00 1936
3713b4e3 1937 nla_nest_end(msg, nl_ifs);
ee688b00 1938
ae0be8de 1939 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_RX_FRAME_TYPES);
3713b4e3
JB
1940 if (!nl_ifs)
1941 return -ENOBUFS;
ee688b00 1942
3713b4e3 1943 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1944 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1945 if (!nl_ftypes)
1946 return -ENOBUFS;
1947 i = 0;
1948 stypes = mgmt_stypes[ift].rx;
1949 while (stypes) {
1950 if ((stypes & 1) &&
1951 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1952 (i << 4) | IEEE80211_FTYPE_MGMT))
1953 return -ENOBUFS;
1954 stypes >>= 1;
1955 i++;
1956 }
1957 nla_nest_end(msg, nl_ftypes);
1958 }
1959 nla_nest_end(msg, nl_ifs);
ee688b00 1960
3713b4e3
JB
1961 return 0;
1962}
ee688b00 1963
1794899e
JB
1964#define CMD(op, n) \
1965 do { \
1966 if (rdev->ops->op) { \
1967 i++; \
1968 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1969 goto nla_put_failure; \
1970 } \
1971 } while (0)
1972
1973static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1974 struct sk_buff *msg)
1975{
1976 int i = 0;
1977
1978 /*
1979 * do *NOT* add anything into this function, new things need to be
1980 * advertised only to new versions of userspace that can deal with
1981 * the split (and they can't possibly care about new features...
1982 */
1983 CMD(add_virtual_intf, NEW_INTERFACE);
1984 CMD(change_virtual_intf, SET_INTERFACE);
1985 CMD(add_key, NEW_KEY);
1986 CMD(start_ap, START_AP);
1987 CMD(add_station, NEW_STATION);
1988 CMD(add_mpath, NEW_MPATH);
1989 CMD(update_mesh_config, SET_MESH_CONFIG);
1990 CMD(change_bss, SET_BSS);
1991 CMD(auth, AUTHENTICATE);
1992 CMD(assoc, ASSOCIATE);
1993 CMD(deauth, DEAUTHENTICATE);
1994 CMD(disassoc, DISASSOCIATE);
1995 CMD(join_ibss, JOIN_IBSS);
1996 CMD(join_mesh, JOIN_MESH);
1997 CMD(set_pmksa, SET_PMKSA);
1998 CMD(del_pmksa, DEL_PMKSA);
1999 CMD(flush_pmksa, FLUSH_PMKSA);
2000 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
2001 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
2002 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
2003 CMD(mgmt_tx, FRAME);
2004 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
2005 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
2006 i++;
2007 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
2008 goto nla_put_failure;
2009 }
2010 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
2011 rdev->ops->join_mesh) {
2012 i++;
2013 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
2014 goto nla_put_failure;
2015 }
1794899e
JB
2016 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
2017 CMD(tdls_mgmt, TDLS_MGMT);
2018 CMD(tdls_oper, TDLS_OPER);
2019 }
ca986ad9 2020 if (rdev->wiphy.max_sched_scan_reqs)
1794899e
JB
2021 CMD(sched_scan_start, START_SCHED_SCAN);
2022 CMD(probe_client, PROBE_CLIENT);
2023 CMD(set_noack_map, SET_NOACK_MAP);
2024 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
2025 i++;
2026 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
2027 goto nla_put_failure;
2028 }
2029 CMD(start_p2p_device, START_P2P_DEVICE);
2030 CMD(set_mcast_rate, SET_MCAST_RATE);
2031#ifdef CONFIG_NL80211_TESTMODE
2032 CMD(testmode_cmd, TESTMODE);
2033#endif
2034
2035 if (rdev->ops->connect || rdev->ops->auth) {
2036 i++;
2037 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
2038 goto nla_put_failure;
2039 }
2040
2041 if (rdev->ops->disconnect || rdev->ops->deauth) {
2042 i++;
2043 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
2044 goto nla_put_failure;
2045 }
2046
2047 return i;
2048 nla_put_failure:
2049 return -ENOBUFS;
2050}
2051
9bb7e0f2
JB
2052static int
2053nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
2054 struct sk_buff *msg)
2055{
2056 struct nlattr *ftm;
2057
2058 if (!cap->ftm.supported)
2059 return 0;
2060
ae0be8de 2061 ftm = nla_nest_start_noflag(msg, NL80211_PMSR_TYPE_FTM);
9bb7e0f2
JB
2062 if (!ftm)
2063 return -ENOBUFS;
2064
2065 if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
2066 return -ENOBUFS;
2067 if (cap->ftm.non_asap &&
2068 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
2069 return -ENOBUFS;
2070 if (cap->ftm.request_lci &&
2071 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
2072 return -ENOBUFS;
2073 if (cap->ftm.request_civicloc &&
2074 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
2075 return -ENOBUFS;
2076 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
2077 cap->ftm.preambles))
2078 return -ENOBUFS;
2079 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
2080 cap->ftm.bandwidths))
2081 return -ENOBUFS;
2082 if (cap->ftm.max_bursts_exponent >= 0 &&
2083 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
2084 cap->ftm.max_bursts_exponent))
2085 return -ENOBUFS;
2086 if (cap->ftm.max_ftms_per_burst &&
2087 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
2088 cap->ftm.max_ftms_per_burst))
2089 return -ENOBUFS;
efb5520d
AS
2090 if (cap->ftm.trigger_based &&
2091 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED))
2092 return -ENOBUFS;
2093 if (cap->ftm.non_trigger_based &&
2094 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED))
2095 return -ENOBUFS;
9bb7e0f2
JB
2096
2097 nla_nest_end(msg, ftm);
2098 return 0;
2099}
2100
2101static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
2102 struct sk_buff *msg)
2103{
2104 const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
2105 struct nlattr *pmsr, *caps;
2106
2107 if (!cap)
2108 return 0;
2109
2110 /*
2111 * we don't need to clean up anything here since the caller
2112 * will genlmsg_cancel() if we fail
2113 */
2114
ae0be8de 2115 pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
9bb7e0f2
JB
2116 if (!pmsr)
2117 return -ENOBUFS;
2118
2119 if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
2120 return -ENOBUFS;
2121
2122 if (cap->report_ap_tsf &&
2123 nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
2124 return -ENOBUFS;
2125
2126 if (cap->randomize_mac_addr &&
2127 nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
2128 return -ENOBUFS;
2129
ae0be8de 2130 caps = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
9bb7e0f2
JB
2131 if (!caps)
2132 return -ENOBUFS;
2133
2134 if (nl80211_send_pmsr_ftm_capa(cap, msg))
2135 return -ENOBUFS;
2136
2137 nla_nest_end(msg, caps);
2138 nla_nest_end(msg, pmsr);
2139
2140 return 0;
2141}
2142
d6039a34
VJ
2143static int
2144nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
2145 struct sk_buff *msg)
2146{
2147 int i;
2148 struct nlattr *nested, *nested_akms;
2149 const struct wiphy_iftype_akm_suites *iftype_akms;
2150
2151 if (!rdev->wiphy.num_iftype_akm_suites ||
2152 !rdev->wiphy.iftype_akm_suites)
2153 return 0;
2154
2155 nested = nla_nest_start(msg, NL80211_ATTR_IFTYPE_AKM_SUITES);
2156 if (!nested)
2157 return -ENOBUFS;
2158
2159 for (i = 0; i < rdev->wiphy.num_iftype_akm_suites; i++) {
2160 nested_akms = nla_nest_start(msg, i + 1);
2161 if (!nested_akms)
2162 return -ENOBUFS;
2163
2164 iftype_akms = &rdev->wiphy.iftype_akm_suites[i];
2165
2166 if (nl80211_put_iftypes(msg, NL80211_IFTYPE_AKM_ATTR_IFTYPES,
2167 iftype_akms->iftypes_mask))
2168 return -ENOBUFS;
2169
2170 if (nla_put(msg, NL80211_IFTYPE_AKM_ATTR_SUITES,
2171 sizeof(u32) * iftype_akms->n_akm_suites,
2172 iftype_akms->akm_suites)) {
2173 return -ENOBUFS;
2174 }
2175 nla_nest_end(msg, nested_akms);
2176 }
2177
2178 nla_nest_end(msg, nested);
2179
2180 return 0;
2181}
2182
3710a8a6
JB
2183static int
2184nl80211_put_tid_config_support(struct cfg80211_registered_device *rdev,
2185 struct sk_buff *msg)
2186{
2187 struct nlattr *supp;
2188
2189 if (!rdev->wiphy.tid_config_support.vif &&
2190 !rdev->wiphy.tid_config_support.peer)
2191 return 0;
2192
2193 supp = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
2194 if (!supp)
2195 return -ENOSPC;
2196
2197 if (rdev->wiphy.tid_config_support.vif &&
2198 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_VIF_SUPP,
2199 rdev->wiphy.tid_config_support.vif,
2200 NL80211_TID_CONFIG_ATTR_PAD))
2201 goto fail;
2202
2203 if (rdev->wiphy.tid_config_support.peer &&
2204 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_PEER_SUPP,
2205 rdev->wiphy.tid_config_support.peer,
2206 NL80211_TID_CONFIG_ATTR_PAD))
2207 goto fail;
2208
6a21d16c
T
2209 /* for now we just use the same value ... makes more sense */
2210 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
2211 rdev->wiphy.tid_config_support.max_retry))
2212 goto fail;
2213 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG,
2214 rdev->wiphy.tid_config_support.max_retry))
2215 goto fail;
2216
3710a8a6
JB
2217 nla_nest_end(msg, supp);
2218
2219 return 0;
2220fail:
2221 nla_nest_cancel(msg, supp);
2222 return -ENOBUFS;
2223}
2224
6bdb68ce
CH
2225static int
2226nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
2227 struct sk_buff *msg)
2228{
2229 struct nlattr *sar_capa, *specs, *sub_freq_range;
2230 u8 num_freq_ranges;
2231 int i;
2232
2233 if (!rdev->wiphy.sar_capa)
2234 return 0;
2235
2236 num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
2237
2238 sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
2239 if (!sar_capa)
2240 return -ENOSPC;
2241
2242 if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
2243 goto fail;
2244
2245 specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
2246 if (!specs)
2247 goto fail;
2248
2249 /* report supported freq_ranges */
2250 for (i = 0; i < num_freq_ranges; i++) {
2251 sub_freq_range = nla_nest_start(msg, i + 1);
2252 if (!sub_freq_range)
2253 goto fail;
2254
2255 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
2256 rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
2257 goto fail;
2258
2259 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
2260 rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
2261 goto fail;
2262
2263 nla_nest_end(msg, sub_freq_range);
2264 }
2265
2266 nla_nest_end(msg, specs);
2267 nla_nest_end(msg, sar_capa);
2268
2269 return 0;
2270fail:
2271 nla_nest_cancel(msg, sar_capa);
2272 return -ENOBUFS;
2273}
2274
dc1e3cb8
JC
2275static int nl80211_put_mbssid_support(struct wiphy *wiphy, struct sk_buff *msg)
2276{
2277 struct nlattr *config;
2278
2279 if (!wiphy->mbssid_max_interfaces)
2280 return 0;
2281
2282 config = nla_nest_start(msg, NL80211_ATTR_MBSSID_CONFIG);
2283 if (!config)
2284 return -ENOBUFS;
2285
2286 if (nla_put_u8(msg, NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES,
2287 wiphy->mbssid_max_interfaces))
2288 goto fail;
2289
2290 if (wiphy->ema_max_profile_periodicity &&
2291 nla_put_u8(msg,
2292 NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY,
2293 wiphy->ema_max_profile_periodicity))
2294 goto fail;
2295
2296 nla_nest_end(msg, config);
2297 return 0;
2298
2299fail:
2300 nla_nest_cancel(msg, config);
2301 return -ENOBUFS;
2302}
2303
86e8cf98
JB
2304struct nl80211_dump_wiphy_state {
2305 s64 filter_wiphy;
2306 long start;
019ae3a9 2307 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
2308 bool split;
2309};
2310
1b8ec87a 2311static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 2312 enum nl80211_commands cmd,
3713b4e3 2313 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 2314 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
2315{
2316 void *hdr;
2317 struct nlattr *nl_bands, *nl_band;
2318 struct nlattr *nl_freqs, *nl_freq;
2319 struct nlattr *nl_cmds;
57fbcce3 2320 enum nl80211_band band;
3713b4e3
JB
2321 struct ieee80211_channel *chan;
2322 int i;
2323 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 2324 rdev->wiphy.mgmt_stypes;
fe1abafd 2325 u32 features;
ee688b00 2326
3bb20556 2327 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
2328 if (!hdr)
2329 return -ENOBUFS;
ee688b00 2330
86e8cf98
JB
2331 if (WARN_ON(!state))
2332 return -EINVAL;
ee688b00 2333
1b8ec87a 2334 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 2335 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 2336 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
2337 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2338 cfg80211_rdev_list_generation))
8fdc621d
JB
2339 goto nla_put_failure;
2340
3bb20556
JB
2341 if (cmd != NL80211_CMD_NEW_WIPHY)
2342 goto finish;
2343
86e8cf98 2344 switch (state->split_start) {
3713b4e3
JB
2345 case 0:
2346 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 2347 rdev->wiphy.retry_short) ||
3713b4e3 2348 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 2349 rdev->wiphy.retry_long) ||
3713b4e3 2350 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 2351 rdev->wiphy.frag_threshold) ||
3713b4e3 2352 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 2353 rdev->wiphy.rts_threshold) ||
3713b4e3 2354 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 2355 rdev->wiphy.coverage_class) ||
3713b4e3 2356 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 2357 rdev->wiphy.max_scan_ssids) ||
3713b4e3 2358 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 2359 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 2360 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 2361 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 2362 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 2363 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 2364 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
f8d504ca 2365 rdev->wiphy.max_match_sets))
9360ffd1 2366 goto nla_put_failure;
3713b4e3 2367
1b8ec87a 2368 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 2369 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 2370 goto nla_put_failure;
1b8ec87a 2371 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
2372 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
2373 goto nla_put_failure;
1b8ec87a 2374 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
2375 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
2376 goto nla_put_failure;
1b8ec87a 2377 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
2378 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
2379 goto nla_put_failure;
1b8ec87a 2380 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
2381 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
2382 goto nla_put_failure;
1b8ec87a 2383 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 2384 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 2385 goto nla_put_failure;
86e8cf98
JB
2386 state->split_start++;
2387 if (state->split)
3713b4e3 2388 break;
7b506ff6 2389 fallthrough;
3713b4e3
JB
2390 case 1:
2391 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
2392 sizeof(u32) * rdev->wiphy.n_cipher_suites,
2393 rdev->wiphy.cipher_suites))
3713b4e3 2394 goto nla_put_failure;
4745fc09 2395
3713b4e3 2396 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 2397 rdev->wiphy.max_num_pmkids))
3713b4e3 2398 goto nla_put_failure;
b23aa676 2399
1b8ec87a 2400 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 2401 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 2402 goto nla_put_failure;
b23aa676 2403
3713b4e3 2404 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 2405 rdev->wiphy.available_antennas_tx) ||
3713b4e3 2406 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 2407 rdev->wiphy.available_antennas_rx))
9360ffd1 2408 goto nla_put_failure;
b23aa676 2409
1b8ec87a 2410 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 2411 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 2412 rdev->wiphy.probe_resp_offload))
3713b4e3 2413 goto nla_put_failure;
8fdc621d 2414
1b8ec87a
ZG
2415 if ((rdev->wiphy.available_antennas_tx ||
2416 rdev->wiphy.available_antennas_rx) &&
2417 rdev->ops->get_antenna) {
3713b4e3
JB
2418 u32 tx_ant = 0, rx_ant = 0;
2419 int res;
7a087e74 2420
1b8ec87a 2421 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
2422 if (!res) {
2423 if (nla_put_u32(msg,
2424 NL80211_ATTR_WIPHY_ANTENNA_TX,
2425 tx_ant) ||
2426 nla_put_u32(msg,
2427 NL80211_ATTR_WIPHY_ANTENNA_RX,
2428 rx_ant))
2429 goto nla_put_failure;
2430 }
2431 }
a293911d 2432
86e8cf98
JB
2433 state->split_start++;
2434 if (state->split)
3713b4e3 2435 break;
7b506ff6 2436 fallthrough;
3713b4e3
JB
2437 case 2:
2438 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 2439 rdev->wiphy.interface_modes))
3713b4e3 2440 goto nla_put_failure;
86e8cf98
JB
2441 state->split_start++;
2442 if (state->split)
3713b4e3 2443 break;
7b506ff6 2444 fallthrough;
3713b4e3 2445 case 3:
ae0be8de
MK
2446 nl_bands = nla_nest_start_noflag(msg,
2447 NL80211_ATTR_WIPHY_BANDS);
3713b4e3
JB
2448 if (!nl_bands)
2449 goto nla_put_failure;
f7ca38df 2450
86e8cf98 2451 for (band = state->band_start;
0d059964
JB
2452 band < (state->split ?
2453 NUM_NL80211_BANDS :
2454 NL80211_BAND_60GHZ + 1);
2455 band++) {
3713b4e3 2456 struct ieee80211_supported_band *sband;
2e161f78 2457
f8d504ca
JB
2458 /* omit higher bands for ancient software */
2459 if (band > NL80211_BAND_5GHZ && !state->split)
2460 break;
2461
1b8ec87a 2462 sband = rdev->wiphy.bands[band];
2e161f78 2463
3713b4e3
JB
2464 if (!sband)
2465 continue;
2466
ae0be8de 2467 nl_band = nla_nest_start_noflag(msg, band);
3713b4e3 2468 if (!nl_band)
2e161f78 2469 goto nla_put_failure;
3713b4e3 2470
86e8cf98 2471 switch (state->chan_start) {
3713b4e3 2472 case 0:
f8d504ca
JB
2473 if (nl80211_send_band_rateinfo(msg, sband,
2474 state->split))
9360ffd1 2475 goto nla_put_failure;
86e8cf98
JB
2476 state->chan_start++;
2477 if (state->split)
3713b4e3 2478 break;
7b506ff6 2479 fallthrough;
3713b4e3
JB
2480 default:
2481 /* add frequencies */
ae0be8de
MK
2482 nl_freqs = nla_nest_start_noflag(msg,
2483 NL80211_BAND_ATTR_FREQS);
3713b4e3
JB
2484 if (!nl_freqs)
2485 goto nla_put_failure;
2486
86e8cf98 2487 for (i = state->chan_start - 1;
3713b4e3
JB
2488 i < sband->n_channels;
2489 i++) {
ae0be8de
MK
2490 nl_freq = nla_nest_start_noflag(msg,
2491 i);
3713b4e3
JB
2492 if (!nl_freq)
2493 goto nla_put_failure;
2494
2495 chan = &sband->channels[i];
2496
86e8cf98 2497 if (nl80211_msg_put_channel(
50f32718 2498 msg, &rdev->wiphy, chan,
86e8cf98 2499 state->split))
3713b4e3
JB
2500 goto nla_put_failure;
2501
2502 nla_nest_end(msg, nl_freq);
86e8cf98 2503 if (state->split)
3713b4e3
JB
2504 break;
2505 }
2506 if (i < sband->n_channels)
86e8cf98 2507 state->chan_start = i + 2;
3713b4e3 2508 else
86e8cf98 2509 state->chan_start = 0;
3713b4e3
JB
2510 nla_nest_end(msg, nl_freqs);
2511 }
2512
2513 nla_nest_end(msg, nl_band);
2514
86e8cf98 2515 if (state->split) {
3713b4e3 2516 /* start again here */
86e8cf98 2517 if (state->chan_start)
3713b4e3
JB
2518 band--;
2519 break;
2e161f78 2520 }
2e161f78 2521 }
3713b4e3 2522 nla_nest_end(msg, nl_bands);
2e161f78 2523
57fbcce3 2524 if (band < NUM_NL80211_BANDS)
86e8cf98 2525 state->band_start = band + 1;
3713b4e3 2526 else
86e8cf98 2527 state->band_start = 0;
74b70a4e 2528
3713b4e3 2529 /* if bands & channels are done, continue outside */
86e8cf98
JB
2530 if (state->band_start == 0 && state->chan_start == 0)
2531 state->split_start++;
2532 if (state->split)
3713b4e3 2533 break;
7b506ff6 2534 fallthrough;
3713b4e3 2535 case 4:
ae0be8de
MK
2536 nl_cmds = nla_nest_start_noflag(msg,
2537 NL80211_ATTR_SUPPORTED_COMMANDS);
3713b4e3 2538 if (!nl_cmds)
2e161f78
JB
2539 goto nla_put_failure;
2540
1794899e
JB
2541 i = nl80211_add_commands_unsplit(rdev, msg);
2542 if (i < 0)
2543 goto nla_put_failure;
86e8cf98 2544 if (state->split) {
5de17984
AS
2545 CMD(crit_proto_start, CRIT_PROTOCOL_START);
2546 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 2547 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 2548 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 2549 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
2550 if (rdev->wiphy.features &
2551 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 2552 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 2553 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 2554 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
7010998c 2555 CMD(update_ft_ies, UPDATE_FT_IES);
6bdb68ce
CH
2556 if (rdev->wiphy.sar_capa)
2557 CMD(set_sar_specs, SET_SAR_SPECS);
5de17984 2558 }
3713b4e3 2559#undef CMD
ff1b6e69 2560
3713b4e3 2561 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
2562 state->split_start++;
2563 if (state->split)
3713b4e3 2564 break;
7b506ff6 2565 fallthrough;
3713b4e3 2566 case 5:
1b8ec87a
ZG
2567 if (rdev->ops->remain_on_channel &&
2568 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
2569 nla_put_u32(msg,
2570 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 2571 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
2572 goto nla_put_failure;
2573
1b8ec87a 2574 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
2575 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
2576 goto nla_put_failure;
2577
86e8cf98
JB
2578 state->split_start++;
2579 if (state->split)
3713b4e3 2580 break;
7b506ff6 2581 fallthrough;
3713b4e3
JB
2582 case 6:
2583#ifdef CONFIG_PM
1b8ec87a 2584 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 2585 goto nla_put_failure;
86e8cf98
JB
2586 state->split_start++;
2587 if (state->split)
3713b4e3
JB
2588 break;
2589#else
86e8cf98 2590 state->split_start++;
dfb89c56 2591#endif
7b506ff6 2592 fallthrough;
3713b4e3
JB
2593 case 7:
2594 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 2595 rdev->wiphy.software_iftypes))
3713b4e3 2596 goto nla_put_failure;
ff1b6e69 2597
1b8ec87a 2598 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 2599 state->split))
3713b4e3 2600 goto nla_put_failure;
7527a782 2601
86e8cf98
JB
2602 state->split_start++;
2603 if (state->split)
3713b4e3 2604 break;
7b506ff6 2605 fallthrough;
3713b4e3 2606 case 8:
1b8ec87a 2607 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 2608 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 2609 rdev->wiphy.ap_sme_capa))
3713b4e3 2610 goto nla_put_failure;
7527a782 2611
1b8ec87a 2612 features = rdev->wiphy.features;
fe1abafd
JB
2613 /*
2614 * We can only add the per-channel limit information if the
2615 * dump is split, otherwise it makes it too big. Therefore
2616 * only advertise it in that case.
2617 */
86e8cf98 2618 if (state->split)
fe1abafd
JB
2619 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
2620 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 2621 goto nla_put_failure;
562a7480 2622
1b8ec87a 2623 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 2624 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
2625 sizeof(*rdev->wiphy.ht_capa_mod_mask),
2626 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 2627 goto nla_put_failure;
1f074bd8 2628
1b8ec87a
ZG
2629 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
2630 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 2631 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 2632 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 2633 goto nla_put_failure;
7e7c8926 2634
3713b4e3
JB
2635 /*
2636 * Any information below this point is only available to
2637 * applications that can deal with it being split. This
2638 * helps ensure that newly added capabilities don't break
2639 * older tools by overrunning their buffers.
2640 *
2641 * We still increment split_start so that in the split
2642 * case we'll continue with more data in the next round,
2643 * but break unconditionally so unsplit data stops here.
2644 */
ab10c22b
JB
2645 if (state->split)
2646 state->split_start++;
2647 else
2648 state->split_start = 0;
3713b4e3
JB
2649 break;
2650 case 9:
f8d504ca
JB
2651 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
2652 goto nla_put_failure;
2653
2654 if (nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
2655 rdev->wiphy.max_sched_scan_plans) ||
2656 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
2657 rdev->wiphy.max_sched_scan_plan_interval) ||
2658 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
2659 rdev->wiphy.max_sched_scan_plan_iterations))
2660 goto nla_put_failure;
2661
1b8ec87a 2662 if (rdev->wiphy.extended_capabilities &&
fe1abafd 2663 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
2664 rdev->wiphy.extended_capabilities_len,
2665 rdev->wiphy.extended_capabilities) ||
fe1abafd 2666 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
2667 rdev->wiphy.extended_capabilities_len,
2668 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 2669 goto nla_put_failure;
a50df0c4 2670
1b8ec87a 2671 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 2672 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
2673 sizeof(*rdev->wiphy.vht_capa_mod_mask),
2674 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
2675 goto nla_put_failure;
2676
ae6fa4d5
DK
2677 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
2678 rdev->wiphy.perm_addr))
2679 goto nla_put_failure;
2680
2681 if (!is_zero_ether_addr(rdev->wiphy.addr_mask) &&
2682 nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
2683 rdev->wiphy.addr_mask))
2684 goto nla_put_failure;
2685
2686 if (rdev->wiphy.n_addresses > 1) {
2687 void *attr;
2688
2689 attr = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
2690 if (!attr)
2691 goto nla_put_failure;
2692
2693 for (i = 0; i < rdev->wiphy.n_addresses; i++)
2694 if (nla_put(msg, i + 1, ETH_ALEN,
2695 rdev->wiphy.addresses[i].addr))
2696 goto nla_put_failure;
2697
2698 nla_nest_end(msg, attr);
2699 }
2700
be29b99a
AK
2701 state->split_start++;
2702 break;
2703 case 10:
1b8ec87a 2704 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
2705 goto nla_put_failure;
2706
1b8ec87a 2707 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
2708 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
2709 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
2710 goto nla_put_failure;
b43504cf 2711
1b8ec87a 2712 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 2713 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 2714 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
2715 goto nla_put_failure;
2716
ad7e718c
JB
2717 state->split_start++;
2718 break;
2719 case 11:
1b8ec87a 2720 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
2721 const struct nl80211_vendor_cmd_info *info;
2722 struct nlattr *nested;
2723
ae0be8de
MK
2724 nested = nla_nest_start_noflag(msg,
2725 NL80211_ATTR_VENDOR_DATA);
567ffc35
JB
2726 if (!nested)
2727 goto nla_put_failure;
2728
1b8ec87a
ZG
2729 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
2730 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
2731 if (nla_put(msg, i + 1, sizeof(*info), info))
2732 goto nla_put_failure;
2733 }
2734 nla_nest_end(msg, nested);
2735 }
2736
1b8ec87a 2737 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
2738 const struct nl80211_vendor_cmd_info *info;
2739 struct nlattr *nested;
ad7e718c 2740
ae0be8de
MK
2741 nested = nla_nest_start_noflag(msg,
2742 NL80211_ATTR_VENDOR_EVENTS);
567ffc35 2743 if (!nested)
ad7e718c 2744 goto nla_put_failure;
567ffc35 2745
1b8ec87a
ZG
2746 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
2747 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
2748 if (nla_put(msg, i + 1, sizeof(*info), info))
2749 goto nla_put_failure;
2750 }
2751 nla_nest_end(msg, nested);
2752 }
9a774c78
AO
2753 state->split_start++;
2754 break;
2755 case 12:
2756 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
2757 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
2758 rdev->wiphy.max_num_csa_counters))
2759 goto nla_put_failure;
01e0daa4 2760
1bdd716c
AN
2761 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2762 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
2763 goto nla_put_failure;
2764
ca986ad9
AVS
2765 if (rdev->wiphy.max_sched_scan_reqs &&
2766 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
2767 rdev->wiphy.max_sched_scan_reqs))
2768 goto nla_put_failure;
2769
d75bb06b
GKS
2770 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
2771 sizeof(rdev->wiphy.ext_features),
2772 rdev->wiphy.ext_features))
2773 goto nla_put_failure;
2774
38de03d2
AS
2775 if (rdev->wiphy.bss_select_support) {
2776 struct nlattr *nested;
2777 u32 bss_select_support = rdev->wiphy.bss_select_support;
2778
ae0be8de
MK
2779 nested = nla_nest_start_noflag(msg,
2780 NL80211_ATTR_BSS_SELECT);
38de03d2
AS
2781 if (!nested)
2782 goto nla_put_failure;
2783
2784 i = 0;
2785 while (bss_select_support) {
2786 if ((bss_select_support & 1) &&
2787 nla_put_flag(msg, i))
2788 goto nla_put_failure;
2789 i++;
2790 bss_select_support >>= 1;
2791 }
2792 nla_nest_end(msg, nested);
2793 }
2794
019ae3a9
KV
2795 state->split_start++;
2796 break;
2797 case 13:
2798 if (rdev->wiphy.num_iftype_ext_capab &&
2799 rdev->wiphy.iftype_ext_capab) {
2800 struct nlattr *nested_ext_capab, *nested;
2801
ae0be8de
MK
2802 nested = nla_nest_start_noflag(msg,
2803 NL80211_ATTR_IFTYPE_EXT_CAPA);
019ae3a9
KV
2804 if (!nested)
2805 goto nla_put_failure;
2806
2807 for (i = state->capa_start;
2808 i < rdev->wiphy.num_iftype_ext_capab; i++) {
2809 const struct wiphy_iftype_ext_capab *capab;
2810
2811 capab = &rdev->wiphy.iftype_ext_capab[i];
2812
ae0be8de
MK
2813 nested_ext_capab = nla_nest_start_noflag(msg,
2814 i);
019ae3a9
KV
2815 if (!nested_ext_capab ||
2816 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
2817 capab->iftype) ||
2818 nla_put(msg, NL80211_ATTR_EXT_CAPA,
2819 capab->extended_capabilities_len,
2820 capab->extended_capabilities) ||
2821 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
2822 capab->extended_capabilities_len,
2823 capab->extended_capabilities_mask))
2824 goto nla_put_failure;
2825
2826 nla_nest_end(msg, nested_ext_capab);
2827 if (state->split)
2828 break;
2829 }
2830 nla_nest_end(msg, nested);
2831 if (i < rdev->wiphy.num_iftype_ext_capab) {
2832 state->capa_start = i + 1;
2833 break;
2834 }
2835 }
2836
8585989d
LC
2837 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
2838 rdev->wiphy.nan_supported_bands))
2839 goto nla_put_failure;
2840
52539ca8
THJ
2841 if (wiphy_ext_feature_isset(&rdev->wiphy,
2842 NL80211_EXT_FEATURE_TXQS)) {
2843 struct cfg80211_txq_stats txqstats = {};
2844 int res;
2845
2846 res = rdev_get_txq_stats(rdev, NULL, &txqstats);
2847 if (!res &&
2848 !nl80211_put_txq_stats(msg, &txqstats,
2849 NL80211_ATTR_TXQ_STATS))
2850 goto nla_put_failure;
2851
2852 if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
2853 rdev->wiphy.txq_limit))
2854 goto nla_put_failure;
2855 if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
2856 rdev->wiphy.txq_memory_limit))
2857 goto nla_put_failure;
2858 if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
2859 rdev->wiphy.txq_quantum))
2860 goto nla_put_failure;
2861 }
2862
9bb7e0f2
JB
2863 state->split_start++;
2864 break;
2865 case 14:
2866 if (nl80211_send_pmsr_capa(rdev, msg))
2867 goto nla_put_failure;
2868
ab4dfa20
VJ
2869 state->split_start++;
2870 break;
2871 case 15:
2872 if (rdev->wiphy.akm_suites &&
2873 nla_put(msg, NL80211_ATTR_AKM_SUITES,
2874 sizeof(u32) * rdev->wiphy.n_akm_suites,
2875 rdev->wiphy.akm_suites))
2876 goto nla_put_failure;
2877
d6039a34
VJ
2878 if (nl80211_put_iftype_akm_suites(rdev, msg))
2879 goto nla_put_failure;
2880
3710a8a6
JB
2881 if (nl80211_put_tid_config_support(rdev, msg))
2882 goto nla_put_failure;
6bdb68ce
CH
2883 state->split_start++;
2884 break;
2885 case 16:
2886 if (nl80211_put_sar_specs(rdev, msg))
2887 goto nla_put_failure;
3710a8a6 2888
dc1e3cb8
JC
2889 if (nl80211_put_mbssid_support(&rdev->wiphy, msg))
2890 goto nla_put_failure;
2891
3713b4e3 2892 /* done */
86e8cf98 2893 state->split_start = 0;
3713b4e3
JB
2894 break;
2895 }
3bb20556 2896 finish:
053c095a
JB
2897 genlmsg_end(msg, hdr);
2898 return 0;
55682965
JB
2899
2900 nla_put_failure:
bc3ed28c
TG
2901 genlmsg_cancel(msg, hdr);
2902 return -EMSGSIZE;
55682965
JB
2903}
2904
86e8cf98
JB
2905static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
2906 struct netlink_callback *cb,
2907 struct nl80211_dump_wiphy_state *state)
2908{
50508d94
JB
2909 struct nlattr **tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
2910 int ret;
2911
2912 if (!tb)
2913 return -ENOMEM;
2914
2915 ret = nlmsg_parse_deprecated(cb->nlh,
2916 GENL_HDRLEN + nl80211_fam.hdrsize,
2917 tb, nl80211_fam.maxattr,
2918 nl80211_policy, NULL);
86e8cf98 2919 /* ignore parse errors for backward compatibility */
50508d94
JB
2920 if (ret) {
2921 ret = 0;
2922 goto out;
2923 }
86e8cf98
JB
2924
2925 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
2926 if (tb[NL80211_ATTR_WIPHY])
2927 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2928 if (tb[NL80211_ATTR_WDEV])
2929 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
2930 if (tb[NL80211_ATTR_IFINDEX]) {
2931 struct net_device *netdev;
2932 struct cfg80211_registered_device *rdev;
2933 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2934
7f2b8562 2935 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
50508d94
JB
2936 if (!netdev) {
2937 ret = -ENODEV;
2938 goto out;
2939 }
86e8cf98 2940 if (netdev->ieee80211_ptr) {
f26cbf40 2941 rdev = wiphy_to_rdev(
86e8cf98
JB
2942 netdev->ieee80211_ptr->wiphy);
2943 state->filter_wiphy = rdev->wiphy_idx;
2944 }
86e8cf98
JB
2945 }
2946
50508d94
JB
2947 ret = 0;
2948out:
2949 kfree(tb);
2950 return ret;
86e8cf98
JB
2951}
2952
55682965
JB
2953static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
2954{
645e77de 2955 int idx = 0, ret;
86e8cf98 2956 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 2957 struct cfg80211_registered_device *rdev;
3a5a423b 2958
5fe231e8 2959 rtnl_lock();
86e8cf98
JB
2960 if (!state) {
2961 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
2962 if (!state) {
2963 rtnl_unlock();
86e8cf98 2964 return -ENOMEM;
3713b4e3 2965 }
86e8cf98
JB
2966 state->filter_wiphy = -1;
2967 ret = nl80211_dump_wiphy_parse(skb, cb, state);
2968 if (ret) {
2969 kfree(state);
2970 rtnl_unlock();
2971 return ret;
3713b4e3 2972 }
86e8cf98 2973 cb->args[0] = (long)state;
3713b4e3
JB
2974 }
2975
1b8ec87a
ZG
2976 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2977 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2978 continue;
86e8cf98 2979 if (++idx <= state->start)
55682965 2980 continue;
86e8cf98 2981 if (state->filter_wiphy != -1 &&
1b8ec87a 2982 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
2983 continue;
2984 /* attempt to fit multiple wiphy data chunks into the skb */
2985 do {
3bb20556
JB
2986 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
2987 skb,
3713b4e3
JB
2988 NETLINK_CB(cb->skb).portid,
2989 cb->nlh->nlmsg_seq,
86e8cf98 2990 NLM_F_MULTI, state);
3713b4e3
JB
2991 if (ret < 0) {
2992 /*
2993 * If sending the wiphy data didn't fit (ENOBUFS
2994 * or EMSGSIZE returned), this SKB is still
2995 * empty (so it's not too big because another
2996 * wiphy dataset is already in the skb) and
2997 * we've not tried to adjust the dump allocation
2998 * yet ... then adjust the alloc size to be
2999 * bigger, and return 1 but with the empty skb.
3000 * This results in an empty message being RX'ed
3001 * in userspace, but that is ignored.
3002 *
3003 * We can then retry with the larger buffer.
3004 */
3005 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 3006 !skb->len && !state->split &&
3713b4e3
JB
3007 cb->min_dump_alloc < 4096) {
3008 cb->min_dump_alloc = 4096;
f12cb289 3009 state->split_start = 0;
d98cae64 3010 rtnl_unlock();
3713b4e3
JB
3011 return 1;
3012 }
3013 idx--;
3014 break;
645e77de 3015 }
86e8cf98 3016 } while (state->split_start > 0);
3713b4e3 3017 break;
55682965 3018 }
5fe231e8 3019 rtnl_unlock();
55682965 3020
86e8cf98 3021 state->start = idx;
55682965
JB
3022
3023 return skb->len;
3024}
3025
86e8cf98
JB
3026static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
3027{
3028 kfree((void *)cb->args[0]);
3029 return 0;
3030}
3031
55682965
JB
3032static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
3033{
3034 struct sk_buff *msg;
1b8ec87a 3035 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 3036 struct nl80211_dump_wiphy_state state = {};
55682965 3037
645e77de 3038 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 3039 if (!msg)
4c476991 3040 return -ENOMEM;
55682965 3041
3bb20556
JB
3042 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
3043 info->snd_portid, info->snd_seq, 0,
86e8cf98 3044 &state) < 0) {
4c476991
JB
3045 nlmsg_free(msg);
3046 return -ENOBUFS;
3047 }
55682965 3048
134e6375 3049 return genlmsg_reply(msg, info);
55682965
JB
3050}
3051
31888487
JM
3052static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
3053 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
3054 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
3055 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
3056 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
3057 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
3058};
3059
3060static int parse_txq_params(struct nlattr *tb[],
3061 struct ieee80211_txq_params *txq_params)
3062{
259d8c1e
DW
3063 u8 ac;
3064
a3304b0a 3065 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
3066 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
3067 !tb[NL80211_TXQ_ATTR_AIFS])
3068 return -EINVAL;
3069
259d8c1e 3070 ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
3071 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
3072 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
3073 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
3074 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
3075
259d8c1e 3076 if (ac >= NL80211_NUM_ACS)
a3304b0a 3077 return -EINVAL;
259d8c1e 3078 txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
31888487
JM
3079 return 0;
3080}
3081
f444de05
JB
3082static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
3083{
3084 /*
e7e0517c
JB
3085 * You can only set the channel explicitly for some interfaces,
3086 * most have their channel managed via their respective
cc1d2806
JB
3087 * "establish a connection" command (connect, join, ...)
3088 *
3089 * For AP/GO and mesh mode, the channel can be set with the
3090 * channel userspace API, but is only stored and passed to the
3091 * low-level driver when the AP starts or the mesh is joined.
3092 * This is for backward compatibility, userspace can also give
3093 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
3094 *
3095 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
3096 * whatever else is going on, so they have their own special
3097 * operation to set the monitor channel if possible.
f444de05
JB
3098 */
3099 return !wdev ||
3100 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 3101 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
3102 wdev->iftype == NL80211_IFTYPE_MONITOR ||
3103 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
3104}
3105
9bb7e0f2
JB
3106int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
3107 struct genl_info *info,
3108 struct cfg80211_chan_def *chandef)
683b6d3b 3109{
49f9cf0e
JB
3110 struct netlink_ext_ack *extack = info->extack;
3111 struct nlattr **attrs = info->attrs;
dbeca2ea 3112 u32 control_freq;
683b6d3b 3113
49f9cf0e 3114 if (!attrs[NL80211_ATTR_WIPHY_FREQ])
683b6d3b
JB
3115 return -EINVAL;
3116
942ba88b
TP
3117 control_freq = MHZ_TO_KHZ(
3118 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3119 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
3120 control_freq +=
3121 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
683b6d3b 3122
f43e5210 3123 memset(chandef, 0, sizeof(*chandef));
942ba88b 3124 chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
3d9d1d66 3125 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
942ba88b
TP
3126 chandef->center_freq1 = KHZ_TO_MHZ(control_freq);
3127 chandef->freq1_offset = control_freq % 1000;
3d9d1d66 3128 chandef->center_freq2 = 0;
683b6d3b
JB
3129
3130 /* Primary channel not allowed */
49f9cf0e
JB
3131 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) {
3132 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
3133 "Channel is disabled");
683b6d3b 3134 return -EINVAL;
49f9cf0e 3135 }
683b6d3b 3136
49f9cf0e 3137 if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
3d9d1d66
JB
3138 enum nl80211_channel_type chantype;
3139
49f9cf0e 3140 chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
3d9d1d66
JB
3141
3142 switch (chantype) {
3143 case NL80211_CHAN_NO_HT:
3144 case NL80211_CHAN_HT20:
3145 case NL80211_CHAN_HT40PLUS:
3146 case NL80211_CHAN_HT40MINUS:
3147 cfg80211_chandef_create(chandef, chandef->chan,
3148 chantype);
ffa4629e 3149 /* user input for center_freq is incorrect */
49f9cf0e
JB
3150 if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
3151 chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
3152 NL_SET_ERR_MSG_ATTR(extack,
3153 attrs[NL80211_ATTR_CENTER_FREQ1],
3154 "bad center frequency 1");
ffa4629e 3155 return -EINVAL;
49f9cf0e 3156 }
ffa4629e 3157 /* center_freq2 must be zero */
49f9cf0e
JB
3158 if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
3159 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
3160 NL_SET_ERR_MSG_ATTR(extack,
3161 attrs[NL80211_ATTR_CENTER_FREQ2],
3162 "center frequency 2 can't be used");
ffa4629e 3163 return -EINVAL;
49f9cf0e 3164 }
3d9d1d66
JB
3165 break;
3166 default:
49f9cf0e
JB
3167 NL_SET_ERR_MSG_ATTR(extack,
3168 attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3169 "invalid channel type");
3d9d1d66
JB
3170 return -EINVAL;
3171 }
49f9cf0e 3172 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
3d9d1d66 3173 chandef->width =
49f9cf0e 3174 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
942ba88b 3175 if (attrs[NL80211_ATTR_CENTER_FREQ1]) {
3d9d1d66 3176 chandef->center_freq1 =
49f9cf0e 3177 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
942ba88b
TP
3178 if (attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET])
3179 chandef->freq1_offset = nla_get_u32(
3180 attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET]);
3181 else
3182 chandef->freq1_offset = 0;
3183 }
49f9cf0e 3184 if (attrs[NL80211_ATTR_CENTER_FREQ2])
3d9d1d66 3185 chandef->center_freq2 =
49f9cf0e 3186 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
3d9d1d66
JB
3187 }
3188
2a38075c
AAL
3189 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
3190 chandef->edmg.channels =
3191 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
3192
3193 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
3194 chandef->edmg.bw_config =
3195 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
3196 } else {
3197 chandef->edmg.bw_config = 0;
3198 chandef->edmg.channels = 0;
3199 }
3200
49f9cf0e
JB
3201 if (!cfg80211_chandef_valid(chandef)) {
3202 NL_SET_ERR_MSG(extack, "invalid channel definition");
3d9d1d66 3203 return -EINVAL;
49f9cf0e 3204 }
3d9d1d66 3205
9f5e8f6e 3206 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
49f9cf0e
JB
3207 IEEE80211_CHAN_DISABLED)) {
3208 NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
3d9d1d66 3209 return -EINVAL;
49f9cf0e 3210 }
3d9d1d66 3211
2f301ab2
SW
3212 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
3213 chandef->width == NL80211_CHAN_WIDTH_10) &&
49f9cf0e
JB
3214 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
3215 NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
2f301ab2 3216 return -EINVAL;
49f9cf0e 3217 }
2f301ab2 3218
683b6d3b
JB
3219 return 0;
3220}
3221
f444de05 3222static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 3223 struct net_device *dev,
f444de05
JB
3224 struct genl_info *info)
3225{
683b6d3b 3226 struct cfg80211_chan_def chandef;
f444de05 3227 int result;
e8c9bd5b 3228 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 3229 struct wireless_dev *wdev = NULL;
e8c9bd5b 3230
e16821bc
JM
3231 if (dev)
3232 wdev = dev->ieee80211_ptr;
f444de05
JB
3233 if (!nl80211_can_set_dev_channel(wdev))
3234 return -EOPNOTSUPP;
e16821bc
JM
3235 if (wdev)
3236 iftype = wdev->iftype;
f444de05 3237
683b6d3b
JB
3238 result = nl80211_parse_chandef(rdev, info, &chandef);
3239 if (result)
3240 return result;
f444de05 3241
e8c9bd5b 3242 switch (iftype) {
aa430da4
JB
3243 case NL80211_IFTYPE_AP:
3244 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
3245 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
3246 iftype)) {
aa430da4
JB
3247 result = -EINVAL;
3248 break;
3249 }
e16821bc
JM
3250 if (wdev->beacon_interval) {
3251 if (!dev || !rdev->ops->set_ap_chanwidth ||
3252 !(rdev->wiphy.features &
3253 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
3254 result = -EBUSY;
3255 break;
3256 }
3257
3258 /* Only allow dynamic channel width changes */
3259 if (chandef.chan != wdev->preset_chandef.chan) {
3260 result = -EBUSY;
3261 break;
3262 }
3263 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
3264 if (result)
3265 break;
3266 }
683b6d3b 3267 wdev->preset_chandef = chandef;
aa430da4
JB
3268 result = 0;
3269 break;
cc1d2806 3270 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 3271 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 3272 break;
e8c9bd5b 3273 case NL80211_IFTYPE_MONITOR:
683b6d3b 3274 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 3275 break;
aa430da4 3276 default:
e8c9bd5b 3277 result = -EINVAL;
f444de05 3278 }
f444de05
JB
3279
3280 return result;
3281}
3282
3283static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
3284{
4c476991
JB
3285 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3286 struct net_device *netdev = info->user_ptr[1];
f444de05 3287
e16821bc 3288 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
3289}
3290
55682965
JB
3291static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
3292{
a05829a7 3293 struct cfg80211_registered_device *rdev = NULL;
f444de05
JB
3294 struct net_device *netdev = NULL;
3295 struct wireless_dev *wdev;
a1e567c8 3296 int result = 0, rem_txq_params = 0;
31888487 3297 struct nlattr *nl_txq_params;
b9a5f8ca
JM
3298 u32 changed;
3299 u8 retry_short = 0, retry_long = 0;
3300 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 3301 u8 coverage_class = 0;
52539ca8 3302 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
55682965 3303
a05829a7 3304 rtnl_lock();
f444de05
JB
3305 /*
3306 * Try to find the wiphy and netdev. Normally this
3307 * function shouldn't need the netdev, but this is
3308 * done for backward compatibility -- previously
3309 * setting the channel was done per wiphy, but now
3310 * it is per netdev. Previous userland like hostapd
3311 * also passed a netdev to set_wiphy, so that it is
3312 * possible to let that go to the right netdev!
3313 */
4bbf4d56 3314
f444de05
JB
3315 if (info->attrs[NL80211_ATTR_IFINDEX]) {
3316 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
3317
7f2b8562 3318 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 3319 if (netdev && netdev->ieee80211_ptr)
f26cbf40 3320 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 3321 else
f444de05 3322 netdev = NULL;
4bbf4d56
JB
3323 }
3324
f444de05 3325 if (!netdev) {
878d9ec7
JB
3326 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
3327 info->attrs);
a05829a7
JB
3328 if (IS_ERR(rdev)) {
3329 rtnl_unlock();
4c476991 3330 return PTR_ERR(rdev);
a05829a7 3331 }
f444de05
JB
3332 wdev = NULL;
3333 netdev = NULL;
3334 result = 0;
71fe96bf 3335 } else
f444de05 3336 wdev = netdev->ieee80211_ptr;
f444de05 3337
a05829a7 3338 wiphy_lock(&rdev->wiphy);
a05829a7 3339
f444de05
JB
3340 /*
3341 * end workaround code, by now the rdev is available
3342 * and locked, and wdev may or may not be NULL.
3343 */
4bbf4d56
JB
3344
3345 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
3346 result = cfg80211_dev_rename(
3347 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
0391a45c 3348 rtnl_unlock();
4bbf4d56 3349
4bbf4d56 3350 if (result)
a05829a7 3351 goto out;
31888487
JM
3352
3353 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
3354 struct ieee80211_txq_params txq_params;
3355 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
3356
a05829a7
JB
3357 if (!rdev->ops->set_txq_params) {
3358 result = -EOPNOTSUPP;
3359 goto out;
3360 }
31888487 3361
a05829a7
JB
3362 if (!netdev) {
3363 result = -EINVAL;
3364 goto out;
3365 }
f70f01c2 3366
133a3ff2 3367 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
a05829a7
JB
3368 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
3369 result = -EINVAL;
3370 goto out;
3371 }
133a3ff2 3372
a05829a7
JB
3373 if (!netif_running(netdev)) {
3374 result = -ENETDOWN;
3375 goto out;
3376 }
2b5f8b0b 3377
31888487
JM
3378 nla_for_each_nested(nl_txq_params,
3379 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
3380 rem_txq_params) {
8cb08174
JB
3381 result = nla_parse_nested_deprecated(tb,
3382 NL80211_TXQ_ATTR_MAX,
3383 nl_txq_params,
3384 txq_params_policy,
3385 info->extack);
ae811e21 3386 if (result)
a05829a7 3387 goto out;
31888487
JM
3388 result = parse_txq_params(tb, &txq_params);
3389 if (result)
a05829a7 3390 goto out;
31888487 3391
e35e4d28
HG
3392 result = rdev_set_txq_params(rdev, netdev,
3393 &txq_params);
31888487 3394 if (result)
a05829a7 3395 goto out;
31888487
JM
3396 }
3397 }
55682965 3398
72bdcf34 3399 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
3400 result = __nl80211_set_channel(
3401 rdev,
3402 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
3403 info);
72bdcf34 3404 if (result)
a05829a7 3405 goto out;
72bdcf34
JM
3406 }
3407
98d2ff8b 3408 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 3409 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
3410 enum nl80211_tx_power_setting type;
3411 int idx, mbm = 0;
3412
c8442118
JB
3413 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
3414 txp_wdev = NULL;
3415
a05829a7
JB
3416 if (!rdev->ops->set_tx_power) {
3417 result = -EOPNOTSUPP;
3418 goto out;
3419 }
98d2ff8b
JO
3420
3421 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
3422 type = nla_get_u32(info->attrs[idx]);
3423
3424 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
a05829a7
JB
3425 (type != NL80211_TX_POWER_AUTOMATIC)) {
3426 result = -EINVAL;
3427 goto out;
3428 }
98d2ff8b
JO
3429
3430 if (type != NL80211_TX_POWER_AUTOMATIC) {
3431 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
3432 mbm = nla_get_u32(info->attrs[idx]);
3433 }
3434
c8442118 3435 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 3436 if (result)
a05829a7 3437 goto out;
98d2ff8b
JO
3438 }
3439
afe0cbf8
BR
3440 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
3441 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
3442 u32 tx_ant, rx_ant;
7a087e74 3443
7f531e03
BR
3444 if ((!rdev->wiphy.available_antennas_tx &&
3445 !rdev->wiphy.available_antennas_rx) ||
a05829a7
JB
3446 !rdev->ops->set_antenna) {
3447 result = -EOPNOTSUPP;
3448 goto out;
3449 }
afe0cbf8
BR
3450
3451 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
3452 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
3453
a7ffac95 3454 /* reject antenna configurations which don't match the
7f531e03
BR
3455 * available antenna masks, except for the "all" mask */
3456 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
a05829a7
JB
3457 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
3458 result = -EINVAL;
3459 goto out;
3460 }
a7ffac95 3461
7f531e03
BR
3462 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
3463 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 3464
e35e4d28 3465 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 3466 if (result)
a05829a7 3467 goto out;
afe0cbf8
BR
3468 }
3469
b9a5f8ca
JM
3470 changed = 0;
3471
3472 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
3473 retry_short = nla_get_u8(
3474 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562 3475
b9a5f8ca
JM
3476 changed |= WIPHY_PARAM_RETRY_SHORT;
3477 }
3478
3479 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
3480 retry_long = nla_get_u8(
3481 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562 3482
b9a5f8ca
JM
3483 changed |= WIPHY_PARAM_RETRY_LONG;
3484 }
3485
3486 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
3487 frag_threshold = nla_get_u32(
3488 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
a05829a7
JB
3489 if (frag_threshold < 256) {
3490 result = -EINVAL;
3491 goto out;
3492 }
7f2b8562 3493
b9a5f8ca
JM
3494 if (frag_threshold != (u32) -1) {
3495 /*
3496 * Fragments (apart from the last one) are required to
3497 * have even length. Make the fragmentation code
3498 * simpler by stripping LSB should someone try to use
3499 * odd threshold value.
3500 */
3501 frag_threshold &= ~0x1;
3502 }
3503 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
3504 }
3505
3506 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
3507 rts_threshold = nla_get_u32(
3508 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
3509 changed |= WIPHY_PARAM_RTS_THRESHOLD;
3510 }
3511
81077e82 3512 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
a05829a7
JB
3513 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
3514 result = -EINVAL;
3515 goto out;
3516 }
3057dbfd 3517
81077e82
LT
3518 coverage_class = nla_get_u8(
3519 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
3520 changed |= WIPHY_PARAM_COVERAGE_CLASS;
3521 }
3522
3057dbfd 3523 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
a05829a7
JB
3524 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION)) {
3525 result = -EOPNOTSUPP;
3526 goto out;
3527 }
3057dbfd
LB
3528
3529 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
3530 }
3531
52539ca8
THJ
3532 if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
3533 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3534 NL80211_EXT_FEATURE_TXQS)) {
3535 result = -EOPNOTSUPP;
3536 goto out;
3537 }
52539ca8
THJ
3538 txq_limit = nla_get_u32(
3539 info->attrs[NL80211_ATTR_TXQ_LIMIT]);
3540 changed |= WIPHY_PARAM_TXQ_LIMIT;
3541 }
3542
3543 if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
3544 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3545 NL80211_EXT_FEATURE_TXQS)) {
3546 result = -EOPNOTSUPP;
3547 goto out;
3548 }
52539ca8
THJ
3549 txq_memory_limit = nla_get_u32(
3550 info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
3551 changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
3552 }
3553
3554 if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
3555 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3556 NL80211_EXT_FEATURE_TXQS)) {
3557 result = -EOPNOTSUPP;
3558 goto out;
3559 }
52539ca8
THJ
3560 txq_quantum = nla_get_u32(
3561 info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
3562 changed |= WIPHY_PARAM_TXQ_QUANTUM;
3563 }
3564
b9a5f8ca
JM
3565 if (changed) {
3566 u8 old_retry_short, old_retry_long;
3567 u32 old_frag_threshold, old_rts_threshold;
81077e82 3568 u8 old_coverage_class;
52539ca8 3569 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
b9a5f8ca 3570
a05829a7
JB
3571 if (!rdev->ops->set_wiphy_params) {
3572 result = -EOPNOTSUPP;
3573 goto out;
3574 }
b9a5f8ca
JM
3575
3576 old_retry_short = rdev->wiphy.retry_short;
3577 old_retry_long = rdev->wiphy.retry_long;
3578 old_frag_threshold = rdev->wiphy.frag_threshold;
3579 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 3580 old_coverage_class = rdev->wiphy.coverage_class;
52539ca8
THJ
3581 old_txq_limit = rdev->wiphy.txq_limit;
3582 old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
3583 old_txq_quantum = rdev->wiphy.txq_quantum;
b9a5f8ca
JM
3584
3585 if (changed & WIPHY_PARAM_RETRY_SHORT)
3586 rdev->wiphy.retry_short = retry_short;
3587 if (changed & WIPHY_PARAM_RETRY_LONG)
3588 rdev->wiphy.retry_long = retry_long;
3589 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
3590 rdev->wiphy.frag_threshold = frag_threshold;
3591 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
3592 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
3593 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
3594 rdev->wiphy.coverage_class = coverage_class;
52539ca8
THJ
3595 if (changed & WIPHY_PARAM_TXQ_LIMIT)
3596 rdev->wiphy.txq_limit = txq_limit;
3597 if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
3598 rdev->wiphy.txq_memory_limit = txq_memory_limit;
3599 if (changed & WIPHY_PARAM_TXQ_QUANTUM)
3600 rdev->wiphy.txq_quantum = txq_quantum;
b9a5f8ca 3601
e35e4d28 3602 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
3603 if (result) {
3604 rdev->wiphy.retry_short = old_retry_short;
3605 rdev->wiphy.retry_long = old_retry_long;
3606 rdev->wiphy.frag_threshold = old_frag_threshold;
3607 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 3608 rdev->wiphy.coverage_class = old_coverage_class;
52539ca8
THJ
3609 rdev->wiphy.txq_limit = old_txq_limit;
3610 rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
3611 rdev->wiphy.txq_quantum = old_txq_quantum;
a05829a7 3612 goto out;
b9a5f8ca
JM
3613 }
3614 }
a05829a7
JB
3615
3616 result = 0;
3617
3618out:
3619 wiphy_unlock(&rdev->wiphy);
3620 return result;
55682965
JB
3621}
3622
683b6d3b 3623static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 3624 const struct cfg80211_chan_def *chandef)
683b6d3b 3625{
601555cd
JB
3626 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
3627 return -EINVAL;
3d9d1d66 3628
683b6d3b
JB
3629 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
3630 chandef->chan->center_freq))
3631 return -ENOBUFS;
942ba88b
TP
3632 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
3633 chandef->chan->freq_offset))
3634 return -ENOBUFS;
3d9d1d66
JB
3635 switch (chandef->width) {
3636 case NL80211_CHAN_WIDTH_20_NOHT:
3637 case NL80211_CHAN_WIDTH_20:
3638 case NL80211_CHAN_WIDTH_40:
3639 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3640 cfg80211_get_chandef_type(chandef)))
3641 return -ENOBUFS;
3642 break;
3643 default:
3644 break;
3645 }
3646 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
3647 return -ENOBUFS;
3648 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
3649 return -ENOBUFS;
3650 if (chandef->center_freq2 &&
3651 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
3652 return -ENOBUFS;
3653 return 0;
3654}
3655
15e47304 3656static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 3657 struct cfg80211_registered_device *rdev,
3d1a5bbf
AZ
3658 struct wireless_dev *wdev,
3659 enum nl80211_commands cmd)
55682965 3660{
72fb2abc 3661 struct net_device *dev = wdev->netdev;
55682965
JB
3662 void *hdr;
3663
3d1a5bbf
AZ
3664 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
3665 cmd != NL80211_CMD_DEL_INTERFACE &&
3666 cmd != NL80211_CMD_SET_INTERFACE);
8f894be2
TB
3667
3668 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
3669 if (!hdr)
3670 return -1;
3671
72fb2abc
JB
3672 if (dev &&
3673 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 3674 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
3675 goto nla_put_failure;
3676
3677 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3678 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
3679 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
3680 NL80211_ATTR_PAD) ||
98104fde 3681 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
3682 nla_put_u32(msg, NL80211_ATTR_GENERATION,
3683 rdev->devlist_generation ^
446faa15
AQ
3684 (cfg80211_rdev_list_generation << 2)) ||
3685 nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
9360ffd1 3686 goto nla_put_failure;
f5ea9120 3687
5b7ccaf3 3688 if (rdev->ops->get_channel) {
683b6d3b 3689 int ret;
f43e5210 3690 struct cfg80211_chan_def chandef = {};
683b6d3b
JB
3691
3692 ret = rdev_get_channel(rdev, wdev, &chandef);
3693 if (ret == 0) {
3694 if (nl80211_send_chandef(msg, &chandef))
3695 goto nla_put_failure;
3696 }
d91df0e3
PF
3697 }
3698
d55d0d59
RM
3699 if (rdev->ops->get_tx_power) {
3700 int dbm, ret;
3701
3702 ret = rdev_get_tx_power(rdev, wdev, &dbm);
3703 if (ret == 0 &&
3704 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
3705 DBM_TO_MBM(dbm)))
3706 goto nla_put_failure;
3707 }
3708
44905265
JB
3709 wdev_lock(wdev);
3710 switch (wdev->iftype) {
3711 case NL80211_IFTYPE_AP:
3712 if (wdev->ssid_len &&
3713 nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
4564b187 3714 goto nla_put_failure_locked;
44905265
JB
3715 break;
3716 case NL80211_IFTYPE_STATION:
3717 case NL80211_IFTYPE_P2P_CLIENT:
3718 case NL80211_IFTYPE_ADHOC: {
fb8b53ac
JB
3719 const struct element *ssid_elem;
3720
44905265
JB
3721 if (!wdev->current_bss)
3722 break;
7a94b8c2 3723 rcu_read_lock();
fb8b53ac
JB
3724 ssid_elem = ieee80211_bss_get_elem(&wdev->current_bss->pub,
3725 WLAN_EID_SSID);
3726 if (ssid_elem &&
3727 nla_put(msg, NL80211_ATTR_SSID, ssid_elem->datalen,
3728 ssid_elem->data))
7a94b8c2
DB
3729 goto nla_put_failure_rcu_locked;
3730 rcu_read_unlock();
44905265
JB
3731 break;
3732 }
3733 default:
3734 /* nothing */
3735 break;
b84e7a05 3736 }
44905265 3737 wdev_unlock(wdev);
b84e7a05 3738
52539ca8
THJ
3739 if (rdev->ops->get_txq_stats) {
3740 struct cfg80211_txq_stats txqstats = {};
3741 int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
3742
3743 if (ret == 0 &&
3744 !nl80211_put_txq_stats(msg, &txqstats,
3745 NL80211_ATTR_TXQ_STATS))
3746 goto nla_put_failure;
3747 }
3748
053c095a
JB
3749 genlmsg_end(msg, hdr);
3750 return 0;
55682965 3751
7a94b8c2
DB
3752 nla_put_failure_rcu_locked:
3753 rcu_read_unlock();
4564b187
JB
3754 nla_put_failure_locked:
3755 wdev_unlock(wdev);
55682965 3756 nla_put_failure:
bc3ed28c
TG
3757 genlmsg_cancel(msg, hdr);
3758 return -EMSGSIZE;
55682965
JB
3759}
3760
3761static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
3762{
3763 int wp_idx = 0;
3764 int if_idx = 0;
3765 int wp_start = cb->args[0];
3766 int if_start = cb->args[1];
b7fb44da 3767 int filter_wiphy = -1;
f5ea9120 3768 struct cfg80211_registered_device *rdev;
55682965 3769 struct wireless_dev *wdev;
ea90e0dc 3770 int ret;
55682965 3771
5fe231e8 3772 rtnl_lock();
b7fb44da
DK
3773 if (!cb->args[2]) {
3774 struct nl80211_dump_wiphy_state state = {
3775 .filter_wiphy = -1,
3776 };
b7fb44da
DK
3777
3778 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
3779 if (ret)
ea90e0dc 3780 goto out_unlock;
b7fb44da
DK
3781
3782 filter_wiphy = state.filter_wiphy;
3783
3784 /*
3785 * if filtering, set cb->args[2] to +1 since 0 is the default
3786 * value needed to determine that parsing is necessary.
3787 */
3788 if (filter_wiphy >= 0)
3789 cb->args[2] = filter_wiphy + 1;
3790 else
3791 cb->args[2] = -1;
3792 } else if (cb->args[2] > 0) {
3793 filter_wiphy = cb->args[2] - 1;
3794 }
3795
f5ea9120
JB
3796 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
3797 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 3798 continue;
bba95fef
JB
3799 if (wp_idx < wp_start) {
3800 wp_idx++;
55682965 3801 continue;
bba95fef 3802 }
b7fb44da
DK
3803
3804 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
3805 continue;
3806
55682965
JB
3807 if_idx = 0;
3808
53873f13 3809 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
3810 if (if_idx < if_start) {
3811 if_idx++;
55682965 3812 continue;
bba95fef 3813 }
15e47304 3814 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 3815 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3d1a5bbf
AZ
3816 rdev, wdev,
3817 NL80211_CMD_NEW_INTERFACE) < 0) {
bba95fef
JB
3818 goto out;
3819 }
3820 if_idx++;
55682965 3821 }
bba95fef
JB
3822
3823 wp_idx++;
55682965 3824 }
bba95fef 3825 out:
55682965
JB
3826 cb->args[0] = wp_idx;
3827 cb->args[1] = if_idx;
3828
ea90e0dc
JB
3829 ret = skb->len;
3830 out_unlock:
3831 rtnl_unlock();
3832
3833 return ret;
55682965
JB
3834}
3835
3836static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
3837{
3838 struct sk_buff *msg;
1b8ec87a 3839 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 3840 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3841
fd2120ca 3842 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 3843 if (!msg)
4c476991 3844 return -ENOMEM;
55682965 3845
15e47304 3846 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 3847 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
4c476991
JB
3848 nlmsg_free(msg);
3849 return -ENOBUFS;
3850 }
55682965 3851
134e6375 3852 return genlmsg_reply(msg, info);
55682965
JB
3853}
3854
66f7ac50
MW
3855static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
3856 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
3857 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
3858 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
3859 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
3860 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 3861 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
3862};
3863
3864static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
3865{
3866 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
3867 int flag;
3868
3869 *mntrflags = 0;
3870
3871 if (!nla)
3872 return -EINVAL;
3873
8cb08174 3874 if (nla_parse_nested_deprecated(flags, NL80211_MNTR_FLAG_MAX, nla, mntr_flags_policy, NULL))
66f7ac50
MW
3875 return -EINVAL;
3876
3877 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
3878 if (flags[flag])
3879 *mntrflags |= (1<<flag);
3880
818a986e
JB
3881 *mntrflags |= MONITOR_FLAG_CHANGED;
3882
66f7ac50
MW
3883 return 0;
3884}
3885
1db77596
JB
3886static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
3887 enum nl80211_iftype type,
3888 struct genl_info *info,
3889 struct vif_params *params)
3890{
3891 bool change = false;
3892 int err;
3893
3894 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
3895 if (type != NL80211_IFTYPE_MONITOR)
3896 return -EINVAL;
3897
3898 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
3899 &params->flags);
3900 if (err)
3901 return err;
3902
3903 change = true;
3904 }
3905
3906 if (params->flags & MONITOR_FLAG_ACTIVE &&
3907 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
3908 return -EOPNOTSUPP;
3909
3910 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
3911 const u8 *mumimo_groups;
3912 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3913
3914 if (type != NL80211_IFTYPE_MONITOR)
3915 return -EINVAL;
3916
3917 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3918 return -EOPNOTSUPP;
3919
3920 mumimo_groups =
3921 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
3922
3923 /* bits 0 and 63 are reserved and must be zero */
4954601f
JB
3924 if ((mumimo_groups[0] & BIT(0)) ||
3925 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
1db77596
JB
3926 return -EINVAL;
3927
3928 params->vht_mumimo_groups = mumimo_groups;
3929 change = true;
3930 }
3931
3932 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
3933 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3934
3935 if (type != NL80211_IFTYPE_MONITOR)
3936 return -EINVAL;
3937
3938 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3939 return -EOPNOTSUPP;
3940
3941 params->vht_mumimo_follow_addr =
3942 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
3943 change = true;
3944 }
3945
3946 return change ? 1 : 0;
3947}
3948
9bc383de 3949static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
3950 struct net_device *netdev, u8 use_4addr,
3951 enum nl80211_iftype iftype)
9bc383de 3952{
ad4bb6f8 3953 if (!use_4addr) {
2e92a2d0 3954 if (netdev && netif_is_bridge_port(netdev))
ad4bb6f8 3955 return -EBUSY;
9bc383de 3956 return 0;
ad4bb6f8 3957 }
9bc383de
JB
3958
3959 switch (iftype) {
3960 case NL80211_IFTYPE_AP_VLAN:
3961 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
3962 return 0;
3963 break;
3964 case NL80211_IFTYPE_STATION:
3965 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
3966 return 0;
3967 break;
3968 default:
3969 break;
3970 }
3971
3972 return -EOPNOTSUPP;
3973}
3974
55682965
JB
3975static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3976{
4c476991 3977 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3978 struct vif_params params;
e36d56b6 3979 int err;
04a773ad 3980 enum nl80211_iftype otype, ntype;
4c476991 3981 struct net_device *dev = info->user_ptr[1];
ac7f9cfa 3982 bool change = false;
55682965 3983
2ec600d6
LCC
3984 memset(&params, 0, sizeof(params));
3985
04a773ad 3986 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 3987
723b038d 3988 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 3989 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 3990 if (otype != ntype)
ac7f9cfa 3991 change = true;
723b038d
JB
3992 }
3993
92ffe055 3994 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
3995 struct wireless_dev *wdev = dev->ieee80211_ptr;
3996
4c476991
JB
3997 if (ntype != NL80211_IFTYPE_MESH_POINT)
3998 return -EINVAL;
29cbe68c
JB
3999 if (netif_running(dev))
4000 return -EBUSY;
4001
4002 wdev_lock(wdev);
4003 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
4004 IEEE80211_MAX_MESH_ID_LEN);
4005 wdev->mesh_id_up_len =
4006 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4007 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
4008 wdev->mesh_id_up_len);
4009 wdev_unlock(wdev);
2ec600d6
LCC
4010 }
4011
8b787643
FF
4012 if (info->attrs[NL80211_ATTR_4ADDR]) {
4013 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
4014 change = true;
ad4bb6f8 4015 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 4016 if (err)
4c476991 4017 return err;
8b787643
FF
4018 } else {
4019 params.use_4addr = -1;
4020 }
4021
1db77596
JB
4022 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
4023 if (err < 0)
4024 return err;
4025 if (err > 0)
c6e6a0c8 4026 change = true;
e057d3c3 4027
ac7f9cfa 4028 if (change)
818a986e 4029 err = cfg80211_change_iface(rdev, dev, ntype, &params);
ac7f9cfa
JB
4030 else
4031 err = 0;
60719ffd 4032
9bc383de
JB
4033 if (!err && params.use_4addr != -1)
4034 dev->ieee80211_ptr->use_4addr = params.use_4addr;
4035
3d1a5bbf
AZ
4036 if (change && !err) {
4037 struct wireless_dev *wdev = dev->ieee80211_ptr;
4038
4039 nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
4040 }
4041
55682965
JB
4042 return err;
4043}
4044
ea6b2098 4045static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
55682965 4046{
4c476991 4047 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 4048 struct vif_params params;
84efbb84 4049 struct wireless_dev *wdev;
896ff063 4050 struct sk_buff *msg;
55682965
JB
4051 int err;
4052 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
4053
2ec600d6
LCC
4054 memset(&params, 0, sizeof(params));
4055
55682965
JB
4056 if (!info->attrs[NL80211_ATTR_IFNAME])
4057 return -EINVAL;
4058
ab0d76f6 4059 if (info->attrs[NL80211_ATTR_IFTYPE])
55682965 4060 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
55682965 4061
33d915d9 4062 if (!rdev->ops->add_virtual_intf)
4c476991 4063 return -EOPNOTSUPP;
55682965 4064
cb3b7d87 4065 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
4066 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
4067 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
4068 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
4069 ETH_ALEN);
4070 if (!is_valid_ether_addr(params.macaddr))
4071 return -EADDRNOTAVAIL;
4072 }
4073
9bc383de 4074 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 4075 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 4076 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 4077 if (err)
4c476991 4078 return err;
9bc383de 4079 }
8b787643 4080
e6f40511 4081 if (!cfg80211_iftype_allowed(&rdev->wiphy, type, params.use_4addr, 0))
33d915d9
MP
4082 return -EOPNOTSUPP;
4083
1db77596
JB
4084 err = nl80211_parse_mon_options(rdev, type, info, &params);
4085 if (err < 0)
4086 return err;
e057d3c3 4087
a18c7192
JB
4088 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4089 if (!msg)
4090 return -ENOMEM;
4091
e35e4d28
HG
4092 wdev = rdev_add_virtual_intf(rdev,
4093 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
818a986e 4094 NET_NAME_USER, type, &params);
d687cbb7
RM
4095 if (WARN_ON(!wdev)) {
4096 nlmsg_free(msg);
4097 return -EPROTO;
4098 } else if (IS_ERR(wdev)) {
1c90f9d4 4099 nlmsg_free(msg);
84efbb84 4100 return PTR_ERR(wdev);
1c90f9d4 4101 }
2ec600d6 4102
18e5ca65 4103 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
4104 wdev->owner_nlportid = info->snd_portid;
4105
98104fde
JB
4106 switch (type) {
4107 case NL80211_IFTYPE_MESH_POINT:
4108 if (!info->attrs[NL80211_ATTR_MESH_ID])
4109 break;
29cbe68c
JB
4110 wdev_lock(wdev);
4111 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
4112 IEEE80211_MAX_MESH_ID_LEN);
4113 wdev->mesh_id_up_len =
4114 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4115 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
4116 wdev->mesh_id_up_len);
4117 wdev_unlock(wdev);
98104fde 4118 break;
cb3b7d87 4119 case NL80211_IFTYPE_NAN:
98104fde
JB
4120 case NL80211_IFTYPE_P2P_DEVICE:
4121 /*
cb3b7d87 4122 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
4123 * through the netdev notifier and must be added here
4124 */
9bdaf3b9
JB
4125 cfg80211_init_wdev(wdev);
4126 cfg80211_register_wdev(rdev, wdev);
98104fde
JB
4127 break;
4128 default:
4129 break;
29cbe68c
JB
4130 }
4131
15e47304 4132 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 4133 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
1c90f9d4
JB
4134 nlmsg_free(msg);
4135 return -ENOBUFS;
4136 }
4137
4138 return genlmsg_reply(msg, info);
55682965
JB
4139}
4140
ea6b2098
JB
4141static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
4142{
4143 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4144 int ret;
4145
4146 /* to avoid failing a new interface creation due to pending removal */
4147 cfg80211_destroy_ifaces(rdev);
4148
4149 wiphy_lock(&rdev->wiphy);
4150 ret = _nl80211_new_interface(skb, info);
4151 wiphy_unlock(&rdev->wiphy);
4152
4153 return ret;
4154}
4155
55682965
JB
4156static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
4157{
4c476991 4158 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 4159 struct wireless_dev *wdev = info->user_ptr[1];
55682965 4160
4c476991
JB
4161 if (!rdev->ops->del_virtual_intf)
4162 return -EOPNOTSUPP;
55682965 4163
a05829a7
JB
4164 /*
4165 * We hold RTNL, so this is safe, without RTNL opencount cannot
4166 * reach 0, and thus the rdev cannot be deleted.
4167 *
4168 * We need to do it for the dev_close(), since that will call
4169 * the netdev notifiers, and we need to acquire the mutex there
4170 * but don't know if we get there from here or from some other
4171 * place (e.g. "ip link set ... down").
4172 */
4173 mutex_unlock(&rdev->wiphy.mtx);
4174
84efbb84
JB
4175 /*
4176 * If we remove a wireless device without a netdev then clear
4177 * user_ptr[1] so that nl80211_post_doit won't dereference it
4178 * to check if it needs to do dev_put(). Otherwise it crashes
4179 * since the wdev has been freed, unlike with a netdev where
4180 * we need the dev_put() for the netdev to really be freed.
4181 */
4182 if (!wdev->netdev)
4183 info->user_ptr[1] = NULL;
a05829a7
JB
4184 else
4185 dev_close(wdev->netdev);
4186
4187 mutex_lock(&rdev->wiphy.mtx);
84efbb84 4188
7f8ed01e 4189 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
4190}
4191
1d9d9213
SW
4192static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
4193{
4194 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4195 struct net_device *dev = info->user_ptr[1];
4196 u16 noack_map;
4197
4198 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
4199 return -EINVAL;
4200
4201 if (!rdev->ops->set_noack_map)
4202 return -EOPNOTSUPP;
4203
4204 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
4205
e35e4d28 4206 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
4207}
4208
41ade00f
JB
4209struct get_key_cookie {
4210 struct sk_buff *msg;
4211 int error;
b9454e83 4212 int idx;
41ade00f
JB
4213};
4214
4215static void get_key_callback(void *c, struct key_params *params)
4216{
b9454e83 4217 struct nlattr *key;
41ade00f
JB
4218 struct get_key_cookie *cookie = c;
4219
9360ffd1
DM
4220 if ((params->key &&
4221 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
4222 params->key_len, params->key)) ||
4223 (params->seq &&
4224 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
4225 params->seq_len, params->seq)) ||
4226 (params->cipher &&
4227 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
4228 params->cipher)))
4229 goto nla_put_failure;
41ade00f 4230
ae0be8de 4231 key = nla_nest_start_noflag(cookie->msg, NL80211_ATTR_KEY);
b9454e83
JB
4232 if (!key)
4233 goto nla_put_failure;
4234
9360ffd1
DM
4235 if ((params->key &&
4236 nla_put(cookie->msg, NL80211_KEY_DATA,
4237 params->key_len, params->key)) ||
4238 (params->seq &&
4239 nla_put(cookie->msg, NL80211_KEY_SEQ,
4240 params->seq_len, params->seq)) ||
4241 (params->cipher &&
4242 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
4243 params->cipher)))
4244 goto nla_put_failure;
b9454e83 4245
efdfce72 4246 if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
9360ffd1 4247 goto nla_put_failure;
b9454e83
JB
4248
4249 nla_nest_end(cookie->msg, key);
4250
41ade00f
JB
4251 return;
4252 nla_put_failure:
4253 cookie->error = 1;
4254}
4255
4256static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
4257{
4c476991 4258 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 4259 int err;
4c476991 4260 struct net_device *dev = info->user_ptr[1];
41ade00f 4261 u8 key_idx = 0;
e31b8213
JB
4262 const u8 *mac_addr = NULL;
4263 bool pairwise;
41ade00f
JB
4264 struct get_key_cookie cookie = {
4265 .error = 0,
4266 };
4267 void *hdr;
4268 struct sk_buff *msg;
155d7c73
JB
4269 bool bigtk_support = false;
4270
4271 if (wiphy_ext_feature_isset(&rdev->wiphy,
4272 NL80211_EXT_FEATURE_BEACON_PROTECTION))
4273 bigtk_support = true;
4274
4275 if ((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION ||
4276 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
4277 wiphy_ext_feature_isset(&rdev->wiphy,
4278 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
4279 bigtk_support = true;
41ade00f 4280
56be393f 4281 if (info->attrs[NL80211_ATTR_KEY_IDX]) {
41ade00f 4282 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
155d7c73
JB
4283
4284 if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) {
4285 GENL_SET_ERR_MSG(info, "BIGTK not supported");
56be393f 4286 return -EINVAL;
155d7c73 4287 }
56be393f 4288 }
41ade00f 4289
41ade00f
JB
4290 if (info->attrs[NL80211_ATTR_MAC])
4291 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4292
e31b8213
JB
4293 pairwise = !!mac_addr;
4294 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
4295 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 4296
e31b8213
JB
4297 if (kt != NL80211_KEYTYPE_GROUP &&
4298 kt != NL80211_KEYTYPE_PAIRWISE)
4299 return -EINVAL;
4300 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
4301 }
4302
4c476991
JB
4303 if (!rdev->ops->get_key)
4304 return -EOPNOTSUPP;
41ade00f 4305
0fa7b391
JB
4306 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4307 return -ENOENT;
4308
fd2120ca 4309 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
4310 if (!msg)
4311 return -ENOMEM;
41ade00f 4312
15e47304 4313 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 4314 NL80211_CMD_NEW_KEY);
cb35fba3 4315 if (!hdr)
9fe271af 4316 goto nla_put_failure;
41ade00f
JB
4317
4318 cookie.msg = msg;
b9454e83 4319 cookie.idx = key_idx;
41ade00f 4320
9360ffd1
DM
4321 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4322 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
4323 goto nla_put_failure;
4324 if (mac_addr &&
4325 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
4326 goto nla_put_failure;
41ade00f 4327
e35e4d28
HG
4328 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
4329 get_key_callback);
41ade00f
JB
4330
4331 if (err)
6c95e2a2 4332 goto free_msg;
41ade00f
JB
4333
4334 if (cookie.error)
4335 goto nla_put_failure;
4336
4337 genlmsg_end(msg, hdr);
4c476991 4338 return genlmsg_reply(msg, info);
41ade00f
JB
4339
4340 nla_put_failure:
4341 err = -ENOBUFS;
6c95e2a2 4342 free_msg:
41ade00f 4343 nlmsg_free(msg);
41ade00f
JB
4344 return err;
4345}
4346
4347static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
4348{
4c476991 4349 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 4350 struct key_parse key;
41ade00f 4351 int err;
4c476991 4352 struct net_device *dev = info->user_ptr[1];
41ade00f 4353
b9454e83
JB
4354 err = nl80211_parse_key(info, &key);
4355 if (err)
4356 return err;
41ade00f 4357
b9454e83 4358 if (key.idx < 0)
41ade00f
JB
4359 return -EINVAL;
4360
6cdd3979
AW
4361 /* Only support setting default key and
4362 * Extended Key ID action NL80211_KEY_SET_TX.
4363 */
56be393f 4364 if (!key.def && !key.defmgmt && !key.defbeacon &&
6cdd3979 4365 !(key.p.mode == NL80211_KEY_SET_TX))
41ade00f
JB
4366 return -EINVAL;
4367
dbd2fd65 4368 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 4369
dbd2fd65
JB
4370 if (key.def) {
4371 if (!rdev->ops->set_default_key) {
4372 err = -EOPNOTSUPP;
4373 goto out;
4374 }
41ade00f 4375
dbd2fd65
JB
4376 err = nl80211_key_allowed(dev->ieee80211_ptr);
4377 if (err)
4378 goto out;
4379
e35e4d28 4380 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
4381 key.def_uni, key.def_multi);
4382
4383 if (err)
4384 goto out;
fffd0934 4385
3d23e349 4386#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
4387 dev->ieee80211_ptr->wext.default_key = key.idx;
4388#endif
6cdd3979 4389 } else if (key.defmgmt) {
dbd2fd65
JB
4390 if (key.def_uni || !key.def_multi) {
4391 err = -EINVAL;
4392 goto out;
4393 }
4394
4395 if (!rdev->ops->set_default_mgmt_key) {
4396 err = -EOPNOTSUPP;
4397 goto out;
4398 }
4399
4400 err = nl80211_key_allowed(dev->ieee80211_ptr);
4401 if (err)
4402 goto out;
4403
e35e4d28 4404 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
4405 if (err)
4406 goto out;
4407
4408#ifdef CONFIG_CFG80211_WEXT
4409 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 4410#endif
56be393f
JM
4411 } else if (key.defbeacon) {
4412 if (key.def_uni || !key.def_multi) {
4413 err = -EINVAL;
4414 goto out;
4415 }
4416
4417 if (!rdev->ops->set_default_beacon_key) {
4418 err = -EOPNOTSUPP;
4419 goto out;
4420 }
4421
4422 err = nl80211_key_allowed(dev->ieee80211_ptr);
4423 if (err)
4424 goto out;
4425
4426 err = rdev_set_default_beacon_key(rdev, dev, key.idx);
4427 if (err)
4428 goto out;
6cdd3979
AW
4429 } else if (key.p.mode == NL80211_KEY_SET_TX &&
4430 wiphy_ext_feature_isset(&rdev->wiphy,
4431 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
4432 u8 *mac_addr = NULL;
4433
4434 if (info->attrs[NL80211_ATTR_MAC])
4435 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4436
4437 if (!mac_addr || key.idx < 0 || key.idx > 1) {
4438 err = -EINVAL;
4439 goto out;
4440 }
dbd2fd65 4441
6cdd3979
AW
4442 err = rdev_add_key(rdev, dev, key.idx,
4443 NL80211_KEYTYPE_PAIRWISE,
4444 mac_addr, &key.p);
4445 } else {
4446 err = -EINVAL;
4447 }
dbd2fd65 4448 out:
fffd0934 4449 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4450
41ade00f
JB
4451 return err;
4452}
4453
4454static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
4455{
4c476991 4456 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 4457 int err;
4c476991 4458 struct net_device *dev = info->user_ptr[1];
b9454e83 4459 struct key_parse key;
e31b8213 4460 const u8 *mac_addr = NULL;
41ade00f 4461
b9454e83
JB
4462 err = nl80211_parse_key(info, &key);
4463 if (err)
4464 return err;
41ade00f 4465
f8af764b
JM
4466 if (!key.p.key) {
4467 GENL_SET_ERR_MSG(info, "no key");
41ade00f 4468 return -EINVAL;
f8af764b 4469 }
41ade00f 4470
41ade00f
JB
4471 if (info->attrs[NL80211_ATTR_MAC])
4472 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4473
e31b8213
JB
4474 if (key.type == -1) {
4475 if (mac_addr)
4476 key.type = NL80211_KEYTYPE_PAIRWISE;
4477 else
4478 key.type = NL80211_KEYTYPE_GROUP;
4479 }
4480
4481 /* for now */
4482 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
f8af764b
JM
4483 key.type != NL80211_KEYTYPE_GROUP) {
4484 GENL_SET_ERR_MSG(info, "key type not pairwise or group");
e31b8213 4485 return -EINVAL;
f8af764b 4486 }
e31b8213 4487
14f34e36
GG
4488 if (key.type == NL80211_KEYTYPE_GROUP &&
4489 info->attrs[NL80211_ATTR_VLAN_ID])
4490 key.p.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
4491
4c476991
JB
4492 if (!rdev->ops->add_key)
4493 return -EOPNOTSUPP;
25e47c18 4494
e31b8213
JB
4495 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
4496 key.type == NL80211_KEYTYPE_PAIRWISE,
f8af764b
JM
4497 mac_addr)) {
4498 GENL_SET_ERR_MSG(info, "key setting validation failed");
4c476991 4499 return -EINVAL;
f8af764b 4500 }
41ade00f 4501
fffd0934
JB
4502 wdev_lock(dev->ieee80211_ptr);
4503 err = nl80211_key_allowed(dev->ieee80211_ptr);
f8af764b
JM
4504 if (err)
4505 GENL_SET_ERR_MSG(info, "key not allowed");
4506 if (!err) {
e35e4d28
HG
4507 err = rdev_add_key(rdev, dev, key.idx,
4508 key.type == NL80211_KEYTYPE_PAIRWISE,
4509 mac_addr, &key.p);
f8af764b
JM
4510 if (err)
4511 GENL_SET_ERR_MSG(info, "key addition failed");
4512 }
fffd0934 4513 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4514
41ade00f
JB
4515 return err;
4516}
4517
4518static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
4519{
4c476991 4520 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 4521 int err;
4c476991 4522 struct net_device *dev = info->user_ptr[1];
41ade00f 4523 u8 *mac_addr = NULL;
b9454e83 4524 struct key_parse key;
41ade00f 4525
b9454e83
JB
4526 err = nl80211_parse_key(info, &key);
4527 if (err)
4528 return err;
41ade00f
JB
4529
4530 if (info->attrs[NL80211_ATTR_MAC])
4531 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4532
e31b8213
JB
4533 if (key.type == -1) {
4534 if (mac_addr)
4535 key.type = NL80211_KEYTYPE_PAIRWISE;
4536 else
4537 key.type = NL80211_KEYTYPE_GROUP;
4538 }
4539
4540 /* for now */
4541 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
4542 key.type != NL80211_KEYTYPE_GROUP)
4543 return -EINVAL;
4544
2d946308
AT
4545 if (!cfg80211_valid_key_idx(rdev, key.idx,
4546 key.type == NL80211_KEYTYPE_PAIRWISE))
4547 return -EINVAL;
4548
4c476991
JB
4549 if (!rdev->ops->del_key)
4550 return -EOPNOTSUPP;
41ade00f 4551
fffd0934
JB
4552 wdev_lock(dev->ieee80211_ptr);
4553 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 4554
0fa7b391 4555 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
4556 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4557 err = -ENOENT;
4558
fffd0934 4559 if (!err)
e35e4d28
HG
4560 err = rdev_del_key(rdev, dev, key.idx,
4561 key.type == NL80211_KEYTYPE_PAIRWISE,
4562 mac_addr);
41ade00f 4563
3d23e349 4564#ifdef CONFIG_CFG80211_WEXT
08645126 4565 if (!err) {
b9454e83 4566 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 4567 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 4568 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
4569 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
4570 }
4571#endif
fffd0934 4572 wdev_unlock(dev->ieee80211_ptr);
08645126 4573
41ade00f
JB
4574 return err;
4575}
4576
77765eaf
VT
4577/* This function returns an error or the number of nested attributes */
4578static int validate_acl_mac_addrs(struct nlattr *nl_attr)
4579{
4580 struct nlattr *attr;
4581 int n_entries = 0, tmp;
4582
4583 nla_for_each_nested(attr, nl_attr, tmp) {
4584 if (nla_len(attr) != ETH_ALEN)
4585 return -EINVAL;
4586
4587 n_entries++;
4588 }
4589
4590 return n_entries;
4591}
4592
4593/*
4594 * This function parses ACL information and allocates memory for ACL data.
4595 * On successful return, the calling function is responsible to free the
4596 * ACL buffer returned by this function.
4597 */
4598static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
4599 struct genl_info *info)
4600{
4601 enum nl80211_acl_policy acl_policy;
4602 struct nlattr *attr;
4603 struct cfg80211_acl_data *acl;
4604 int i = 0, n_entries, tmp;
4605
4606 if (!wiphy->max_acl_mac_addrs)
4607 return ERR_PTR(-EOPNOTSUPP);
4608
4609 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
4610 return ERR_PTR(-EINVAL);
4611
4612 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
4613 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
4614 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
4615 return ERR_PTR(-EINVAL);
4616
4617 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
4618 return ERR_PTR(-EINVAL);
4619
4620 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
4621 if (n_entries < 0)
4622 return ERR_PTR(n_entries);
4623
4624 if (n_entries > wiphy->max_acl_mac_addrs)
4625 return ERR_PTR(-ENOTSUPP);
4626
391d132c 4627 acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
77765eaf
VT
4628 if (!acl)
4629 return ERR_PTR(-ENOMEM);
4630
4631 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
4632 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
4633 i++;
4634 }
4635
4636 acl->n_acl_entries = n_entries;
4637 acl->acl_policy = acl_policy;
4638
4639 return acl;
4640}
4641
4642static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
4643{
4644 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4645 struct net_device *dev = info->user_ptr[1];
4646 struct cfg80211_acl_data *acl;
4647 int err;
4648
4649 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4650 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4651 return -EOPNOTSUPP;
4652
4653 if (!dev->ieee80211_ptr->beacon_interval)
4654 return -EINVAL;
4655
4656 acl = parse_acl_data(&rdev->wiphy, info);
4657 if (IS_ERR(acl))
4658 return PTR_ERR(acl);
4659
4660 err = rdev_set_mac_acl(rdev, dev, acl);
4661
4662 kfree(acl);
4663
4664 return err;
4665}
4666
a7c7fbff
PK
4667static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
4668 u8 *rates, u8 rates_len)
4669{
4670 u8 i;
4671 u32 mask = 0;
4672
4673 for (i = 0; i < rates_len; i++) {
4674 int rate = (rates[i] & 0x7f) * 5;
4675 int ridx;
4676
4677 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
4678 struct ieee80211_rate *srate =
4679 &sband->bitrates[ridx];
4680 if (rate == srate->bitrate) {
4681 mask |= 1 << ridx;
4682 break;
4683 }
4684 }
4685 if (ridx == sband->n_bitrates)
4686 return 0; /* rate not found */
4687 }
4688
4689 return mask;
4690}
4691
4692static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
4693 u8 *rates, u8 rates_len,
4694 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
4695{
4696 u8 i;
4697
4698 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
4699
4700 for (i = 0; i < rates_len; i++) {
4701 int ridx, rbit;
4702
4703 ridx = rates[i] / 8;
4704 rbit = BIT(rates[i] % 8);
4705
4706 /* check validity */
4707 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
4708 return false;
4709
4710 /* check availability */
30fe6d50 4711 ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
a7c7fbff
PK
4712 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
4713 mcs[ridx] |= rbit;
4714 else
4715 return false;
4716 }
4717
4718 return true;
4719}
4720
4721static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
4722{
4723 u16 mcs_mask = 0;
4724
4725 switch (vht_mcs_map) {
4726 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
4727 break;
4728 case IEEE80211_VHT_MCS_SUPPORT_0_7:
4729 mcs_mask = 0x00FF;
4730 break;
4731 case IEEE80211_VHT_MCS_SUPPORT_0_8:
4732 mcs_mask = 0x01FF;
4733 break;
4734 case IEEE80211_VHT_MCS_SUPPORT_0_9:
4735 mcs_mask = 0x03FF;
4736 break;
4737 default:
4738 break;
4739 }
4740
4741 return mcs_mask;
4742}
4743
4744static void vht_build_mcs_mask(u16 vht_mcs_map,
4745 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
4746{
4747 u8 nss;
4748
4749 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
4750 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
4751 vht_mcs_map >>= 2;
4752 }
4753}
4754
4755static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
4756 struct nl80211_txrate_vht *txrate,
4757 u16 mcs[NL80211_VHT_NSS_MAX])
4758{
4759 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4760 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
4761 u8 i;
4762
4763 if (!sband->vht_cap.vht_supported)
4764 return false;
4765
4766 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
4767
4768 /* Build vht_mcs_mask from VHT capabilities */
4769 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4770
4771 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
4772 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4773 mcs[i] = txrate->mcs[i];
4774 else
4775 return false;
4776 }
4777
4778 return true;
4779}
4780
eb89a6a6
MH
4781static u16 he_mcs_map_to_mcs_mask(u8 he_mcs_map)
4782{
4783 switch (he_mcs_map) {
4784 case IEEE80211_HE_MCS_NOT_SUPPORTED:
4785 return 0;
4786 case IEEE80211_HE_MCS_SUPPORT_0_7:
4787 return 0x00FF;
4788 case IEEE80211_HE_MCS_SUPPORT_0_9:
4789 return 0x03FF;
4790 case IEEE80211_HE_MCS_SUPPORT_0_11:
4791 return 0xFFF;
4792 default:
4793 break;
4794 }
4795 return 0;
4796}
4797
4798static void he_build_mcs_mask(u16 he_mcs_map,
4799 u16 he_mcs_mask[NL80211_HE_NSS_MAX])
4800{
4801 u8 nss;
4802
4803 for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
4804 he_mcs_mask[nss] = he_mcs_map_to_mcs_mask(he_mcs_map & 0x03);
4805 he_mcs_map >>= 2;
4806 }
4807}
4808
4809static u16 he_get_txmcsmap(struct genl_info *info,
4810 const struct ieee80211_sta_he_cap *he_cap)
4811{
4812 struct net_device *dev = info->user_ptr[1];
4813 struct wireless_dev *wdev = dev->ieee80211_ptr;
4814 __le16 tx_mcs;
4815
4816 switch (wdev->chandef.width) {
4817 case NL80211_CHAN_WIDTH_80P80:
4818 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80p80;
4819 break;
4820 case NL80211_CHAN_WIDTH_160:
4821 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_160;
4822 break;
4823 default:
4824 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80;
4825 break;
4826 }
4827 return le16_to_cpu(tx_mcs);
4828}
4829
4830static bool he_set_mcs_mask(struct genl_info *info,
4831 struct wireless_dev *wdev,
4832 struct ieee80211_supported_band *sband,
4833 struct nl80211_txrate_he *txrate,
4834 u16 mcs[NL80211_HE_NSS_MAX])
4835{
4836 const struct ieee80211_sta_he_cap *he_cap;
4837 u16 tx_mcs_mask[NL80211_HE_NSS_MAX] = {};
4838 u16 tx_mcs_map = 0;
4839 u8 i;
4840
4841 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
4842 if (!he_cap)
4843 return false;
4844
4845 memset(mcs, 0, sizeof(u16) * NL80211_HE_NSS_MAX);
4846
4847 tx_mcs_map = he_get_txmcsmap(info, he_cap);
4848
4849 /* Build he_mcs_mask from HE capabilities */
4850 he_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4851
4852 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
4853 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4854 mcs[i] = txrate->mcs[i];
4855 else
4856 return false;
4857 }
4858
4859 return true;
4860}
4861
a7c7fbff 4862static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
9a5f6488
TC
4863 struct nlattr *attrs[],
4864 enum nl80211_attrs attr,
eb89a6a6 4865 struct cfg80211_bitrate_mask *mask,
857b34c4
RM
4866 struct net_device *dev,
4867 bool default_all_enabled)
a7c7fbff
PK
4868{
4869 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4870 struct cfg80211_registered_device *rdev = info->user_ptr[0];
eb89a6a6 4871 struct wireless_dev *wdev = dev->ieee80211_ptr;
a7c7fbff
PK
4872 int rem, i;
4873 struct nlattr *tx_rates;
4874 struct ieee80211_supported_band *sband;
eb89a6a6 4875 u16 vht_tx_mcs_map, he_tx_mcs_map;
a7c7fbff
PK
4876
4877 memset(mask, 0, sizeof(*mask));
4878 /* Default to all rates enabled */
4879 for (i = 0; i < NUM_NL80211_BANDS; i++) {
eb89a6a6
MH
4880 const struct ieee80211_sta_he_cap *he_cap;
4881
857b34c4
RM
4882 if (!default_all_enabled)
4883 break;
4884
a7c7fbff
PK
4885 sband = rdev->wiphy.bands[i];
4886
4887 if (!sband)
4888 continue;
4889
4890 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
4891 memcpy(mask->control[i].ht_mcs,
4892 sband->ht_cap.mcs.rx_mask,
4893 sizeof(mask->control[i].ht_mcs));
4894
9df66d5b
PKS
4895 if (sband->vht_cap.vht_supported) {
4896 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4897 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
4898 }
eb89a6a6
MH
4899
4900 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
4901 if (!he_cap)
4902 continue;
4903
4904 he_tx_mcs_map = he_get_txmcsmap(info, he_cap);
4905 he_build_mcs_mask(he_tx_mcs_map, mask->control[i].he_mcs);
4906
4907 mask->control[i].he_gi = 0xFF;
4908 mask->control[i].he_ltf = 0xFF;
a7c7fbff
PK
4909 }
4910
4911 /* if no rates are given set it back to the defaults */
9a5f6488 4912 if (!attrs[attr])
a7c7fbff
PK
4913 goto out;
4914
4915 /* The nested attribute uses enum nl80211_band as the index. This maps
4916 * directly to the enum nl80211_band values used in cfg80211.
4917 */
4918 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
9a5f6488 4919 nla_for_each_nested(tx_rates, attrs[attr], rem) {
a7c7fbff
PK
4920 enum nl80211_band band = nla_type(tx_rates);
4921 int err;
4922
4923 if (band < 0 || band >= NUM_NL80211_BANDS)
4924 return -EINVAL;
4925 sband = rdev->wiphy.bands[band];
4926 if (sband == NULL)
4927 return -EINVAL;
8cb08174
JB
4928 err = nla_parse_nested_deprecated(tb, NL80211_TXRATE_MAX,
4929 tx_rates,
4930 nl80211_txattr_policy,
4931 info->extack);
a7c7fbff
PK
4932 if (err)
4933 return err;
4934 if (tb[NL80211_TXRATE_LEGACY]) {
4935 mask->control[band].legacy = rateset_to_mask(
4936 sband,
4937 nla_data(tb[NL80211_TXRATE_LEGACY]),
4938 nla_len(tb[NL80211_TXRATE_LEGACY]));
4939 if ((mask->control[band].legacy == 0) &&
4940 nla_len(tb[NL80211_TXRATE_LEGACY]))
4941 return -EINVAL;
4942 }
4943 if (tb[NL80211_TXRATE_HT]) {
4944 if (!ht_rateset_to_mask(
4945 sband,
4946 nla_data(tb[NL80211_TXRATE_HT]),
4947 nla_len(tb[NL80211_TXRATE_HT]),
4948 mask->control[band].ht_mcs))
4949 return -EINVAL;
4950 }
c4a30446 4951
a7c7fbff
PK
4952 if (tb[NL80211_TXRATE_VHT]) {
4953 if (!vht_set_mcs_mask(
4954 sband,
4955 nla_data(tb[NL80211_TXRATE_VHT]),
4956 mask->control[band].vht_mcs))
4957 return -EINVAL;
4958 }
c4a30446 4959
a7c7fbff
PK
4960 if (tb[NL80211_TXRATE_GI]) {
4961 mask->control[band].gi =
4962 nla_get_u8(tb[NL80211_TXRATE_GI]);
4963 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
4964 return -EINVAL;
4965 }
eb89a6a6
MH
4966 if (tb[NL80211_TXRATE_HE] &&
4967 !he_set_mcs_mask(info, wdev, sband,
4968 nla_data(tb[NL80211_TXRATE_HE]),
4969 mask->control[band].he_mcs))
4970 return -EINVAL;
c4a30446 4971
eb89a6a6
MH
4972 if (tb[NL80211_TXRATE_HE_GI])
4973 mask->control[band].he_gi =
4974 nla_get_u8(tb[NL80211_TXRATE_HE_GI]);
4975 if (tb[NL80211_TXRATE_HE_LTF])
4976 mask->control[band].he_ltf =
4977 nla_get_u8(tb[NL80211_TXRATE_HE_LTF]);
a7c7fbff
PK
4978
4979 if (mask->control[band].legacy == 0) {
eb89a6a6 4980 /* don't allow empty legacy rates if HT, VHT or HE
a7c7fbff
PK
4981 * are not even supported.
4982 */
4983 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
eb89a6a6
MH
4984 rdev->wiphy.bands[band]->vht_cap.vht_supported ||
4985 ieee80211_get_he_iftype_cap(sband, wdev->iftype)))
a7c7fbff
PK
4986 return -EINVAL;
4987
4988 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
4989 if (mask->control[band].ht_mcs[i])
4990 goto out;
4991
4992 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
4993 if (mask->control[band].vht_mcs[i])
4994 goto out;
4995
eb89a6a6
MH
4996 for (i = 0; i < NL80211_HE_NSS_MAX; i++)
4997 if (mask->control[band].he_mcs[i])
4998 goto out;
4999
a7c7fbff
PK
5000 /* legacy and mcs rates may not be both empty */
5001 return -EINVAL;
5002 }
5003 }
5004
5005out:
5006 return 0;
5007}
5008
8564e382
JB
5009static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
5010 enum nl80211_band band,
5011 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 5012{
c4a30446 5013 u32 count_ht, count_vht, count_he, i;
8564e382 5014 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
5015
5016 /* Allow only one rate */
5017 if (hweight32(rate) > 1)
5018 return -EINVAL;
5019
5020 count_ht = 0;
5021 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 5022 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 5023 return -EINVAL;
8564e382 5024 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
5025 count_ht++;
5026 if (count_ht > 1)
5027 return -EINVAL;
5028 }
5029 if (count_ht && rate)
5030 return -EINVAL;
5031 }
5032
5033 count_vht = 0;
5034 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 5035 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 5036 return -EINVAL;
8564e382 5037 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
5038 count_vht++;
5039 if (count_vht > 1)
5040 return -EINVAL;
5041 }
5042 if (count_vht && rate)
5043 return -EINVAL;
5044 }
5045
c4a30446
RM
5046 count_he = 0;
5047 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
5048 if (hweight16(beacon_rate->control[band].he_mcs[i]) > 1) {
5049 return -EINVAL;
5050 } else if (beacon_rate->control[band].he_mcs[i]) {
5051 count_he++;
5052 if (count_he > 1)
5053 return -EINVAL;
5054 }
5055 if (count_he && rate)
5056 return -EINVAL;
5057 }
5058
5059 if ((count_ht && count_vht && count_he) ||
5060 (!rate && !count_ht && !count_vht && !count_he))
a7c7fbff
PK
5061 return -EINVAL;
5062
8564e382
JB
5063 if (rate &&
5064 !wiphy_ext_feature_isset(&rdev->wiphy,
5065 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
5066 return -EINVAL;
5067 if (count_ht &&
5068 !wiphy_ext_feature_isset(&rdev->wiphy,
5069 NL80211_EXT_FEATURE_BEACON_RATE_HT))
5070 return -EINVAL;
5071 if (count_vht &&
5072 !wiphy_ext_feature_isset(&rdev->wiphy,
5073 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
5074 return -EINVAL;
c4a30446
RM
5075 if (count_he &&
5076 !wiphy_ext_feature_isset(&rdev->wiphy,
5077 NL80211_EXT_FEATURE_BEACON_RATE_HE))
5078 return -EINVAL;
8564e382 5079
a7c7fbff
PK
5080 return 0;
5081}
5082
dc1e3cb8
JC
5083static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
5084 struct net_device *dev,
5085 struct nlattr *attrs,
5086 struct cfg80211_mbssid_config *config,
5087 u8 num_elems)
5088{
5089 struct nlattr *tb[NL80211_MBSSID_CONFIG_ATTR_MAX + 1];
5090
5091 if (!wiphy->mbssid_max_interfaces)
5092 return -EOPNOTSUPP;
5093
5094 if (nla_parse_nested(tb, NL80211_MBSSID_CONFIG_ATTR_MAX, attrs, NULL,
5095 NULL) ||
5096 !tb[NL80211_MBSSID_CONFIG_ATTR_INDEX])
5097 return -EINVAL;
5098
5099 config->ema = nla_get_flag(tb[NL80211_MBSSID_CONFIG_ATTR_EMA]);
5100 if (config->ema) {
5101 if (!wiphy->ema_max_profile_periodicity)
5102 return -EOPNOTSUPP;
5103
5104 if (num_elems > wiphy->ema_max_profile_periodicity)
5105 return -EINVAL;
5106 }
5107
5108 config->index = nla_get_u8(tb[NL80211_MBSSID_CONFIG_ATTR_INDEX]);
5109 if (config->index >= wiphy->mbssid_max_interfaces ||
5110 (!config->index && !num_elems))
5111 return -EINVAL;
5112
5113 if (tb[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX]) {
5114 u32 tx_ifindex =
5115 nla_get_u32(tb[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX]);
5116
5117 if ((!config->index && tx_ifindex != dev->ifindex) ||
5118 (config->index && tx_ifindex == dev->ifindex))
5119 return -EINVAL;
5120
5121 if (tx_ifindex != dev->ifindex) {
5122 struct net_device *tx_netdev =
5123 dev_get_by_index(wiphy_net(wiphy), tx_ifindex);
5124
5125 if (!tx_netdev || !tx_netdev->ieee80211_ptr ||
5126 tx_netdev->ieee80211_ptr->wiphy != wiphy ||
5127 tx_netdev->ieee80211_ptr->iftype !=
5128 NL80211_IFTYPE_AP) {
5129 dev_put(tx_netdev);
5130 return -EINVAL;
5131 }
5132
5133 config->tx_wdev = tx_netdev->ieee80211_ptr;
5134 } else {
5135 config->tx_wdev = dev->ieee80211_ptr;
5136 }
5137 } else if (!config->index) {
5138 config->tx_wdev = dev->ieee80211_ptr;
5139 } else {
5140 return -EINVAL;
5141 }
5142
5143 return 0;
5144}
5145
5146static struct cfg80211_mbssid_elems *
5147nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
5148{
5149 struct nlattr *nl_elems;
5150 struct cfg80211_mbssid_elems *elems;
5151 int rem_elems;
5152 u8 i = 0, num_elems = 0;
5153
5154 if (!wiphy->mbssid_max_interfaces)
5155 return ERR_PTR(-EINVAL);
5156
5157 nla_for_each_nested(nl_elems, attrs, rem_elems)
5158 num_elems++;
5159
5160 elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL);
5161 if (!elems)
5162 return ERR_PTR(-ENOMEM);
5163
5164 nla_for_each_nested(nl_elems, attrs, rem_elems) {
5165 elems->elem[i].data = nla_data(nl_elems);
5166 elems->elem[i].len = nla_len(nl_elems);
5167 i++;
5168 }
5169 elems->cnt = num_elems;
5170 return elems;
5171}
5172
81e54d08
PKC
5173static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
5174 struct nlattr *attrs[],
8860020e 5175 struct cfg80211_beacon_data *bcn)
ed1b6cc7 5176{
8860020e 5177 bool haveinfo = false;
81e54d08 5178 int err;
ed1b6cc7 5179
8860020e 5180 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 5181
a1193be8
SW
5182 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
5183 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
5184 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
5185 if (!bcn->head_len)
5186 return -EINVAL;
5187 haveinfo = true;
ed1b6cc7
JB
5188 }
5189
a1193be8
SW
5190 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
5191 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
5192 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 5193 haveinfo = true;
ed1b6cc7
JB
5194 }
5195
4c476991
JB
5196 if (!haveinfo)
5197 return -EINVAL;
3b85875a 5198
a1193be8
SW
5199 if (attrs[NL80211_ATTR_IE]) {
5200 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
5201 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
5202 }
5203
a1193be8 5204 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 5205 bcn->proberesp_ies =
a1193be8 5206 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 5207 bcn->proberesp_ies_len =
a1193be8 5208 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
5209 }
5210
a1193be8 5211 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 5212 bcn->assocresp_ies =
a1193be8 5213 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 5214 bcn->assocresp_ies_len =
a1193be8 5215 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
5216 }
5217
a1193be8
SW
5218 if (attrs[NL80211_ATTR_PROBE_RESP]) {
5219 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
5220 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
5221 }
5222
81e54d08
PKC
5223 if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
5224 struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
5225
8cb08174
JB
5226 err = nla_parse_nested_deprecated(tb,
5227 NL80211_FTM_RESP_ATTR_MAX,
5228 attrs[NL80211_ATTR_FTM_RESPONDER],
5229 NULL, NULL);
81e54d08
PKC
5230 if (err)
5231 return err;
5232
5233 if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
5234 wiphy_ext_feature_isset(&rdev->wiphy,
5235 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
5236 bcn->ftm_responder = 1;
5237 else
5238 return -EOPNOTSUPP;
5239
5240 if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
5241 bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
5242 bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
5243 }
5244
5245 if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
5246 bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5247 bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5248 }
5249 } else {
5250 bcn->ftm_responder = -1;
5251 }
5252
dc1e3cb8
JC
5253 if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
5254 struct cfg80211_mbssid_elems *mbssid =
5255 nl80211_parse_mbssid_elems(&rdev->wiphy,
5256 attrs[NL80211_ATTR_MBSSID_ELEMS]);
5257
5258 if (IS_ERR(mbssid))
5259 return PTR_ERR(mbssid);
5260
5261 bcn->mbssid_ies = mbssid;
5262 }
5263
8860020e
JB
5264 return 0;
5265}
5266
796e90f4
JC
5267static int nl80211_parse_he_obss_pd(struct nlattr *attrs,
5268 struct ieee80211_he_obss_pd *he_obss_pd)
5269{
5270 struct nlattr *tb[NL80211_HE_OBSS_PD_ATTR_MAX + 1];
5271 int err;
5272
5273 err = nla_parse_nested(tb, NL80211_HE_OBSS_PD_ATTR_MAX, attrs,
5274 he_obss_pd_policy, NULL);
5275 if (err)
5276 return err;
5277
f5bec330
RM
5278 if (!tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL])
5279 return -EINVAL;
5280
5281 he_obss_pd->sr_ctrl = nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL]);
5282
6c8b6e4a
RM
5283 if (tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET])
5284 he_obss_pd->min_offset =
5285 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
5286 if (tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
5287 he_obss_pd->max_offset =
5288 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
f5bec330
RM
5289 if (tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET])
5290 he_obss_pd->non_srg_max_offset =
5291 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET]);
6c8b6e4a
RM
5292
5293 if (he_obss_pd->min_offset > he_obss_pd->max_offset)
796e90f4
JC
5294 return -EINVAL;
5295
f5bec330
RM
5296 if (tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP])
5297 memcpy(he_obss_pd->bss_color_bitmap,
5298 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP]),
5299 sizeof(he_obss_pd->bss_color_bitmap));
5300
5301 if (tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP])
5302 memcpy(he_obss_pd->partial_bssid_bitmap,
5303 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP]),
5304 sizeof(he_obss_pd->partial_bssid_bitmap));
5305
796e90f4
JC
5306 he_obss_pd->enable = true;
5307
5308 return 0;
5309}
5310
5c5e52d1
JC
5311static int nl80211_parse_he_bss_color(struct nlattr *attrs,
5312 struct cfg80211_he_bss_color *he_bss_color)
5313{
5314 struct nlattr *tb[NL80211_HE_BSS_COLOR_ATTR_MAX + 1];
5315 int err;
5316
5317 err = nla_parse_nested(tb, NL80211_HE_BSS_COLOR_ATTR_MAX, attrs,
5318 he_bss_color_policy, NULL);
5319 if (err)
5320 return err;
5321
5322 if (!tb[NL80211_HE_BSS_COLOR_ATTR_COLOR])
5323 return -EINVAL;
5324
5325 he_bss_color->color =
5326 nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
75e6b594
JB
5327 he_bss_color->enabled =
5328 !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
5c5e52d1
JC
5329 he_bss_color->partial =
5330 nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
5331
5332 return 0;
5333}
5334
291c49de
AD
5335static int nl80211_parse_fils_discovery(struct cfg80211_registered_device *rdev,
5336 struct nlattr *attrs,
5337 struct cfg80211_ap_settings *params)
5338{
5339 struct nlattr *tb[NL80211_FILS_DISCOVERY_ATTR_MAX + 1];
5340 int ret;
5341 struct cfg80211_fils_discovery *fd = &params->fils_discovery;
5342
5343 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5344 NL80211_EXT_FEATURE_FILS_DISCOVERY))
5345 return -EINVAL;
5346
5347 ret = nla_parse_nested(tb, NL80211_FILS_DISCOVERY_ATTR_MAX, attrs,
5348 NULL, NULL);
5349 if (ret)
5350 return ret;
5351
5352 if (!tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN] ||
5353 !tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX] ||
5354 !tb[NL80211_FILS_DISCOVERY_ATTR_TMPL])
5355 return -EINVAL;
5356
5357 fd->tmpl_len = nla_len(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5358 fd->tmpl = nla_data(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5359 fd->min_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN]);
5360 fd->max_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX]);
5361
5362 return 0;
5363}
5364
7443dcd1
AD
5365static int
5366nl80211_parse_unsol_bcast_probe_resp(struct cfg80211_registered_device *rdev,
5367 struct nlattr *attrs,
5368 struct cfg80211_ap_settings *params)
5369{
5370 struct nlattr *tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1];
5371 int ret;
5372 struct cfg80211_unsol_bcast_probe_resp *presp =
5373 &params->unsol_bcast_probe_resp;
5374
5375 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5376 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
5377 return -EINVAL;
5378
5379 ret = nla_parse_nested(tb, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX,
5380 attrs, NULL, NULL);
5381 if (ret)
5382 return ret;
5383
5384 if (!tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] ||
5385 !tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL])
5386 return -EINVAL;
5387
5388 presp->tmpl = nla_data(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5389 presp->tmpl_len = nla_len(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5390 presp->interval = nla_get_u32(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT]);
5391 return 0;
5392}
5393
66cd794e 5394static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
153e2a11 5395 const struct element *rates)
66cd794e
JB
5396{
5397 int i;
5398
5399 if (!rates)
5400 return;
5401
153e2a11
JB
5402 for (i = 0; i < rates->datalen; i++) {
5403 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
66cd794e 5404 params->ht_required = true;
153e2a11 5405 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
66cd794e 5406 params->vht_required = true;
153e2a11 5407 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_HE_PHY)
2a392596 5408 params->he_required = true;
153e2a11 5409 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_SAE_H2E)
d6587602 5410 params->sae_h2e_required = true;
66cd794e
JB
5411 }
5412}
5413
5414/*
5415 * Since the nl80211 API didn't include, from the beginning, attributes about
5416 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
5417 * benefit of drivers that rebuild IEs in the firmware.
5418 */
5419static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
5420{
5421 const struct cfg80211_beacon_data *bcn = &params->beacon;
ba83bfb1
IM
5422 size_t ies_len = bcn->tail_len;
5423 const u8 *ies = bcn->tail;
153e2a11
JB
5424 const struct element *rates;
5425 const struct element *cap;
66cd794e 5426
153e2a11 5427 rates = cfg80211_find_elem(WLAN_EID_SUPP_RATES, ies, ies_len);
66cd794e
JB
5428 nl80211_check_ap_rate_selectors(params, rates);
5429
153e2a11 5430 rates = cfg80211_find_elem(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
66cd794e
JB
5431 nl80211_check_ap_rate_selectors(params, rates);
5432
153e2a11
JB
5433 cap = cfg80211_find_elem(WLAN_EID_HT_CAPABILITY, ies, ies_len);
5434 if (cap && cap->datalen >= sizeof(*params->ht_cap))
5435 params->ht_cap = (void *)cap->data;
5436 cap = cfg80211_find_elem(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
5437 if (cap && cap->datalen >= sizeof(*params->vht_cap))
5438 params->vht_cap = (void *)cap->data;
5439 cap = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
5440 if (cap && cap->datalen >= sizeof(*params->he_cap) + 1)
5441 params->he_cap = (void *)(cap->data + 1);
5442 cap = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
5443 if (cap && cap->datalen >= sizeof(*params->he_oper) + 1)
5444 params->he_oper = (void *)(cap->data + 1);
66cd794e
JB
5445}
5446
46c1dd0c
FF
5447static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
5448 struct cfg80211_ap_settings *params)
5449{
5450 struct wireless_dev *wdev;
5451 bool ret = false;
5452
53873f13 5453 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
5454 if (wdev->iftype != NL80211_IFTYPE_AP &&
5455 wdev->iftype != NL80211_IFTYPE_P2P_GO)
5456 continue;
5457
683b6d3b 5458 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
5459 continue;
5460
683b6d3b 5461 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
5462 ret = true;
5463 break;
5464 }
5465
46c1dd0c
FF
5466 return ret;
5467}
5468
e39e5b5e
JM
5469static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
5470 enum nl80211_auth_type auth_type,
5471 enum nl80211_commands cmd)
5472{
5473 if (auth_type > NL80211_AUTHTYPE_MAX)
5474 return false;
5475
5476 switch (cmd) {
5477 case NL80211_CMD_AUTHENTICATE:
5478 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
5479 auth_type == NL80211_AUTHTYPE_SAE)
5480 return false;
63181060
JM
5481 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5482 NL80211_EXT_FEATURE_FILS_STA) &&
5483 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
5484 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5485 auth_type == NL80211_AUTHTYPE_FILS_PK))
5486 return false;
e39e5b5e
JM
5487 return true;
5488 case NL80211_CMD_CONNECT:
10773a7c 5489 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
26f7044e
CHH
5490 !wiphy_ext_feature_isset(&rdev->wiphy,
5491 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
10773a7c 5492 auth_type == NL80211_AUTHTYPE_SAE)
a3caf744 5493 return false;
10773a7c 5494
a3caf744
VK
5495 /* FILS with SK PFS or PK not supported yet */
5496 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5497 auth_type == NL80211_AUTHTYPE_FILS_PK)
5498 return false;
5499 if (!wiphy_ext_feature_isset(
5500 &rdev->wiphy,
5501 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
5502 auth_type == NL80211_AUTHTYPE_FILS_SK)
5503 return false;
5504 return true;
e39e5b5e 5505 case NL80211_CMD_START_AP:
2831a631
CHH
5506 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5507 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP) &&
5508 auth_type == NL80211_AUTHTYPE_SAE)
e39e5b5e 5509 return false;
63181060
JM
5510 /* FILS not supported yet */
5511 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
5512 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5513 auth_type == NL80211_AUTHTYPE_FILS_PK)
5514 return false;
e39e5b5e
JM
5515 return true;
5516 default:
5517 return false;
5518 }
5519}
5520
8860020e
JB
5521static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
5522{
5523 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5524 struct net_device *dev = info->user_ptr[1];
5525 struct wireless_dev *wdev = dev->ieee80211_ptr;
9e263e19 5526 struct cfg80211_ap_settings *params;
8860020e
JB
5527 int err;
5528
5529 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5530 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5531 return -EOPNOTSUPP;
5532
5533 if (!rdev->ops->start_ap)
5534 return -EOPNOTSUPP;
5535
5536 if (wdev->beacon_interval)
5537 return -EALREADY;
5538
8860020e
JB
5539 /* these are required for START_AP */
5540 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
5541 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
5542 !info->attrs[NL80211_ATTR_BEACON_HEAD])
5543 return -EINVAL;
5544
9e263e19
JB
5545 params = kzalloc(sizeof(*params), GFP_KERNEL);
5546 if (!params)
5547 return -ENOMEM;
5548
5549 err = nl80211_parse_beacon(rdev, info->attrs, &params->beacon);
8860020e 5550 if (err)
9e263e19 5551 goto out;
8860020e 5552
9e263e19 5553 params->beacon_interval =
8860020e 5554 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
9e263e19 5555 params->dtim_period =
8860020e
JB
5556 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
5557
0c317a02 5558 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
9e263e19 5559 params->beacon_interval);
8860020e 5560 if (err)
9e263e19 5561 goto out;
8860020e
JB
5562
5563 /*
5564 * In theory, some of these attributes should be required here
5565 * but since they were not used when the command was originally
5566 * added, keep them optional for old user space programs to let
5567 * them continue to work with drivers that do not need the
5568 * additional information -- drivers must check!
5569 */
5570 if (info->attrs[NL80211_ATTR_SSID]) {
9e263e19
JB
5571 params->ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
5572 params->ssid_len =
8860020e 5573 nla_len(info->attrs[NL80211_ATTR_SSID]);
9e263e19
JB
5574 if (params->ssid_len == 0) {
5575 err = -EINVAL;
5576 goto out;
5577 }
8860020e
JB
5578 }
5579
ab0d76f6 5580 if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
9e263e19 5581 params->hidden_ssid = nla_get_u32(
8860020e 5582 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
8860020e 5583
9e263e19 5584 params->privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
8860020e
JB
5585
5586 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
9e263e19 5587 params->auth_type = nla_get_u32(
8860020e 5588 info->attrs[NL80211_ATTR_AUTH_TYPE]);
9e263e19
JB
5589 if (!nl80211_valid_auth_type(rdev, params->auth_type,
5590 NL80211_CMD_START_AP)) {
5591 err = -EINVAL;
5592 goto out;
5593 }
8860020e 5594 } else
9e263e19 5595 params->auth_type = NL80211_AUTHTYPE_AUTOMATIC;
8860020e 5596
9e263e19 5597 err = nl80211_crypto_settings(rdev, info, &params->crypto,
8860020e
JB
5598 NL80211_MAX_NR_CIPHER_SUITES);
5599 if (err)
9e263e19 5600 goto out;
8860020e 5601
1b658f11 5602 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
9e263e19
JB
5603 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER)) {
5604 err = -EOPNOTSUPP;
5605 goto out;
5606 }
5607 params->inactivity_timeout = nla_get_u16(
1b658f11
VT
5608 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
5609 }
5610
53cabad7 5611 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
9e263e19
JB
5612 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
5613 err = -EINVAL;
5614 goto out;
5615 }
5616 params->p2p_ctwindow =
53cabad7 5617 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
9e263e19
JB
5618 if (params->p2p_ctwindow != 0 &&
5619 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) {
5620 err = -EINVAL;
5621 goto out;
5622 }
53cabad7
JB
5623 }
5624
5625 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5626 u8 tmp;
5627
9e263e19
JB
5628 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
5629 err = -EINVAL;
5630 goto out;
5631 }
53cabad7 5632 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
9e263e19
JB
5633 params->p2p_opp_ps = tmp;
5634 if (params->p2p_opp_ps != 0 &&
5635 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) {
5636 err = -EINVAL;
5637 goto out;
5638 }
53cabad7
JB
5639 }
5640
aa430da4 5641 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
9e263e19 5642 err = nl80211_parse_chandef(rdev, info, &params->chandef);
683b6d3b 5643 if (err)
9e263e19 5644 goto out;
683b6d3b 5645 } else if (wdev->preset_chandef.chan) {
9e263e19
JB
5646 params->chandef = wdev->preset_chandef;
5647 } else if (!nl80211_get_ap_channel(rdev, params)) {
5648 err = -EINVAL;
5649 goto out;
5650 }
aa430da4 5651
9e263e19
JB
5652 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params->chandef,
5653 wdev->iftype)) {
5654 err = -EINVAL;
5655 goto out;
5656 }
aa430da4 5657
a7c7fbff 5658 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9a5f6488
TC
5659 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
5660 NL80211_ATTR_TX_RATES,
9e263e19 5661 &params->beacon_rate,
857b34c4 5662 dev, false);
a7c7fbff 5663 if (err)
9e263e19 5664 goto out;
a7c7fbff 5665
9e263e19
JB
5666 err = validate_beacon_tx_rate(rdev, params->chandef.chan->band,
5667 &params->beacon_rate);
a7c7fbff 5668 if (err)
9e263e19 5669 goto out;
a7c7fbff
PK
5670 }
5671
18998c38 5672 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
9e263e19 5673 params->smps_mode =
18998c38 5674 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
9e263e19 5675 switch (params->smps_mode) {
18998c38
EP
5676 case NL80211_SMPS_OFF:
5677 break;
5678 case NL80211_SMPS_STATIC:
5679 if (!(rdev->wiphy.features &
9e263e19
JB
5680 NL80211_FEATURE_STATIC_SMPS)) {
5681 err = -EINVAL;
5682 goto out;
5683 }
18998c38
EP
5684 break;
5685 case NL80211_SMPS_DYNAMIC:
5686 if (!(rdev->wiphy.features &
9e263e19
JB
5687 NL80211_FEATURE_DYNAMIC_SMPS)) {
5688 err = -EINVAL;
5689 goto out;
5690 }
18998c38
EP
5691 break;
5692 default:
9e263e19
JB
5693 err = -EINVAL;
5694 goto out;
18998c38
EP
5695 }
5696 } else {
9e263e19 5697 params->smps_mode = NL80211_SMPS_OFF;
18998c38
EP
5698 }
5699
9e263e19
JB
5700 params->pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
5701 if (params->pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
5702 err = -EOPNOTSUPP;
5703 goto out;
5704 }
6e8ef842 5705
4baf6bea 5706 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
9e263e19
JB
5707 params->acl = parse_acl_data(&rdev->wiphy, info);
5708 if (IS_ERR(params->acl)) {
5709 err = PTR_ERR(params->acl);
05075fe7 5710 params->acl = NULL;
9e263e19
JB
5711 goto out;
5712 }
4baf6bea
OO
5713 }
5714
9e263e19 5715 params->twt_responder =
a0de1ca3
JC
5716 nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
5717
796e90f4
JC
5718 if (info->attrs[NL80211_ATTR_HE_OBSS_PD]) {
5719 err = nl80211_parse_he_obss_pd(
5720 info->attrs[NL80211_ATTR_HE_OBSS_PD],
9e263e19 5721 &params->he_obss_pd);
bc7a39b4
LC
5722 if (err)
5723 goto out;
796e90f4
JC
5724 }
5725
5c5e52d1
JC
5726 if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
5727 err = nl80211_parse_he_bss_color(
5728 info->attrs[NL80211_ATTR_HE_BSS_COLOR],
9e263e19 5729 &params->he_bss_color);
5c5e52d1 5730 if (err)
60a0121f 5731 goto out;
5c5e52d1
JC
5732 }
5733
291c49de
AD
5734 if (info->attrs[NL80211_ATTR_FILS_DISCOVERY]) {
5735 err = nl80211_parse_fils_discovery(rdev,
5736 info->attrs[NL80211_ATTR_FILS_DISCOVERY],
9e263e19 5737 params);
291c49de
AD
5738 if (err)
5739 goto out;
5740 }
5741
7443dcd1
AD
5742 if (info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP]) {
5743 err = nl80211_parse_unsol_bcast_probe_resp(
5744 rdev, info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP],
9e263e19 5745 params);
7443dcd1 5746 if (err)
abaf94ec 5747 goto out;
7443dcd1
AD
5748 }
5749
dc1e3cb8
JC
5750 if (info->attrs[NL80211_ATTR_MBSSID_CONFIG]) {
5751 err = nl80211_parse_mbssid_config(&rdev->wiphy, dev,
5752 info->attrs[NL80211_ATTR_MBSSID_CONFIG],
5753 &params->mbssid_config,
5754 params->beacon.mbssid_ies ?
5755 params->beacon.mbssid_ies->cnt :
5756 0);
5757 if (err)
5758 goto out;
5759 }
5760
9e263e19 5761 nl80211_calculate_ap_params(params);
66cd794e 5762
47301a74
VJ
5763 if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS])
5764 params->flags = nla_get_u32(
5765 info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]);
5766 else if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
5767 params->flags |= NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
fe494370 5768
c56589ed 5769 wdev_lock(wdev);
9e263e19 5770 err = rdev_start_ap(rdev, dev, params);
46c1dd0c 5771 if (!err) {
9e263e19
JB
5772 wdev->preset_chandef = params->chandef;
5773 wdev->beacon_interval = params->beacon_interval;
5774 wdev->chandef = params->chandef;
5775 wdev->ssid_len = params->ssid_len;
5776 memcpy(wdev->ssid, params->ssid, wdev->ssid_len);
466a3061
DK
5777
5778 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
5779 wdev->conn_owner_nlportid = info->snd_portid;
46c1dd0c 5780 }
c56589ed 5781 wdev_unlock(wdev);
77765eaf 5782
9951ebfc 5783out:
9e263e19 5784 kfree(params->acl);
dc1e3cb8
JC
5785 kfree(params->beacon.mbssid_ies);
5786 if (params->mbssid_config.tx_wdev &&
5787 params->mbssid_config.tx_wdev->netdev &&
5788 params->mbssid_config.tx_wdev->netdev != dev)
5789 dev_put(params->mbssid_config.tx_wdev->netdev);
9e263e19 5790 kfree(params);
77765eaf 5791
56d1893d 5792 return err;
ed1b6cc7
JB
5793}
5794
8860020e
JB
5795static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
5796{
5797 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5798 struct net_device *dev = info->user_ptr[1];
5799 struct wireless_dev *wdev = dev->ieee80211_ptr;
5800 struct cfg80211_beacon_data params;
5801 int err;
5802
5803 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5804 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5805 return -EOPNOTSUPP;
5806
5807 if (!rdev->ops->change_beacon)
5808 return -EOPNOTSUPP;
5809
5810 if (!wdev->beacon_interval)
5811 return -EINVAL;
5812
81e54d08 5813 err = nl80211_parse_beacon(rdev, info->attrs, &params);
8860020e 5814 if (err)
dc1e3cb8 5815 goto out;
8860020e 5816
c56589ed
SW
5817 wdev_lock(wdev);
5818 err = rdev_change_beacon(rdev, dev, &params);
5819 wdev_unlock(wdev);
5820
dc1e3cb8
JC
5821out:
5822 kfree(params.mbssid_ies);
c56589ed 5823 return err;
8860020e
JB
5824}
5825
5826static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 5827{
4c476991
JB
5828 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5829 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 5830
7c8d5e03 5831 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
5832}
5833
5727ef1b
JB
5834static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
5835 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
5836 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
5837 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 5838 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 5839 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 5840 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
5841};
5842
eccb8e8f 5843static int parse_station_flags(struct genl_info *info,
bdd3ae3d 5844 enum nl80211_iftype iftype,
eccb8e8f 5845 struct station_parameters *params)
5727ef1b
JB
5846{
5847 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 5848 struct nlattr *nla;
5727ef1b
JB
5849 int flag;
5850
eccb8e8f
JB
5851 /*
5852 * Try parsing the new attribute first so userspace
5853 * can specify both for older kernels.
5854 */
5855 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
5856 if (nla) {
5857 struct nl80211_sta_flag_update *sta_flags;
5858
5859 sta_flags = nla_data(nla);
5860 params->sta_flags_mask = sta_flags->mask;
5861 params->sta_flags_set = sta_flags->set;
77ee7c89 5862 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
5863 if ((params->sta_flags_mask |
5864 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
5865 return -EINVAL;
5866 return 0;
5867 }
5868
5869 /* if present, parse the old attribute */
5727ef1b 5870
eccb8e8f 5871 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
5872 if (!nla)
5873 return 0;
5874
8cb08174 5875 if (nla_parse_nested_deprecated(flags, NL80211_STA_FLAG_MAX, nla, sta_flags_policy, info->extack))
5727ef1b
JB
5876 return -EINVAL;
5877
bdd3ae3d
JB
5878 /*
5879 * Only allow certain flags for interface types so that
5880 * other attributes are silently ignored. Remember that
5881 * this is backward compatibility code with old userspace
5882 * and shouldn't be hit in other cases anyway.
5883 */
5884 switch (iftype) {
5885 case NL80211_IFTYPE_AP:
5886 case NL80211_IFTYPE_AP_VLAN:
5887 case NL80211_IFTYPE_P2P_GO:
5888 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5889 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
5890 BIT(NL80211_STA_FLAG_WME) |
5891 BIT(NL80211_STA_FLAG_MFP);
5892 break;
5893 case NL80211_IFTYPE_P2P_CLIENT:
5894 case NL80211_IFTYPE_STATION:
5895 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5896 BIT(NL80211_STA_FLAG_TDLS_PEER);
5897 break;
5898 case NL80211_IFTYPE_MESH_POINT:
5899 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5900 BIT(NL80211_STA_FLAG_MFP) |
5901 BIT(NL80211_STA_FLAG_AUTHORIZED);
5cf3006c 5902 break;
bdd3ae3d
JB
5903 default:
5904 return -EINVAL;
5905 }
5727ef1b 5906
3383b5a6
JB
5907 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
5908 if (flags[flag]) {
eccb8e8f 5909 params->sta_flags_set |= (1<<flag);
5727ef1b 5910
3383b5a6
JB
5911 /* no longer support new API additions in old API */
5912 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
5913 return -EINVAL;
5914 }
5915 }
5916
5727ef1b
JB
5917 return 0;
5918}
5919
9bb7e0f2 5920bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
c8dcfd8a
FF
5921{
5922 struct nlattr *rate;
8eb41c8d
VK
5923 u32 bitrate;
5924 u16 bitrate_compat;
bbf67e45 5925 enum nl80211_rate_info rate_flg;
c8dcfd8a 5926
ae0be8de 5927 rate = nla_nest_start_noflag(msg, attr);
c8dcfd8a 5928 if (!rate)
db9c64cf 5929 return false;
c8dcfd8a
FF
5930
5931 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
5932 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
5933 /* report 16-bit bitrate only if we can */
5934 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
5935 if (bitrate > 0 &&
5936 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
5937 return false;
5938 if (bitrate_compat > 0 &&
5939 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
5940 return false;
5941
b51f3bee
JB
5942 switch (info->bw) {
5943 case RATE_INFO_BW_5:
5944 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
5945 break;
5946 case RATE_INFO_BW_10:
5947 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
5948 break;
5949 default:
5950 WARN_ON(1);
7b506ff6 5951 fallthrough;
b51f3bee
JB
5952 case RATE_INFO_BW_20:
5953 rate_flg = 0;
5954 break;
5955 case RATE_INFO_BW_40:
5956 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
5957 break;
5958 case RATE_INFO_BW_80:
5959 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
5960 break;
5961 case RATE_INFO_BW_160:
5962 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
5963 break;
c4cbaf79
LC
5964 case RATE_INFO_BW_HE_RU:
5965 rate_flg = 0;
5966 WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
cfb14110
VJ
5967 break;
5968 case RATE_INFO_BW_320:
5969 rate_flg = NL80211_RATE_INFO_320_MHZ_WIDTH;
5970 break;
5971 case RATE_INFO_BW_EHT_RU:
5972 rate_flg = 0;
5973 WARN_ON(!(info->flags & RATE_INFO_FLAGS_EHT_MCS));
5974 break;
b51f3bee
JB
5975 }
5976
5977 if (rate_flg && nla_put_flag(msg, rate_flg))
5978 return false;
5979
db9c64cf
JB
5980 if (info->flags & RATE_INFO_FLAGS_MCS) {
5981 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
5982 return false;
db9c64cf
JB
5983 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5984 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5985 return false;
5986 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
5987 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
5988 return false;
5989 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
5990 return false;
db9c64cf
JB
5991 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5992 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5993 return false;
c4cbaf79
LC
5994 } else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
5995 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
5996 return false;
5997 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
5998 return false;
5999 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
6000 return false;
6001 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
6002 return false;
6003 if (info->bw == RATE_INFO_BW_HE_RU &&
6004 nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
6005 info->he_ru_alloc))
6006 return false;
cfb14110
VJ
6007 } else if (info->flags & RATE_INFO_FLAGS_EHT_MCS) {
6008 if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_MCS, info->mcs))
6009 return false;
6010 if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_NSS, info->nss))
6011 return false;
6012 if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_GI, info->eht_gi))
6013 return false;
6014 if (info->bw == RATE_INFO_BW_EHT_RU &&
6015 nla_put_u8(msg, NL80211_RATE_INFO_EHT_RU_ALLOC,
6016 info->eht_ru_alloc))
6017 return false;
db9c64cf 6018 }
c8dcfd8a
FF
6019
6020 nla_nest_end(msg, rate);
6021 return true;
c8dcfd8a
FF
6022}
6023
119363c7
FF
6024static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
6025 int id)
6026{
6027 void *attr;
6028 int i = 0;
6029
6030 if (!mask)
6031 return true;
6032
ae0be8de 6033 attr = nla_nest_start_noflag(msg, id);
119363c7
FF
6034 if (!attr)
6035 return false;
6036
6037 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
6038 if (!(mask & BIT(i)))
6039 continue;
6040
6041 if (nla_put_u8(msg, i, signal[i]))
6042 return false;
6043 }
6044
6045 nla_nest_end(msg, attr);
6046
6047 return true;
6048}
6049
cf5ead82
JB
6050static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
6051 u32 seq, int flags,
66266b3a
JL
6052 struct cfg80211_registered_device *rdev,
6053 struct net_device *dev,
98b62183 6054 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
6055{
6056 void *hdr;
f4263c98 6057 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 6058
cf5ead82 6059 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
f77bf486
AS
6060 if (!hdr) {
6061 cfg80211_sinfo_release_content(sinfo);
fd5b74dc 6062 return -1;
f77bf486 6063 }
fd5b74dc 6064
9360ffd1
DM
6065 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6066 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
6067 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
6068 goto nla_put_failure;
f5ea9120 6069
ae0be8de 6070 sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
2ec600d6 6071 if (!sinfoattr)
fd5b74dc 6072 goto nla_put_failure;
319090bf
JB
6073
6074#define PUT_SINFO(attr, memb, type) do { \
d686b920 6075 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
397c657a 6076 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
319090bf
JB
6077 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
6078 sinfo->memb)) \
6079 goto nla_put_failure; \
6080 } while (0)
d686b920 6081#define PUT_SINFO_U64(attr, memb) do { \
397c657a 6082 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
d686b920
JB
6083 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
6084 sinfo->memb, NL80211_STA_INFO_PAD)) \
6085 goto nla_put_failure; \
6086 } while (0)
319090bf
JB
6087
6088 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
6089 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
6c7a0033 6090 PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at);
319090bf 6091
397c657a
OE
6092 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
6093 BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 6094 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 6095 (u32)sinfo->rx_bytes))
9360ffd1 6096 goto nla_put_failure;
319090bf 6097
397c657a
OE
6098 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
6099 BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 6100 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
6101 (u32)sinfo->tx_bytes))
6102 goto nla_put_failure;
319090bf 6103
d686b920
JB
6104 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
6105 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
6106 PUT_SINFO(LLID, llid, u16);
6107 PUT_SINFO(PLID, plid, u16);
6108 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 6109 PUT_SINFO_U64(RX_DURATION, rx_duration);
36647055
THJ
6110 PUT_SINFO_U64(TX_DURATION, tx_duration);
6111
6112 if (wiphy_ext_feature_isset(&rdev->wiphy,
6113 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6114 PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
319090bf 6115
66266b3a
JL
6116 switch (rdev->wiphy.signal_type) {
6117 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
6118 PUT_SINFO(SIGNAL, signal, u8);
6119 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
6120 break;
6121 default:
6122 break;
6123 }
397c657a 6124 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
6125 if (!nl80211_put_signal(msg, sinfo->chains,
6126 sinfo->chain_signal,
6127 NL80211_STA_INFO_CHAIN_SIGNAL))
6128 goto nla_put_failure;
6129 }
397c657a 6130 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
6131 if (!nl80211_put_signal(msg, sinfo->chains,
6132 sinfo->chain_signal_avg,
6133 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
6134 goto nla_put_failure;
6135 }
397c657a 6136 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
6137 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
6138 NL80211_STA_INFO_TX_BITRATE))
6139 goto nla_put_failure;
6140 }
397c657a 6141 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
6142 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
6143 NL80211_STA_INFO_RX_BITRATE))
420e7fab 6144 goto nla_put_failure;
420e7fab 6145 }
319090bf
JB
6146
6147 PUT_SINFO(RX_PACKETS, rx_packets, u32);
6148 PUT_SINFO(TX_PACKETS, tx_packets, u32);
6149 PUT_SINFO(TX_RETRIES, tx_retries, u32);
6150 PUT_SINFO(TX_FAILED, tx_failed, u32);
6151 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
ab60633c 6152 PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
319090bf
JB
6153 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
6154 PUT_SINFO(LOCAL_PM, local_pm, u32);
6155 PUT_SINFO(PEER_PM, peer_pm, u32);
6156 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
dbdaee7a 6157 PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
1303a51c 6158 PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8);
319090bf 6159
397c657a 6160 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
ae0be8de
MK
6161 bss_param = nla_nest_start_noflag(msg,
6162 NL80211_STA_INFO_BSS_PARAM);
f4263c98
PS
6163 if (!bss_param)
6164 goto nla_put_failure;
6165
9360ffd1
DM
6166 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
6167 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
6168 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
6169 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
6170 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
6171 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
6172 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
6173 sinfo->bss_param.dtim_period) ||
6174 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
6175 sinfo->bss_param.beacon_interval))
6176 goto nla_put_failure;
f4263c98
PS
6177
6178 nla_nest_end(msg, bss_param);
6179 }
397c657a 6180 if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
6181 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
6182 sizeof(struct nl80211_sta_flag_update),
6183 &sinfo->sta_flags))
6184 goto nla_put_failure;
319090bf 6185
d686b920
JB
6186 PUT_SINFO_U64(T_OFFSET, t_offset);
6187 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
6188 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 6189 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
0d4e14a3
AB
6190 PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
6191 PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
81d5439d 6192 if (wiphy_ext_feature_isset(&rdev->wiphy,
9c06602b
BP
6193 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
6194 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
6195 PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
6196 }
319090bf
JB
6197
6198#undef PUT_SINFO
d686b920 6199#undef PUT_SINFO_U64
6de39808 6200
8689c051 6201 if (sinfo->pertid) {
6de39808
JB
6202 struct nlattr *tidsattr;
6203 int tid;
6204
ae0be8de
MK
6205 tidsattr = nla_nest_start_noflag(msg,
6206 NL80211_STA_INFO_TID_STATS);
6de39808
JB
6207 if (!tidsattr)
6208 goto nla_put_failure;
6209
6210 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
6211 struct cfg80211_tid_stats *tidstats;
6212 struct nlattr *tidattr;
6213
6214 tidstats = &sinfo->pertid[tid];
6215
6216 if (!tidstats->filled)
6217 continue;
6218
ae0be8de 6219 tidattr = nla_nest_start_noflag(msg, tid + 1);
6de39808
JB
6220 if (!tidattr)
6221 goto nla_put_failure;
6222
d686b920 6223#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 6224 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
6225 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
6226 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
6227 goto nla_put_failure; \
6228 } while (0)
6229
d686b920
JB
6230 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
6231 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
6232 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
6233 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 6234
d686b920 6235#undef PUT_TIDVAL_U64
52539ca8
THJ
6236 if ((tidstats->filled &
6237 BIT(NL80211_TID_STATS_TXQ_STATS)) &&
6238 !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
6239 NL80211_TID_STATS_TXQ_STATS))
6240 goto nla_put_failure;
6241
6de39808
JB
6242 nla_nest_end(msg, tidattr);
6243 }
6244
6245 nla_nest_end(msg, tidsattr);
6246 }
6247
2ec600d6 6248 nla_nest_end(msg, sinfoattr);
fd5b74dc 6249
319090bf 6250 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
6251 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
6252 sinfo->assoc_req_ies))
6253 goto nla_put_failure;
50d3dfb7 6254
7ea3e110 6255 cfg80211_sinfo_release_content(sinfo);
053c095a
JB
6256 genlmsg_end(msg, hdr);
6257 return 0;
fd5b74dc
JB
6258
6259 nla_put_failure:
7ea3e110 6260 cfg80211_sinfo_release_content(sinfo);
bc3ed28c
TG
6261 genlmsg_cancel(msg, hdr);
6262 return -EMSGSIZE;
fd5b74dc
JB
6263}
6264
2ec600d6 6265static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 6266 struct netlink_callback *cb)
2ec600d6 6267{
73887fd9 6268 struct station_info sinfo;
1b8ec87a 6269 struct cfg80211_registered_device *rdev;
97990a06 6270 struct wireless_dev *wdev;
2ec600d6 6271 u8 mac_addr[ETH_ALEN];
97990a06 6272 int sta_idx = cb->args[2];
2ec600d6 6273 int err;
2ec600d6 6274
ce6b6974 6275 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
67748893 6276 if (err)
a05829a7
JB
6277 return err;
6278 /* nl80211_prepare_wdev_dump acquired it in the successful case */
6279 __acquire(&rdev->wiphy.mtx);
bba95fef 6280
97990a06
JB
6281 if (!wdev->netdev) {
6282 err = -EINVAL;
6283 goto out_err;
6284 }
6285
1b8ec87a 6286 if (!rdev->ops->dump_station) {
eec60b03 6287 err = -EOPNOTSUPP;
bba95fef
JB
6288 goto out_err;
6289 }
6290
bba95fef 6291 while (1) {
73887fd9 6292 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 6293 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
73887fd9 6294 mac_addr, &sinfo);
bba95fef
JB
6295 if (err == -ENOENT)
6296 break;
6297 if (err)
3b85875a 6298 goto out_err;
bba95fef 6299
cf5ead82 6300 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 6301 NETLINK_CB(cb->skb).portid,
bba95fef 6302 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 6303 rdev, wdev->netdev, mac_addr,
73887fd9 6304 &sinfo) < 0)
bba95fef
JB
6305 goto out;
6306
6307 sta_idx++;
6308 }
6309
bba95fef 6310 out:
97990a06 6311 cb->args[2] = sta_idx;
bba95fef 6312 err = skb->len;
bba95fef 6313 out_err:
a05829a7 6314 wiphy_unlock(&rdev->wiphy);
bba95fef
JB
6315
6316 return err;
2ec600d6 6317}
fd5b74dc 6318
5727ef1b
JB
6319static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
6320{
4c476991
JB
6321 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6322 struct net_device *dev = info->user_ptr[1];
73887fd9 6323 struct station_info sinfo;
fd5b74dc
JB
6324 struct sk_buff *msg;
6325 u8 *mac_addr = NULL;
4c476991 6326 int err;
fd5b74dc 6327
73887fd9 6328 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc 6329
73887fd9
JB
6330 if (!info->attrs[NL80211_ATTR_MAC])
6331 return -EINVAL;
fd5b74dc
JB
6332
6333 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6334
73887fd9
JB
6335 if (!rdev->ops->get_station)
6336 return -EOPNOTSUPP;
3b85875a 6337
73887fd9 6338 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 6339 if (err)
73887fd9 6340 return err;
2ec600d6 6341
fd2120ca 6342 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7ea3e110 6343 if (!msg) {
ba8f566a 6344 cfg80211_sinfo_release_content(&sinfo);
73887fd9 6345 return -ENOMEM;
7ea3e110 6346 }
fd5b74dc 6347
cf5ead82
JB
6348 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
6349 info->snd_portid, info->snd_seq, 0,
73887fd9 6350 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991 6351 nlmsg_free(msg);
73887fd9 6352 return -ENOBUFS;
4c476991 6353 }
3b85875a 6354
73887fd9 6355 return genlmsg_reply(msg, info);
5727ef1b
JB
6356}
6357
77ee7c89
JB
6358int cfg80211_check_station_change(struct wiphy *wiphy,
6359 struct station_parameters *params,
6360 enum cfg80211_station_type statype)
6361{
e4208427
AB
6362 if (params->listen_interval != -1 &&
6363 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 6364 return -EINVAL;
e4208427 6365
17b94247
AB
6366 if (params->support_p2p_ps != -1 &&
6367 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
6368 return -EINVAL;
6369
c72e1140 6370 if (params->aid &&
e4208427
AB
6371 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
6372 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
6373 return -EINVAL;
6374
6375 /* When you run into this, adjust the code below for the new flag */
6376 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
6377
6378 switch (statype) {
eef941e6
TP
6379 case CFG80211_STA_MESH_PEER_KERNEL:
6380 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
6381 /*
6382 * No ignoring the TDLS flag here -- the userspace mesh
6383 * code doesn't have the bug of including TDLS in the
6384 * mask everywhere.
6385 */
6386 if (params->sta_flags_mask &
6387 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6388 BIT(NL80211_STA_FLAG_MFP) |
6389 BIT(NL80211_STA_FLAG_AUTHORIZED)))
6390 return -EINVAL;
6391 break;
6392 case CFG80211_STA_TDLS_PEER_SETUP:
6393 case CFG80211_STA_TDLS_PEER_ACTIVE:
6394 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
6395 return -EINVAL;
6396 /* ignore since it can't change */
6397 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
6398 break;
6399 default:
6400 /* disallow mesh-specific things */
6401 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
6402 return -EINVAL;
6403 if (params->local_pm)
6404 return -EINVAL;
6405 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
6406 return -EINVAL;
6407 }
6408
6409 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
6410 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
6411 /* TDLS can't be set, ... */
6412 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
6413 return -EINVAL;
6414 /*
6415 * ... but don't bother the driver with it. This works around
6416 * a hostapd/wpa_supplicant issue -- it always includes the
6417 * TLDS_PEER flag in the mask even for AP mode.
6418 */
6419 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
6420 }
6421
47edb11b
AB
6422 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
6423 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
6424 /* reject other things that can't change */
6425 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
6426 return -EINVAL;
6427 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
6428 return -EINVAL;
6429 if (params->supported_rates)
6430 return -EINVAL;
c4cbaf79 6431 if (params->ext_capab || params->ht_capa || params->vht_capa ||
ea05fd35 6432 params->he_capa || params->eht_capa)
77ee7c89
JB
6433 return -EINVAL;
6434 }
6435
47edb11b
AB
6436 if (statype != CFG80211_STA_AP_CLIENT &&
6437 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
6438 if (params->vlan)
6439 return -EINVAL;
6440 }
6441
6442 switch (statype) {
6443 case CFG80211_STA_AP_MLME_CLIENT:
6444 /* Use this only for authorizing/unauthorizing a station */
6445 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
6446 return -EOPNOTSUPP;
6447 break;
6448 case CFG80211_STA_AP_CLIENT:
47edb11b 6449 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
6450 /* accept only the listed bits */
6451 if (params->sta_flags_mask &
6452 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
6453 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6454 BIT(NL80211_STA_FLAG_ASSOCIATED) |
6455 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
6456 BIT(NL80211_STA_FLAG_WME) |
6457 BIT(NL80211_STA_FLAG_MFP)))
6458 return -EINVAL;
6459
6460 /* but authenticated/associated only if driver handles it */
6461 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
6462 params->sta_flags_mask &
6463 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6464 BIT(NL80211_STA_FLAG_ASSOCIATED)))
6465 return -EINVAL;
6466 break;
6467 case CFG80211_STA_IBSS:
6468 case CFG80211_STA_AP_STA:
6469 /* reject any changes other than AUTHORIZED */
6470 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
6471 return -EINVAL;
6472 break;
6473 case CFG80211_STA_TDLS_PEER_SETUP:
6474 /* reject any changes other than AUTHORIZED or WME */
6475 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
6476 BIT(NL80211_STA_FLAG_WME)))
6477 return -EINVAL;
6478 /* force (at least) rates when authorizing */
6479 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
6480 !params->supported_rates)
6481 return -EINVAL;
6482 break;
6483 case CFG80211_STA_TDLS_PEER_ACTIVE:
6484 /* reject any changes */
6485 return -EINVAL;
eef941e6 6486 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
6487 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
6488 return -EINVAL;
6489 break;
eef941e6 6490 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
6491 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
6492 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
6493 return -EINVAL;
6494 break;
6495 }
6496
06f7c88c
BL
6497 /*
6498 * Older kernel versions ignored this attribute entirely, so don't
6499 * reject attempts to update it but mark it as unused instead so the
6500 * driver won't look at the data.
6501 */
6502 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
6503 statype != CFG80211_STA_TDLS_PEER_SETUP)
6504 params->opmode_notif_used = false;
6505
77ee7c89
JB
6506 return 0;
6507}
6508EXPORT_SYMBOL(cfg80211_check_station_change);
6509
5727ef1b 6510/*
c258d2de 6511 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 6512 */
80b99899
JB
6513static struct net_device *get_vlan(struct genl_info *info,
6514 struct cfg80211_registered_device *rdev)
5727ef1b 6515{
463d0183 6516 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
6517 struct net_device *v;
6518 int ret;
6519
6520 if (!vlanattr)
6521 return NULL;
6522
6523 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
6524 if (!v)
6525 return ERR_PTR(-ENODEV);
6526
6527 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
6528 ret = -EINVAL;
6529 goto error;
5727ef1b 6530 }
80b99899 6531
77ee7c89
JB
6532 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
6533 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
6534 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
6535 ret = -EINVAL;
6536 goto error;
6537 }
6538
80b99899
JB
6539 if (!netif_running(v)) {
6540 ret = -ENETDOWN;
6541 goto error;
6542 }
6543
6544 return v;
6545 error:
6546 dev_put(v);
6547 return ERR_PTR(ret);
5727ef1b
JB
6548}
6549
94e860f1
JB
6550static const struct nla_policy
6551nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
6552 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
6553 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
6554};
6555
ff276691
JB
6556static int nl80211_parse_sta_wme(struct genl_info *info,
6557 struct station_parameters *params)
df881293 6558{
df881293
JM
6559 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
6560 struct nlattr *nla;
6561 int err;
6562
df881293
JM
6563 /* parse WME attributes if present */
6564 if (!info->attrs[NL80211_ATTR_STA_WME])
6565 return 0;
6566
6567 nla = info->attrs[NL80211_ATTR_STA_WME];
8cb08174
JB
6568 err = nla_parse_nested_deprecated(tb, NL80211_STA_WME_MAX, nla,
6569 nl80211_sta_wme_policy,
6570 info->extack);
df881293
JM
6571 if (err)
6572 return err;
6573
6574 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
6575 params->uapsd_queues = nla_get_u8(
6576 tb[NL80211_STA_WME_UAPSD_QUEUES]);
6577 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
6578 return -EINVAL;
6579
6580 if (tb[NL80211_STA_WME_MAX_SP])
6581 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
6582
6583 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
6584 return -EINVAL;
6585
6586 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
6587
6588 return 0;
6589}
6590
c01fc9ad
SD
6591static int nl80211_parse_sta_channel_info(struct genl_info *info,
6592 struct station_parameters *params)
6593{
6594 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
6595 params->supported_channels =
6596 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
6597 params->supported_channels_len =
6598 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
6599 /*
6600 * Need to include at least one (first channel, number of
cb9abd48
JB
6601 * channels) tuple for each subband (checked in policy),
6602 * and must have proper tuples for the rest of the data as well.
c01fc9ad 6603 */
c01fc9ad
SD
6604 if (params->supported_channels_len % 2)
6605 return -EINVAL;
6606 }
6607
6608 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
6609 params->supported_oper_classes =
6610 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
6611 params->supported_oper_classes_len =
6612 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
c01fc9ad
SD
6613 }
6614 return 0;
6615}
6616
ff276691
JB
6617static int nl80211_set_station_tdls(struct genl_info *info,
6618 struct station_parameters *params)
6619{
c01fc9ad 6620 int err;
ff276691 6621 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
6622 if (info->attrs[NL80211_ATTR_PEER_AID])
6623 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
6624 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
6625 params->ht_capa =
6626 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
6627 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
6628 params->vht_capa =
6629 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
c4cbaf79
LC
6630 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
6631 params->he_capa =
6632 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6633 params->he_capa_len =
6634 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
ea05fd35
IP
6635
6636 if (info->attrs[NL80211_ATTR_EHT_CAPABILITY]) {
6637 params->eht_capa =
6638 nla_data(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
6639 params->eht_capa_len =
6640 nla_len(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
6641
6642 if (!ieee80211_eht_capa_size_ok((const u8 *)params->he_capa,
6643 (const u8 *)params->eht_capa,
6644 params->eht_capa_len))
6645 return -EINVAL;
6646 }
c4cbaf79 6647 }
ff276691 6648
c01fc9ad
SD
6649 err = nl80211_parse_sta_channel_info(info, params);
6650 if (err)
6651 return err;
6652
ff276691
JB
6653 return nl80211_parse_sta_wme(info, params);
6654}
6655
e96d1cd2
ARN
6656static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
6657 struct station_parameters *params)
6658{
6659 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6660 int idx;
6661
6662 if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
6663 if (!rdev->ops->set_tx_power ||
6664 !wiphy_ext_feature_isset(&rdev->wiphy,
6665 NL80211_EXT_FEATURE_STA_TX_PWR))
6666 return -EOPNOTSUPP;
6667
6668 idx = NL80211_ATTR_STA_TX_POWER_SETTING;
6669 params->txpwr.type = nla_get_u8(info->attrs[idx]);
6670
6671 if (params->txpwr.type == NL80211_TX_POWER_LIMITED) {
6672 idx = NL80211_ATTR_STA_TX_POWER;
6673
6674 if (info->attrs[idx])
6675 params->txpwr.power =
6676 nla_get_s16(info->attrs[idx]);
6677 else
6678 return -EINVAL;
6679 }
6680 params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER;
6681 }
6682
6683 return 0;
6684}
6685
5727ef1b
JB
6686static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
6687{
4c476991 6688 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 6689 struct net_device *dev = info->user_ptr[1];
5727ef1b 6690 struct station_parameters params;
77ee7c89
JB
6691 u8 *mac_addr;
6692 int err;
5727ef1b
JB
6693
6694 memset(&params, 0, sizeof(params));
6695
77ee7c89
JB
6696 if (!rdev->ops->change_station)
6697 return -EOPNOTSUPP;
6698
e4208427
AB
6699 /*
6700 * AID and listen_interval properties can be set only for unassociated
6701 * station. Include these parameters here and will check them in
6702 * cfg80211_check_station_change().
6703 */
a9bc31e4
AB
6704 if (info->attrs[NL80211_ATTR_STA_AID])
6705 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427 6706
14f34e36
GG
6707 if (info->attrs[NL80211_ATTR_VLAN_ID])
6708 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
6709
e4208427
AB
6710 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
6711 params.listen_interval =
6712 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
6713 else
6714 params.listen_interval = -1;
5727ef1b 6715
ab0d76f6
JB
6716 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
6717 params.support_p2p_ps =
6718 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
6719 else
17b94247 6720 params.support_p2p_ps = -1;
17b94247 6721
5727ef1b
JB
6722 if (!info->attrs[NL80211_ATTR_MAC])
6723 return -EINVAL;
6724
6725 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6726
6727 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
6728 params.supported_rates =
6729 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6730 params.supported_rates_len =
6731 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6732 }
6733
9d62a986
JM
6734 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
6735 params.capability =
6736 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
6737 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
6738 }
6739
6740 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
6741 params.ext_capab =
6742 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6743 params.ext_capab_len =
6744 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6745 }
6746
bdd3ae3d 6747 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
6748 return -EINVAL;
6749
ab0d76f6 6750 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2ec600d6 6751 params.plink_action =
f8bacc21 6752 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2ec600d6 6753
f8bacc21 6754 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 6755 params.plink_state =
f8bacc21 6756 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
ab0d76f6 6757 if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
7d27a0ba
MH
6758 params.peer_aid = nla_get_u16(
6759 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
f8bacc21
JB
6760 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
6761 }
9c3990aa 6762
ab0d76f6
JB
6763 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
6764 params.local_pm = nla_get_u32(
3b1c5a53
MP
6765 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
6766
06f7c88c
BL
6767 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
6768 params.opmode_notif_used = true;
6769 params.opmode_notif =
6770 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
6771 }
6772
43e64bf3
RM
6773 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
6774 params.he_6ghz_capa =
fce2ff72 6775 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
43e64bf3 6776
36647055
THJ
6777 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
6778 params.airtime_weight =
6779 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
6780
6781 if (params.airtime_weight &&
6782 !wiphy_ext_feature_isset(&rdev->wiphy,
6783 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6784 return -EOPNOTSUPP;
6785
e96d1cd2
ARN
6786 err = nl80211_parse_sta_txpower_setting(info, &params);
6787 if (err)
6788 return err;
6789
77ee7c89
JB
6790 /* Include parameters for TDLS peer (will check later) */
6791 err = nl80211_set_station_tdls(info, &params);
6792 if (err)
6793 return err;
6794
6795 params.vlan = get_vlan(info, rdev);
6796 if (IS_ERR(params.vlan))
6797 return PTR_ERR(params.vlan);
6798
a97f4424
JB
6799 switch (dev->ieee80211_ptr->iftype) {
6800 case NL80211_IFTYPE_AP:
6801 case NL80211_IFTYPE_AP_VLAN:
074ac8df 6802 case NL80211_IFTYPE_P2P_GO:
074ac8df 6803 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 6804 case NL80211_IFTYPE_STATION:
267335d6 6805 case NL80211_IFTYPE_ADHOC:
a97f4424 6806 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
6807 break;
6808 default:
77ee7c89
JB
6809 err = -EOPNOTSUPP;
6810 goto out_put_vlan;
034d655e
JB
6811 }
6812
77ee7c89 6813 /* driver will call cfg80211_check_station_change() */
e35e4d28 6814 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 6815
77ee7c89 6816 out_put_vlan:
1160dfa1 6817 dev_put(params.vlan);
3b85875a 6818
5727ef1b
JB
6819 return err;
6820}
6821
6822static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
6823{
4c476991 6824 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 6825 int err;
4c476991 6826 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
6827 struct station_parameters params;
6828 u8 *mac_addr = NULL;
bda95eb1
JB
6829 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6830 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
6831
6832 memset(&params, 0, sizeof(params));
6833
984c311b
JB
6834 if (!rdev->ops->add_station)
6835 return -EOPNOTSUPP;
6836
5727ef1b
JB
6837 if (!info->attrs[NL80211_ATTR_MAC])
6838 return -EINVAL;
6839
5727ef1b
JB
6840 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
6841 return -EINVAL;
6842
6843 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
6844 return -EINVAL;
6845
5e4b6f56
JM
6846 if (!info->attrs[NL80211_ATTR_STA_AID] &&
6847 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
6848 return -EINVAL;
6849
5727ef1b
JB
6850 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6851 params.supported_rates =
6852 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6853 params.supported_rates_len =
6854 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6855 params.listen_interval =
6856 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 6857
14f34e36
GG
6858 if (info->attrs[NL80211_ATTR_VLAN_ID])
6859 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
6860
17b94247 6861 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
ab0d76f6
JB
6862 params.support_p2p_ps =
6863 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
17b94247
AB
6864 } else {
6865 /*
6866 * if not specified, assume it's supported for P2P GO interface,
6867 * and is NOT supported for AP interface
6868 */
6869 params.support_p2p_ps =
6870 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
6871 }
6872
3d124ea2 6873 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 6874 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
6875 else
6876 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
51b50fbe 6877
9d62a986
JM
6878 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
6879 params.capability =
6880 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
6881 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
6882 }
6883
6884 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
6885 params.ext_capab =
6886 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6887 params.ext_capab_len =
6888 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6889 }
6890
36aedc90
JM
6891 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
6892 params.ht_capa =
6893 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 6894
f461be3e
MP
6895 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
6896 params.vht_capa =
6897 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
6898
c4cbaf79
LC
6899 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
6900 params.he_capa =
6901 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6902 params.he_capa_len =
6903 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
ea05fd35
IP
6904
6905 if (info->attrs[NL80211_ATTR_EHT_CAPABILITY]) {
6906 params.eht_capa =
6907 nla_data(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
6908 params.eht_capa_len =
6909 nla_len(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
6910
6911 if (!ieee80211_eht_capa_size_ok((const u8 *)params.he_capa,
6912 (const u8 *)params.eht_capa,
6913 params.eht_capa_len))
6914 return -EINVAL;
6915 }
c4cbaf79
LC
6916 }
6917
43e64bf3
RM
6918 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
6919 params.he_6ghz_capa =
6920 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
6921
60f4a7b1
MK
6922 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
6923 params.opmode_notif_used = true;
6924 params.opmode_notif =
6925 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
6926 }
6927
ab0d76f6 6928 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
96b78dff 6929 params.plink_action =
f8bacc21 6930 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
96b78dff 6931
36647055
THJ
6932 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
6933 params.airtime_weight =
6934 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
6935
6936 if (params.airtime_weight &&
6937 !wiphy_ext_feature_isset(&rdev->wiphy,
6938 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6939 return -EOPNOTSUPP;
6940
e96d1cd2
ARN
6941 err = nl80211_parse_sta_txpower_setting(info, &params);
6942 if (err)
6943 return err;
6944
c01fc9ad
SD
6945 err = nl80211_parse_sta_channel_info(info, &params);
6946 if (err)
6947 return err;
6948
ff276691
JB
6949 err = nl80211_parse_sta_wme(info, &params);
6950 if (err)
6951 return err;
bdd90d5e 6952
bdd3ae3d 6953 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
6954 return -EINVAL;
6955
496fcc29
JB
6956 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
6957 * as userspace might just pass through the capabilities from the IEs
6958 * directly, rather than enforcing this restriction and returning an
6959 * error in this case.
6960 */
6961 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
6962 params.ht_capa = NULL;
6963 params.vht_capa = NULL;
c4cbaf79 6964
ea05fd35
IP
6965 /* HE and EHT require WME */
6966 if (params.he_capa_len || params.he_6ghz_capa ||
6967 params.eht_capa_len)
c4cbaf79 6968 return -EINVAL;
496fcc29
JB
6969 }
6970
43e64bf3
RM
6971 /* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */
6972 if (params.he_6ghz_capa && (params.ht_capa || params.vht_capa))
6973 return -EINVAL;
6974
77ee7c89
JB
6975 /* When you run into this, adjust the code below for the new flag */
6976 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
6977
bdd90d5e
JB
6978 switch (dev->ieee80211_ptr->iftype) {
6979 case NL80211_IFTYPE_AP:
6980 case NL80211_IFTYPE_AP_VLAN:
6981 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
6982 /* ignore WME attributes if iface/sta is not capable */
6983 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
6984 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
6985 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 6986
bdd90d5e 6987 /* TDLS peers cannot be added */
3d124ea2
JM
6988 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
6989 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 6990 return -EINVAL;
bdd90d5e
JB
6991 /* but don't bother the driver with it */
6992 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 6993
d582cffb
JB
6994 /* allow authenticated/associated only if driver handles it */
6995 if (!(rdev->wiphy.features &
6996 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 6997 params.sta_flags_mask & auth_assoc)
d582cffb
JB
6998 return -EINVAL;
6999
bda95eb1
JB
7000 /* Older userspace, or userspace wanting to be compatible with
7001 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
7002 * and assoc flags in the mask, but assumes the station will be
7003 * added as associated anyway since this was the required driver
7004 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
7005 * introduced.
7006 * In order to not bother drivers with this quirk in the API
7007 * set the flags in both the mask and set for new stations in
7008 * this case.
7009 */
7010 if (!(params.sta_flags_mask & auth_assoc)) {
7011 params.sta_flags_mask |= auth_assoc;
7012 params.sta_flags_set |= auth_assoc;
7013 }
7014
bdd90d5e
JB
7015 /* must be last in here for error handling */
7016 params.vlan = get_vlan(info, rdev);
7017 if (IS_ERR(params.vlan))
7018 return PTR_ERR(params.vlan);
7019 break;
7020 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
7021 /* ignore uAPSD data */
7022 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
7023
d582cffb
JB
7024 /* associated is disallowed */
7025 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
7026 return -EINVAL;
bdd90d5e 7027 /* TDLS peers cannot be added */
3d124ea2
JM
7028 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
7029 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
7030 return -EINVAL;
7031 break;
7032 case NL80211_IFTYPE_STATION:
93d08f0b 7033 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
7034 /* ignore uAPSD data */
7035 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
7036
77ee7c89
JB
7037 /* these are disallowed */
7038 if (params.sta_flags_mask &
7039 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
7040 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 7041 return -EINVAL;
bdd90d5e
JB
7042 /* Only TDLS peers can be added */
7043 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
7044 return -EINVAL;
7045 /* Can only add if TDLS ... */
7046 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
7047 return -EOPNOTSUPP;
7048 /* ... with external setup is supported */
7049 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
7050 return -EOPNOTSUPP;
77ee7c89
JB
7051 /*
7052 * Older wpa_supplicant versions always mark the TDLS peer
7053 * as authorized, but it shouldn't yet be.
7054 */
7055 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
7056 break;
7057 default:
7058 return -EOPNOTSUPP;
c75786c9
EP
7059 }
7060
bdd90d5e 7061 /* be aware of params.vlan when changing code here */
5727ef1b 7062
e35e4d28 7063 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 7064
1160dfa1 7065 dev_put(params.vlan);
5727ef1b
JB
7066 return err;
7067}
7068
7069static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
7070{
4c476991
JB
7071 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7072 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
7073 struct station_del_parameters params;
7074
7075 memset(&params, 0, sizeof(params));
5727ef1b
JB
7076
7077 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 7078 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 7079
306b79ea
JB
7080 switch (dev->ieee80211_ptr->iftype) {
7081 case NL80211_IFTYPE_AP:
7082 case NL80211_IFTYPE_AP_VLAN:
7083 case NL80211_IFTYPE_MESH_POINT:
7084 case NL80211_IFTYPE_P2P_GO:
7085 /* always accept these */
7086 break;
7087 case NL80211_IFTYPE_ADHOC:
7088 /* conditionally accept */
7089 if (wiphy_ext_feature_isset(&rdev->wiphy,
7090 NL80211_EXT_FEATURE_DEL_IBSS_STA))
7091 break;
edafcf42 7092 return -EINVAL;
306b79ea 7093 default:
4c476991 7094 return -EINVAL;
306b79ea 7095 }
5727ef1b 7096
4c476991
JB
7097 if (!rdev->ops->del_station)
7098 return -EOPNOTSUPP;
3b85875a 7099
98856866
JM
7100 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
7101 params.subtype =
7102 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
7103 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
7104 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
7105 return -EINVAL;
7106 } else {
7107 /* Default to Deauthentication frame */
7108 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
7109 }
7110
7111 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
7112 params.reason_code =
7113 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
7114 if (params.reason_code == 0)
7115 return -EINVAL; /* 0 is reserved */
7116 } else {
7117 /* Default to reason code 2 */
7118 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
7119 }
7120
89c771e5 7121 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
7122}
7123
15e47304 7124static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
7125 int flags, struct net_device *dev,
7126 u8 *dst, u8 *next_hop,
7127 struct mpath_info *pinfo)
7128{
7129 void *hdr;
7130 struct nlattr *pinfoattr;
7131
1ef4c850 7132 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
7133 if (!hdr)
7134 return -1;
7135
9360ffd1
DM
7136 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
7137 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
7138 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
7139 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
7140 goto nla_put_failure;
f5ea9120 7141
ae0be8de 7142 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MPATH_INFO);
2ec600d6
LCC
7143 if (!pinfoattr)
7144 goto nla_put_failure;
9360ffd1
DM
7145 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
7146 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
7147 pinfo->frame_qlen))
7148 goto nla_put_failure;
7149 if (((pinfo->filled & MPATH_INFO_SN) &&
7150 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
7151 ((pinfo->filled & MPATH_INFO_METRIC) &&
7152 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
7153 pinfo->metric)) ||
7154 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
7155 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
7156 pinfo->exptime)) ||
7157 ((pinfo->filled & MPATH_INFO_FLAGS) &&
7158 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
7159 pinfo->flags)) ||
7160 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
7161 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
7162 pinfo->discovery_timeout)) ||
7163 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
7164 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
cc241636
JH
7165 pinfo->discovery_retries)) ||
7166 ((pinfo->filled & MPATH_INFO_HOP_COUNT) &&
7167 nla_put_u8(msg, NL80211_MPATH_INFO_HOP_COUNT,
540bbcb9
JH
7168 pinfo->hop_count)) ||
7169 ((pinfo->filled & MPATH_INFO_PATH_CHANGE) &&
7170 nla_put_u32(msg, NL80211_MPATH_INFO_PATH_CHANGE,
7171 pinfo->path_change_count)))
9360ffd1 7172 goto nla_put_failure;
2ec600d6
LCC
7173
7174 nla_nest_end(msg, pinfoattr);
7175
053c095a
JB
7176 genlmsg_end(msg, hdr);
7177 return 0;
2ec600d6
LCC
7178
7179 nla_put_failure:
bc3ed28c
TG
7180 genlmsg_cancel(msg, hdr);
7181 return -EMSGSIZE;
2ec600d6
LCC
7182}
7183
7184static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 7185 struct netlink_callback *cb)
2ec600d6 7186{
2ec600d6 7187 struct mpath_info pinfo;
1b8ec87a 7188 struct cfg80211_registered_device *rdev;
97990a06 7189 struct wireless_dev *wdev;
2ec600d6
LCC
7190 u8 dst[ETH_ALEN];
7191 u8 next_hop[ETH_ALEN];
97990a06 7192 int path_idx = cb->args[2];
2ec600d6 7193 int err;
2ec600d6 7194
ce6b6974 7195 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
67748893 7196 if (err)
a05829a7
JB
7197 return err;
7198 /* nl80211_prepare_wdev_dump acquired it in the successful case */
7199 __acquire(&rdev->wiphy.mtx);
bba95fef 7200
1b8ec87a 7201 if (!rdev->ops->dump_mpath) {
eec60b03 7202 err = -EOPNOTSUPP;
bba95fef
JB
7203 goto out_err;
7204 }
7205
97990a06 7206 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 7207 err = -EOPNOTSUPP;
0448b5fc 7208 goto out_err;
eec60b03
JM
7209 }
7210
bba95fef 7211 while (1) {
1b8ec87a 7212 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 7213 next_hop, &pinfo);
bba95fef 7214 if (err == -ENOENT)
2ec600d6 7215 break;
bba95fef 7216 if (err)
3b85875a 7217 goto out_err;
2ec600d6 7218
15e47304 7219 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 7220 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 7221 wdev->netdev, dst, next_hop,
bba95fef
JB
7222 &pinfo) < 0)
7223 goto out;
2ec600d6 7224
bba95fef 7225 path_idx++;
2ec600d6 7226 }
2ec600d6 7227
bba95fef 7228 out:
97990a06 7229 cb->args[2] = path_idx;
bba95fef 7230 err = skb->len;
bba95fef 7231 out_err:
a05829a7 7232 wiphy_unlock(&rdev->wiphy);
bba95fef 7233 return err;
2ec600d6
LCC
7234}
7235
7236static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
7237{
4c476991 7238 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 7239 int err;
4c476991 7240 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
7241 struct mpath_info pinfo;
7242 struct sk_buff *msg;
7243 u8 *dst = NULL;
7244 u8 next_hop[ETH_ALEN];
7245
7246 memset(&pinfo, 0, sizeof(pinfo));
7247
7248 if (!info->attrs[NL80211_ATTR_MAC])
7249 return -EINVAL;
7250
7251 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7252
4c476991
JB
7253 if (!rdev->ops->get_mpath)
7254 return -EOPNOTSUPP;
2ec600d6 7255
4c476991
JB
7256 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7257 return -EOPNOTSUPP;
eec60b03 7258
e35e4d28 7259 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 7260 if (err)
4c476991 7261 return err;
2ec600d6 7262
fd2120ca 7263 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 7264 if (!msg)
4c476991 7265 return -ENOMEM;
2ec600d6 7266
15e47304 7267 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
7268 dev, dst, next_hop, &pinfo) < 0) {
7269 nlmsg_free(msg);
7270 return -ENOBUFS;
7271 }
3b85875a 7272
4c476991 7273 return genlmsg_reply(msg, info);
2ec600d6
LCC
7274}
7275
7276static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
7277{
4c476991
JB
7278 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7279 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
7280 u8 *dst = NULL;
7281 u8 *next_hop = NULL;
7282
7283 if (!info->attrs[NL80211_ATTR_MAC])
7284 return -EINVAL;
7285
7286 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
7287 return -EINVAL;
7288
7289 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7290 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
7291
4c476991
JB
7292 if (!rdev->ops->change_mpath)
7293 return -EOPNOTSUPP;
35a8efe1 7294
4c476991
JB
7295 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7296 return -EOPNOTSUPP;
2ec600d6 7297
e35e4d28 7298 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 7299}
4c476991 7300
2ec600d6
LCC
7301static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
7302{
4c476991
JB
7303 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7304 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
7305 u8 *dst = NULL;
7306 u8 *next_hop = NULL;
7307
7308 if (!info->attrs[NL80211_ATTR_MAC])
7309 return -EINVAL;
7310
7311 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
7312 return -EINVAL;
7313
7314 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7315 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
7316
4c476991
JB
7317 if (!rdev->ops->add_mpath)
7318 return -EOPNOTSUPP;
35a8efe1 7319
4c476991
JB
7320 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7321 return -EOPNOTSUPP;
2ec600d6 7322
e35e4d28 7323 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
7324}
7325
7326static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
7327{
4c476991
JB
7328 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7329 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
7330 u8 *dst = NULL;
7331
7332 if (info->attrs[NL80211_ATTR_MAC])
7333 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7334
4c476991
JB
7335 if (!rdev->ops->del_mpath)
7336 return -EOPNOTSUPP;
3b85875a 7337
b501426c
MP
7338 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7339 return -EOPNOTSUPP;
7340
e35e4d28 7341 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
7342}
7343
66be7d2b
HR
7344static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
7345{
7346 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7347 int err;
7348 struct net_device *dev = info->user_ptr[1];
7349 struct mpath_info pinfo;
7350 struct sk_buff *msg;
7351 u8 *dst = NULL;
7352 u8 mpp[ETH_ALEN];
7353
7354 memset(&pinfo, 0, sizeof(pinfo));
7355
7356 if (!info->attrs[NL80211_ATTR_MAC])
7357 return -EINVAL;
7358
7359 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7360
7361 if (!rdev->ops->get_mpp)
7362 return -EOPNOTSUPP;
7363
7364 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7365 return -EOPNOTSUPP;
7366
7367 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
7368 if (err)
7369 return err;
7370
7371 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7372 if (!msg)
7373 return -ENOMEM;
7374
7375 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
7376 dev, dst, mpp, &pinfo) < 0) {
7377 nlmsg_free(msg);
7378 return -ENOBUFS;
7379 }
7380
7381 return genlmsg_reply(msg, info);
7382}
7383
7384static int nl80211_dump_mpp(struct sk_buff *skb,
7385 struct netlink_callback *cb)
7386{
7387 struct mpath_info pinfo;
7388 struct cfg80211_registered_device *rdev;
7389 struct wireless_dev *wdev;
7390 u8 dst[ETH_ALEN];
7391 u8 mpp[ETH_ALEN];
7392 int path_idx = cb->args[2];
7393 int err;
7394
ce6b6974 7395 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
66be7d2b 7396 if (err)
a05829a7
JB
7397 return err;
7398 /* nl80211_prepare_wdev_dump acquired it in the successful case */
7399 __acquire(&rdev->wiphy.mtx);
66be7d2b
HR
7400
7401 if (!rdev->ops->dump_mpp) {
7402 err = -EOPNOTSUPP;
7403 goto out_err;
7404 }
7405
7406 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
7407 err = -EOPNOTSUPP;
7408 goto out_err;
7409 }
7410
7411 while (1) {
7412 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
7413 mpp, &pinfo);
7414 if (err == -ENOENT)
7415 break;
7416 if (err)
7417 goto out_err;
7418
7419 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
7420 cb->nlh->nlmsg_seq, NLM_F_MULTI,
7421 wdev->netdev, dst, mpp,
7422 &pinfo) < 0)
7423 goto out;
7424
7425 path_idx++;
7426 }
7427
7428 out:
7429 cb->args[2] = path_idx;
7430 err = skb->len;
7431 out_err:
a05829a7 7432 wiphy_unlock(&rdev->wiphy);
66be7d2b
HR
7433 return err;
7434}
7435
9f1ba906
JM
7436static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
7437{
4c476991
JB
7438 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7439 struct net_device *dev = info->user_ptr[1];
c56589ed 7440 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 7441 struct bss_parameters params;
c56589ed 7442 int err;
9f1ba906
JM
7443
7444 memset(&params, 0, sizeof(params));
7445 /* default to not changing parameters */
7446 params.use_cts_prot = -1;
7447 params.use_short_preamble = -1;
7448 params.use_short_slot_time = -1;
fd8aaaf3 7449 params.ap_isolate = -1;
50b12f59 7450 params.ht_opmode = -1;
53cabad7
JB
7451 params.p2p_ctwindow = -1;
7452 params.p2p_opp_ps = -1;
9f1ba906
JM
7453
7454 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
7455 params.use_cts_prot =
7456 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
7457 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
7458 params.use_short_preamble =
7459 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
7460 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
7461 params.use_short_slot_time =
7462 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
7463 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
7464 params.basic_rates =
7465 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7466 params.basic_rates_len =
7467 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7468 }
fd8aaaf3
FF
7469 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
7470 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
7471 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
7472 params.ht_opmode =
7473 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 7474
53cabad7
JB
7475 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
7476 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7477 return -EINVAL;
7478 params.p2p_ctwindow =
ab0d76f6 7479 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
7480 if (params.p2p_ctwindow != 0 &&
7481 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
7482 return -EINVAL;
7483 }
7484
7485 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
7486 u8 tmp;
7487
7488 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7489 return -EINVAL;
7490 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
7491 params.p2p_opp_ps = tmp;
7492 if (params.p2p_opp_ps &&
7493 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
7494 return -EINVAL;
7495 }
7496
4c476991
JB
7497 if (!rdev->ops->change_bss)
7498 return -EOPNOTSUPP;
9f1ba906 7499
074ac8df 7500 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
7501 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7502 return -EOPNOTSUPP;
3b85875a 7503
c56589ed
SW
7504 wdev_lock(wdev);
7505 err = rdev_change_bss(rdev, dev, &params);
7506 wdev_unlock(wdev);
7507
7508 return err;
9f1ba906
JM
7509}
7510
b2e1b302
LR
7511static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
7512{
b2e1b302 7513 char *data = NULL;
05050753 7514 bool is_indoor;
57b5ce07 7515 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
7516 u32 owner_nlportid;
7517
80778f18
LR
7518 /*
7519 * You should only get this when cfg80211 hasn't yet initialized
7520 * completely when built-in to the kernel right between the time
7521 * window between nl80211_init() and regulatory_init(), if that is
7522 * even possible.
7523 */
458f4f9e 7524 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 7525 return -EINPROGRESS;
80778f18 7526
57b5ce07
LR
7527 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
7528 user_reg_hint_type =
7529 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
7530 else
7531 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
7532
7533 switch (user_reg_hint_type) {
7534 case NL80211_USER_REG_HINT_USER:
7535 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
7536 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
7537 return -EINVAL;
7538
7539 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
7540 return regulatory_hint_user(data, user_reg_hint_type);
7541 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
7542 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
7543 owner_nlportid = info->snd_portid;
7544 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
7545 } else {
7546 owner_nlportid = 0;
7547 is_indoor = true;
7548 }
7549
7550 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
7551 default:
7552 return -EINVAL;
7553 }
b2e1b302
LR
7554}
7555
1ea4ff3e
JB
7556static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
7557{
7558 return reg_reload_regdb();
7559}
7560
24bdd9f4 7561static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 7562 struct genl_info *info)
93da9cc1 7563{
4c476991 7564 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 7565 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
7566 struct wireless_dev *wdev = dev->ieee80211_ptr;
7567 struct mesh_config cur_params;
7568 int err = 0;
93da9cc1 7569 void *hdr;
7570 struct nlattr *pinfoattr;
7571 struct sk_buff *msg;
7572
29cbe68c
JB
7573 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
7574 return -EOPNOTSUPP;
7575
24bdd9f4 7576 if (!rdev->ops->get_mesh_config)
4c476991 7577 return -EOPNOTSUPP;
f3f92586 7578
29cbe68c
JB
7579 wdev_lock(wdev);
7580 /* If not connected, get default parameters */
7581 if (!wdev->mesh_id_len)
7582 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
7583 else
e35e4d28 7584 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
7585 wdev_unlock(wdev);
7586
93da9cc1 7587 if (err)
4c476991 7588 return err;
93da9cc1 7589
7590 /* Draw up a netlink message to send back */
fd2120ca 7591 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
7592 if (!msg)
7593 return -ENOMEM;
15e47304 7594 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 7595 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 7596 if (!hdr)
efe1cf0c 7597 goto out;
ae0be8de 7598 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 7599 if (!pinfoattr)
7600 goto nla_put_failure;
9360ffd1
DM
7601 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
7602 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
7603 cur_params.dot11MeshRetryTimeout) ||
7604 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
7605 cur_params.dot11MeshConfirmTimeout) ||
7606 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
7607 cur_params.dot11MeshHoldingTimeout) ||
7608 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
7609 cur_params.dot11MeshMaxPeerLinks) ||
7610 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
7611 cur_params.dot11MeshMaxRetries) ||
7612 nla_put_u8(msg, NL80211_MESHCONF_TTL,
7613 cur_params.dot11MeshTTL) ||
7614 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
7615 cur_params.element_ttl) ||
7616 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
7617 cur_params.auto_open_plinks) ||
7eab0f64
JL
7618 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
7619 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
7620 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
7621 cur_params.dot11MeshHWMPmaxPREQretries) ||
7622 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
7623 cur_params.path_refresh_time) ||
7624 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
7625 cur_params.min_discovery_timeout) ||
7626 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
7627 cur_params.dot11MeshHWMPactivePathTimeout) ||
7628 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
7629 cur_params.dot11MeshHWMPpreqMinInterval) ||
7630 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
7631 cur_params.dot11MeshHWMPperrMinInterval) ||
7632 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
7633 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
7634 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
7635 cur_params.dot11MeshHWMPRootMode) ||
7636 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
7637 cur_params.dot11MeshHWMPRannInterval) ||
7638 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
7639 cur_params.dot11MeshGateAnnouncementProtocol) ||
7640 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
7641 cur_params.dot11MeshForwarding) ||
335d5349 7642 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
7643 cur_params.rssi_threshold) ||
7644 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
7645 cur_params.ht_opmode) ||
7646 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
7647 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
7648 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
7649 cur_params.dot11MeshHWMProotInterval) ||
7650 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
7651 cur_params.dot11MeshHWMPconfirmationInterval) ||
7652 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
7653 cur_params.power_mode) ||
7654 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
7655 cur_params.dot11MeshAwakeWindowDuration) ||
7656 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
01d66fbd
BC
7657 cur_params.plink_timeout) ||
7658 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
e3718a61
LL
7659 cur_params.dot11MeshConnectedToMeshGate) ||
7660 nla_put_u8(msg, NL80211_MESHCONF_NOLEARN,
184eebe6
MT
7661 cur_params.dot11MeshNolearn) ||
7662 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_AS,
7663 cur_params.dot11MeshConnectedToAuthServer))
9360ffd1 7664 goto nla_put_failure;
93da9cc1 7665 nla_nest_end(msg, pinfoattr);
7666 genlmsg_end(msg, hdr);
4c476991 7667 return genlmsg_reply(msg, info);
93da9cc1 7668
3b85875a 7669 nla_put_failure:
efe1cf0c 7670 out:
d080e275 7671 nlmsg_free(msg);
4c476991 7672 return -ENOBUFS;
93da9cc1 7673}
7674
ab0d76f6
JB
7675static const struct nla_policy
7676nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
7677 [NL80211_MESHCONF_RETRY_TIMEOUT] =
7678 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7679 [NL80211_MESHCONF_CONFIRM_TIMEOUT] =
7680 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7681 [NL80211_MESHCONF_HOLDING_TIMEOUT] =
7682 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7683 [NL80211_MESHCONF_MAX_PEER_LINKS] =
7684 NLA_POLICY_RANGE(NLA_U16, 0, 255),
7685 [NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
7686 [NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
7687 [NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
7688 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
7689 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
7690 NLA_POLICY_RANGE(NLA_U32, 1, 255),
93da9cc1 7691 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
7692 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
ab0d76f6 7693 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
93da9cc1 7694 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
7695 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
7696 NLA_POLICY_MIN(NLA_U16, 1),
7697 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
7698 NLA_POLICY_MIN(NLA_U16, 1),
7699 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
7700 NLA_POLICY_MIN(NLA_U16, 1),
7701 [NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
7702 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
7703 NLA_POLICY_MIN(NLA_U16, 1),
7704 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
7705 [NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
7706 [NL80211_MESHCONF_RSSI_THRESHOLD] =
7707 NLA_POLICY_RANGE(NLA_S32, -255, 0),
a4f606ea 7708 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6 7709 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
7710 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
7711 NLA_POLICY_MIN(NLA_U16, 1),
7712 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
7713 NLA_POLICY_MIN(NLA_U16, 1),
7714 [NL80211_MESHCONF_POWER_MODE] =
7715 NLA_POLICY_RANGE(NLA_U32,
7716 NL80211_MESH_POWER_ACTIVE,
7717 NL80211_MESH_POWER_MAX),
3b1c5a53 7718 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 7719 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
01d66fbd 7720 [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
e3718a61 7721 [NL80211_MESHCONF_NOLEARN] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
184eebe6 7722 [NL80211_MESHCONF_CONNECTED_TO_AS] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
93da9cc1 7723};
7724
c80d545d
JC
7725static const struct nla_policy
7726 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 7727 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
7728 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
7729 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 7730 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 7731 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 7732 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
3d7af878
JB
7733 [NL80211_MESH_SETUP_IE] =
7734 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
7735 IEEE80211_MAX_DATA_LEN),
b130e5ce 7736 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
7737};
7738
24bdd9f4 7739static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
7740 struct mesh_config *cfg,
7741 u32 *mask_out)
93da9cc1 7742{
93da9cc1 7743 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 7744 u32 mask = 0;
9757235f 7745 u16 ht_opmode;
93da9cc1 7746
ab0d76f6
JB
7747#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
7748do { \
7749 if (tb[attr]) { \
7750 cfg->param = fn(tb[attr]); \
7751 mask |= BIT((attr) - 1); \
7752 } \
ea54fba2 7753} while (0)
bd90fdcc 7754
24bdd9f4 7755 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 7756 return -EINVAL;
8cb08174 7757 if (nla_parse_nested_deprecated(tb, NL80211_MESHCONF_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy, info->extack))
93da9cc1 7758 return -EINVAL;
7759
93da9cc1 7760 /* This makes sure that there aren't more than 32 mesh config
7761 * parameters (otherwise our bitfield scheme would not work.) */
7762 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
7763
7764 /* Fill in the params struct */
ab0d76f6
JB
7765 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
7766 NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
7767 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
7768 NL80211_MESHCONF_CONFIRM_TIMEOUT,
7769 nla_get_u16);
7770 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
7771 NL80211_MESHCONF_HOLDING_TIMEOUT,
7772 nla_get_u16);
7773 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
7774 NL80211_MESHCONF_MAX_PEER_LINKS,
7775 nla_get_u16);
7776 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
7777 NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
7778 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
7779 NL80211_MESHCONF_TTL, nla_get_u8);
7780 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
7781 NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
7782 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
7783 NL80211_MESHCONF_AUTO_OPEN_PLINKS,
7784 nla_get_u8);
ea54fba2 7785 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
ab0d76f6 7786 mask,
a4f606ea 7787 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
ab0d76f6
JB
7788 nla_get_u32);
7789 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
7790 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
7791 nla_get_u8);
7792 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
7793 NL80211_MESHCONF_PATH_REFRESH_TIME,
7794 nla_get_u32);
7795 if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
7796 (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
7797 return -EINVAL;
7798 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
7799 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
7800 nla_get_u16);
ea54fba2 7801 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
ab0d76f6 7802 mask,
a4f606ea 7803 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
ab0d76f6
JB
7804 nla_get_u32);
7805 if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
7806 (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
7807 cfg->dot11MeshHWMPactivePathTimeout > 65535))
7808 return -EINVAL;
7809 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
ea54fba2 7810 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
ab0d76f6
JB
7811 nla_get_u16);
7812 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
ea54fba2 7813 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
ab0d76f6 7814 nla_get_u16);
93da9cc1 7815 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6 7816 dot11MeshHWMPnetDiameterTraversalTime, mask,
a4f606ea 7817 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
ab0d76f6
JB
7818 nla_get_u16);
7819 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
7820 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
7821 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
7822 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
7823 nla_get_u16);
7824 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
ea54fba2 7825 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
ab0d76f6
JB
7826 nla_get_u8);
7827 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
7828 NL80211_MESHCONF_FORWARDING, nla_get_u8);
7829 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
7830 NL80211_MESHCONF_RSSI_THRESHOLD,
7831 nla_get_s32);
01d66fbd
BC
7832 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
7833 NL80211_MESHCONF_CONNECTED_TO_GATE,
7834 nla_get_u8);
184eebe6
MT
7835 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToAuthServer, mask,
7836 NL80211_MESHCONF_CONNECTED_TO_AS,
7837 nla_get_u8);
9757235f
MH
7838 /*
7839 * Check HT operation mode based on
188f60ab 7840 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
9757235f
MH
7841 */
7842 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
7843 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
7844
7845 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
7846 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
7847 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
7848 return -EINVAL;
7849
188f60ab
BC
7850 /* NON_HT_STA bit is reserved, but some programs set it */
7851 ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
9757235f 7852
9757235f 7853 cfg->ht_opmode = ht_opmode;
fd551bac 7854 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
9757235f 7855 }
728b19e5 7856 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6
JB
7857 dot11MeshHWMPactivePathToRootTimeout, mask,
7858 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
7859 nla_get_u32);
7860 if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
7861 (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
7862 cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
7863 return -EINVAL;
7864 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
7865 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
7866 nla_get_u16);
7867 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
7868 mask,
728b19e5 7869 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
ab0d76f6
JB
7870 nla_get_u16);
7871 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
7872 NL80211_MESHCONF_POWER_MODE, nla_get_u32);
7873 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
7874 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
7875 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
7876 NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
e3718a61
LL
7877 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNolearn, mask,
7878 NL80211_MESHCONF_NOLEARN, nla_get_u8);
bd90fdcc
JB
7879 if (mask_out)
7880 *mask_out = mask;
c80d545d 7881
bd90fdcc
JB
7882 return 0;
7883
7884#undef FILL_IN_MESH_PARAM_IF_SET
7885}
7886
c80d545d
JC
7887static int nl80211_parse_mesh_setup(struct genl_info *info,
7888 struct mesh_setup *setup)
7889{
bb2798d4 7890 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
7891 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
7892
7893 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
7894 return -EINVAL;
8cb08174 7895 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
7896 return -EINVAL;
7897
d299a1f2
JC
7898 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
7899 setup->sync_method =
7900 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
7901 IEEE80211_SYNC_METHOD_VENDOR :
7902 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
7903
c80d545d
JC
7904 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
7905 setup->path_sel_proto =
7906 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
7907 IEEE80211_PATH_PROTOCOL_VENDOR :
7908 IEEE80211_PATH_PROTOCOL_HWMP;
7909
7910 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
7911 setup->path_metric =
7912 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
7913 IEEE80211_PATH_METRIC_VENDOR :
7914 IEEE80211_PATH_METRIC_AIRTIME;
7915
581a8b0f 7916 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 7917 struct nlattr *ieattr =
581a8b0f 7918 tb[NL80211_MESH_SETUP_IE];
581a8b0f
JC
7919 setup->ie = nla_data(ieattr);
7920 setup->ie_len = nla_len(ieattr);
c80d545d 7921 }
bb2798d4
TP
7922 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
7923 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
7924 return -EINVAL;
7925 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
7926 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
7927 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
7928 if (setup->is_secure)
7929 setup->user_mpm = true;
c80d545d 7930
6e16d90b
CT
7931 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
7932 if (!setup->user_mpm)
7933 return -EINVAL;
7934 setup->auth_id =
7935 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
7936 }
7937
c80d545d
JC
7938 return 0;
7939}
7940
24bdd9f4 7941static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 7942 struct genl_info *info)
bd90fdcc
JB
7943{
7944 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7945 struct net_device *dev = info->user_ptr[1];
29cbe68c 7946 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
7947 struct mesh_config cfg;
7948 u32 mask;
7949 int err;
7950
29cbe68c
JB
7951 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
7952 return -EOPNOTSUPP;
7953
24bdd9f4 7954 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
7955 return -EOPNOTSUPP;
7956
24bdd9f4 7957 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
7958 if (err)
7959 return err;
7960
29cbe68c
JB
7961 wdev_lock(wdev);
7962 if (!wdev->mesh_id_len)
7963 err = -ENOLINK;
7964
7965 if (!err)
e35e4d28 7966 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
7967
7968 wdev_unlock(wdev);
7969
7970 return err;
93da9cc1 7971}
7972
ad30ca2c
AN
7973static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
7974 struct sk_buff *msg)
f130347c 7975{
f130347c
LR
7976 struct nlattr *nl_reg_rules;
7977 unsigned int i;
f130347c 7978
458f4f9e
JB
7979 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
7980 (regdom->dfs_region &&
7981 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 7982 goto nla_put_failure;
458f4f9e 7983
ae0be8de 7984 nl_reg_rules = nla_nest_start_noflag(msg, NL80211_ATTR_REG_RULES);
f130347c 7985 if (!nl_reg_rules)
ad30ca2c 7986 goto nla_put_failure;
f130347c 7987
458f4f9e 7988 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
7989 struct nlattr *nl_reg_rule;
7990 const struct ieee80211_reg_rule *reg_rule;
7991 const struct ieee80211_freq_range *freq_range;
7992 const struct ieee80211_power_rule *power_rule;
97524820 7993 unsigned int max_bandwidth_khz;
f130347c 7994
458f4f9e 7995 reg_rule = &regdom->reg_rules[i];
f130347c
LR
7996 freq_range = &reg_rule->freq_range;
7997 power_rule = &reg_rule->power_rule;
7998
ae0be8de 7999 nl_reg_rule = nla_nest_start_noflag(msg, i);
f130347c 8000 if (!nl_reg_rule)
ad30ca2c 8001 goto nla_put_failure;
f130347c 8002
97524820
JD
8003 max_bandwidth_khz = freq_range->max_bandwidth_khz;
8004 if (!max_bandwidth_khz)
8005 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
8006 reg_rule);
8007
9360ffd1
DM
8008 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
8009 reg_rule->flags) ||
8010 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
8011 freq_range->start_freq_khz) ||
8012 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
8013 freq_range->end_freq_khz) ||
8014 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 8015 max_bandwidth_khz) ||
9360ffd1
DM
8016 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
8017 power_rule->max_antenna_gain) ||
8018 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
8019 power_rule->max_eirp) ||
8020 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
8021 reg_rule->dfs_cac_ms))
ad30ca2c 8022 goto nla_put_failure;
f130347c
LR
8023
8024 nla_nest_end(msg, nl_reg_rule);
8025 }
8026
8027 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
8028 return 0;
8029
8030nla_put_failure:
8031 return -EMSGSIZE;
8032}
8033
8034static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
8035{
8036 const struct ieee80211_regdomain *regdom = NULL;
8037 struct cfg80211_registered_device *rdev;
8038 struct wiphy *wiphy = NULL;
8039 struct sk_buff *msg;
024fcf5e 8040 int err = -EMSGSIZE;
ad30ca2c
AN
8041 void *hdr;
8042
8043 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8044 if (!msg)
8045 return -ENOBUFS;
8046
8047 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
8048 NL80211_CMD_GET_REG);
8049 if (!hdr)
8050 goto put_failure;
8051
a05829a7
JB
8052 rtnl_lock();
8053
ad30ca2c 8054 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
8055 bool self_managed;
8056
ad30ca2c
AN
8057 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
8058 if (IS_ERR(rdev)) {
024fcf5e
JB
8059 err = PTR_ERR(rdev);
8060 goto nla_put_failure;
ad30ca2c
AN
8061 }
8062
8063 wiphy = &rdev->wiphy;
1bdd716c
AN
8064 self_managed = wiphy->regulatory_flags &
8065 REGULATORY_WIPHY_SELF_MANAGED;
024fcf5e
JB
8066
8067 rcu_read_lock();
8068
ad30ca2c
AN
8069 regdom = get_wiphy_regdom(wiphy);
8070
1bdd716c
AN
8071 /* a self-managed-reg device must have a private regdom */
8072 if (WARN_ON(!regdom && self_managed)) {
024fcf5e
JB
8073 err = -EINVAL;
8074 goto nla_put_failure_rcu;
1bdd716c
AN
8075 }
8076
ad30ca2c
AN
8077 if (regdom &&
8078 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
024fcf5e
JB
8079 goto nla_put_failure_rcu;
8080 } else {
8081 rcu_read_lock();
ad30ca2c
AN
8082 }
8083
8084 if (!wiphy && reg_last_request_cell_base() &&
8085 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
8086 NL80211_USER_REG_HINT_CELL_BASE))
024fcf5e 8087 goto nla_put_failure_rcu;
ad30ca2c
AN
8088
8089 if (!regdom)
8090 regdom = rcu_dereference(cfg80211_regdomain);
8091
8092 if (nl80211_put_regdom(regdom, msg))
8093 goto nla_put_failure_rcu;
8094
8095 rcu_read_unlock();
f130347c
LR
8096
8097 genlmsg_end(msg, hdr);
a05829a7 8098 rtnl_unlock();
5fe231e8 8099 return genlmsg_reply(msg, info);
f130347c 8100
458f4f9e
JB
8101nla_put_failure_rcu:
8102 rcu_read_unlock();
f130347c 8103nla_put_failure:
a05829a7 8104 rtnl_unlock();
efe1cf0c 8105put_failure:
d080e275 8106 nlmsg_free(msg);
024fcf5e 8107 return err;
f130347c
LR
8108}
8109
ad30ca2c
AN
8110static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
8111 u32 seq, int flags, struct wiphy *wiphy,
8112 const struct ieee80211_regdomain *regdom)
8113{
8114 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
8115 NL80211_CMD_GET_REG);
8116
8117 if (!hdr)
8118 return -1;
8119
0a833c29 8120 genl_dump_check_consistent(cb, hdr);
ad30ca2c
AN
8121
8122 if (nl80211_put_regdom(regdom, msg))
8123 goto nla_put_failure;
8124
8125 if (!wiphy && reg_last_request_cell_base() &&
8126 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
8127 NL80211_USER_REG_HINT_CELL_BASE))
8128 goto nla_put_failure;
8129
8130 if (wiphy &&
8131 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
8132 goto nla_put_failure;
8133
1bdd716c
AN
8134 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
8135 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
8136 goto nla_put_failure;
8137
053c095a
JB
8138 genlmsg_end(msg, hdr);
8139 return 0;
ad30ca2c
AN
8140
8141nla_put_failure:
8142 genlmsg_cancel(msg, hdr);
8143 return -EMSGSIZE;
8144}
8145
8146static int nl80211_get_reg_dump(struct sk_buff *skb,
8147 struct netlink_callback *cb)
8148{
8149 const struct ieee80211_regdomain *regdom = NULL;
8150 struct cfg80211_registered_device *rdev;
8151 int err, reg_idx, start = cb->args[2];
8152
024fcf5e 8153 rcu_read_lock();
ad30ca2c
AN
8154
8155 if (cfg80211_regdomain && start == 0) {
8156 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
8157 NLM_F_MULTI, NULL,
024fcf5e 8158 rcu_dereference(cfg80211_regdomain));
ad30ca2c
AN
8159 if (err < 0)
8160 goto out_err;
8161 }
8162
8163 /* the global regdom is idx 0 */
8164 reg_idx = 1;
024fcf5e 8165 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ad30ca2c
AN
8166 regdom = get_wiphy_regdom(&rdev->wiphy);
8167 if (!regdom)
8168 continue;
8169
8170 if (++reg_idx <= start)
8171 continue;
8172
8173 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
8174 NLM_F_MULTI, &rdev->wiphy, regdom);
8175 if (err < 0) {
8176 reg_idx--;
8177 break;
8178 }
8179 }
8180
8181 cb->args[2] = reg_idx;
8182 err = skb->len;
8183out_err:
024fcf5e 8184 rcu_read_unlock();
ad30ca2c
AN
8185 return err;
8186}
8187
b6863036
JB
8188#ifdef CONFIG_CFG80211_CRDA_SUPPORT
8189static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
8190 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
8191 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
8192 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
8193 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
8194 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
8195 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
8196 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
8197};
8198
8199static int parse_reg_rule(struct nlattr *tb[],
8200 struct ieee80211_reg_rule *reg_rule)
8201{
8202 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
8203 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
8204
8205 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
8206 return -EINVAL;
8207 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
8208 return -EINVAL;
8209 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
8210 return -EINVAL;
8211 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
8212 return -EINVAL;
8213 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
8214 return -EINVAL;
8215
8216 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
8217
8218 freq_range->start_freq_khz =
8219 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
8220 freq_range->end_freq_khz =
8221 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
8222 freq_range->max_bandwidth_khz =
8223 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
8224
8225 power_rule->max_eirp =
8226 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
8227
8228 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
8229 power_rule->max_antenna_gain =
8230 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
8231
8232 if (tb[NL80211_ATTR_DFS_CAC_TIME])
8233 reg_rule->dfs_cac_ms =
8234 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
8235
8236 return 0;
8237}
8238
b2e1b302
LR
8239static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
8240{
8241 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
8242 struct nlattr *nl_reg_rule;
ea372c54
JB
8243 char *alpha2;
8244 int rem_reg_rules, r;
391d132c 8245 u32 num_rules = 0, rule_idx = 0;
4c7d3982 8246 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 8247 struct ieee80211_regdomain *rd;
b2e1b302
LR
8248
8249 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
8250 return -EINVAL;
8251
8252 if (!info->attrs[NL80211_ATTR_REG_RULES])
8253 return -EINVAL;
8254
8255 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
8256
8b60b078
LR
8257 if (info->attrs[NL80211_ATTR_DFS_REGION])
8258 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
8259
b2e1b302 8260 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 8261 rem_reg_rules) {
b2e1b302
LR
8262 num_rules++;
8263 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 8264 return -EINVAL;
b2e1b302
LR
8265 }
8266
a05829a7
JB
8267 rtnl_lock();
8268 if (!reg_is_valid_request(alpha2)) {
8269 r = -EINVAL;
8270 goto out;
8271 }
e438768f 8272
391d132c 8273 rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
a05829a7
JB
8274 if (!rd) {
8275 r = -ENOMEM;
8276 goto out;
8277 }
b2e1b302
LR
8278
8279 rd->n_reg_rules = num_rules;
8280 rd->alpha2[0] = alpha2[0];
8281 rd->alpha2[1] = alpha2[1];
8282
8b60b078
LR
8283 /*
8284 * Disable DFS master mode if the DFS region was
8285 * not supported or known on this kernel.
8286 */
8287 if (reg_supported_dfs_region(dfs_region))
8288 rd->dfs_region = dfs_region;
8289
b2e1b302 8290 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 8291 rem_reg_rules) {
8cb08174
JB
8292 r = nla_parse_nested_deprecated(tb, NL80211_REG_RULE_ATTR_MAX,
8293 nl_reg_rule, reg_rule_policy,
8294 info->extack);
ae811e21
JB
8295 if (r)
8296 goto bad_reg;
b2e1b302
LR
8297 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
8298 if (r)
8299 goto bad_reg;
8300
8301 rule_idx++;
8302
d0e18f83
LR
8303 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
8304 r = -EINVAL;
b2e1b302 8305 goto bad_reg;
d0e18f83 8306 }
b2e1b302
LR
8307 }
8308
a05829a7 8309 r = set_regdom(rd, REGD_SOURCE_CRDA);
06627990 8310 /* set_regdom takes ownership of rd */
a05829a7 8311 rd = NULL;
d2372b31 8312 bad_reg:
b2e1b302 8313 kfree(rd);
a05829a7
JB
8314 out:
8315 rtnl_unlock();
d0e18f83 8316 return r;
b2e1b302 8317}
b6863036 8318#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 8319
83f5e2cf
JB
8320static int validate_scan_freqs(struct nlattr *freqs)
8321{
8322 struct nlattr *attr1, *attr2;
8323 int n_channels = 0, tmp1, tmp2;
8324
d7f13f74
SD
8325 nla_for_each_nested(attr1, freqs, tmp1)
8326 if (nla_len(attr1) != sizeof(u32))
8327 return 0;
8328
83f5e2cf
JB
8329 nla_for_each_nested(attr1, freqs, tmp1) {
8330 n_channels++;
8331 /*
8332 * Some hardware has a limited channel list for
8333 * scanning, and it is pretty much nonsensical
8334 * to scan for a channel twice, so disallow that
8335 * and don't require drivers to check that the
8336 * channel list they get isn't longer than what
8337 * they can scan, as long as they can scan all
8338 * the channels they registered at once.
8339 */
8340 nla_for_each_nested(attr2, freqs, tmp2)
8341 if (attr1 != attr2 &&
8342 nla_get_u32(attr1) == nla_get_u32(attr2))
8343 return 0;
8344 }
8345
8346 return n_channels;
8347}
8348
57fbcce3 8349static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 8350{
57fbcce3 8351 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
8352}
8353
8354static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
8355 struct cfg80211_bss_selection *bss_select)
8356{
8357 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
8358 struct nlattr *nest;
8359 int err;
8360 bool found = false;
8361 int i;
8362
8363 /* only process one nested attribute */
8364 nest = nla_data(nla);
8365 if (!nla_ok(nest, nla_len(nest)))
8366 return -EINVAL;
8367
8cb08174
JB
8368 err = nla_parse_nested_deprecated(attr, NL80211_BSS_SELECT_ATTR_MAX,
8369 nest, nl80211_bss_select_policy,
8370 NULL);
38de03d2
AS
8371 if (err)
8372 return err;
8373
8374 /* only one attribute may be given */
8375 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
8376 if (attr[i]) {
8377 if (found)
8378 return -EINVAL;
8379 found = true;
8380 }
8381 }
8382
8383 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
8384
8385 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
8386 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
8387
8388 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
8389 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
8390 bss_select->param.band_pref =
8391 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
8392 if (!is_band_valid(wiphy, bss_select->param.band_pref))
8393 return -EINVAL;
8394 }
8395
8396 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
8397 struct nl80211_bss_select_rssi_adjust *adj_param;
8398
8399 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
8400 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
8401 bss_select->param.adjust.band = adj_param->band;
8402 bss_select->param.adjust.delta = adj_param->delta;
8403 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
8404 return -EINVAL;
8405 }
8406
8407 /* user-space did not provide behaviour attribute */
8408 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
8409 return -EINVAL;
8410
8411 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
8412 return -EINVAL;
8413
8414 return 0;
8415}
8416
9bb7e0f2
JB
8417int nl80211_parse_random_mac(struct nlattr **attrs,
8418 u8 *mac_addr, u8 *mac_addr_mask)
ad2b26ab
JB
8419{
8420 int i;
8421
8422 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
8423 eth_zero_addr(mac_addr);
8424 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
8425 mac_addr[0] = 0x2;
8426 mac_addr_mask[0] = 0x3;
8427
8428 return 0;
8429 }
8430
8431 /* need both or none */
8432 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
8433 return -EINVAL;
8434
8435 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
8436 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
8437
8438 /* don't allow or configure an mcast address */
8439 if (!is_multicast_ether_addr(mac_addr_mask) ||
8440 is_multicast_ether_addr(mac_addr))
8441 return -EINVAL;
8442
8443 /*
8444 * allow users to pass a MAC address that has bits set outside
8445 * of the mask, but don't bother drivers with having to deal
8446 * with such bits
8447 */
8448 for (i = 0; i < ETH_ALEN; i++)
8449 mac_addr[i] &= mac_addr_mask[i];
8450
8451 return 0;
8452}
8453
34373d12
VT
8454static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
8455{
8456 ASSERT_WDEV_LOCK(wdev);
8457
8458 if (!cfg80211_beaconing_iface_active(wdev))
8459 return true;
8460
8461 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
8462 return true;
8463
8464 return regulatory_pre_cac_allowed(wdev->wiphy);
8465}
8466
db0a4ad8
JB
8467static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
8468 enum nl80211_ext_feature_index feat)
8469{
8470 if (!(flags & flag))
8471 return true;
8472 if (wiphy_ext_feature_isset(wiphy, feat))
8473 return true;
8474 return false;
8475}
8476
2d23d073
RZ
8477static int
8478nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
8479 void *request, struct nlattr **attrs,
8480 bool is_sched_scan)
8481{
8482 u8 *mac_addr, *mac_addr_mask;
8483 u32 *flags;
8484 enum nl80211_feature_flags randomness_flag;
8485
8486 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
8487 return 0;
8488
8489 if (is_sched_scan) {
8490 struct cfg80211_sched_scan_request *req = request;
8491
8492 randomness_flag = wdev ?
8493 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
8494 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
8495 flags = &req->flags;
8496 mac_addr = req->mac_addr;
8497 mac_addr_mask = req->mac_addr_mask;
8498 } else {
8499 struct cfg80211_scan_request *req = request;
8500
8501 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
8502 flags = &req->flags;
8503 mac_addr = req->mac_addr;
8504 mac_addr_mask = req->mac_addr_mask;
8505 }
8506
8507 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
8508
5037a009
SD
8509 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
8510 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
db0a4ad8
JB
8511 !nl80211_check_scan_feat(wiphy, *flags,
8512 NL80211_SCAN_FLAG_LOW_SPAN,
8513 NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
8514 !nl80211_check_scan_feat(wiphy, *flags,
8515 NL80211_SCAN_FLAG_LOW_POWER,
8516 NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
8517 !nl80211_check_scan_feat(wiphy, *flags,
8518 NL80211_SCAN_FLAG_HIGH_ACCURACY,
8519 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
8520 !nl80211_check_scan_feat(wiphy, *flags,
8521 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
8522 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
8523 !nl80211_check_scan_feat(wiphy, *flags,
8524 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
8525 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
8526 !nl80211_check_scan_feat(wiphy, *flags,
8527 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
8528 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
8529 !nl80211_check_scan_feat(wiphy, *flags,
8530 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
2e076f19
JB
8531 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
8532 !nl80211_check_scan_feat(wiphy, *flags,
8533 NL80211_SCAN_FLAG_RANDOM_SN,
8534 NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
8535 !nl80211_check_scan_feat(wiphy, *flags,
8536 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
8537 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
2d23d073
RZ
8538 return -EOPNOTSUPP;
8539
8540 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
8541 int err;
8542
8543 if (!(wiphy->features & randomness_flag) ||
8544 (wdev && wdev->current_bss))
8545 return -EOPNOTSUPP;
8546
8547 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
8548 if (err)
8549 return err;
8550 }
8551
2d23d073
RZ
8552 return 0;
8553}
8554
2a519311
JB
8555static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
8556{
4c476991 8557 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 8558 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 8559 struct cfg80211_scan_request *request;
2032f3b2
TP
8560 struct nlattr *scan_freqs = NULL;
8561 bool scan_freqs_khz = false;
2a519311
JB
8562 struct nlattr *attr;
8563 struct wiphy *wiphy;
83f5e2cf 8564 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 8565 size_t ie_len;
2a519311 8566
79c97e97 8567 wiphy = &rdev->wiphy;
2a519311 8568
cb3b7d87
AB
8569 if (wdev->iftype == NL80211_IFTYPE_NAN)
8570 return -EOPNOTSUPP;
8571
4c476991
JB
8572 if (!rdev->ops->scan)
8573 return -EOPNOTSUPP;
2a519311 8574
83286856
CJ
8575 if (rdev->scan_req || rdev->scan_msg)
8576 return -EBUSY;
2a519311 8577
2032f3b2
TP
8578 if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) {
8579 if (!wiphy_ext_feature_isset(wiphy,
8580 NL80211_EXT_FEATURE_SCAN_FREQ_KHZ))
8581 return -EOPNOTSUPP;
8582 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ];
8583 scan_freqs_khz = true;
8584 } else if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES])
8585 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
8586
8587 if (scan_freqs) {
8588 n_channels = validate_scan_freqs(scan_freqs);
83286856
CJ
8589 if (!n_channels)
8590 return -EINVAL;
2a519311 8591 } else {
bdfbec2d 8592 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
8593 }
8594
8595 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
8596 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
8597 n_ssids++;
8598
83286856
CJ
8599 if (n_ssids > wiphy->max_scan_ssids)
8600 return -EINVAL;
2a519311 8601
70692ad2
JM
8602 if (info->attrs[NL80211_ATTR_IE])
8603 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8604 else
8605 ie_len = 0;
8606
83286856
CJ
8607 if (ie_len > wiphy->max_scan_ie_len)
8608 return -EINVAL;
18a83659 8609
2a519311 8610 request = kzalloc(sizeof(*request)
a2cd43c5
LC
8611 + sizeof(*request->ssids) * n_ssids
8612 + sizeof(*request->channels) * n_channels
70692ad2 8613 + ie_len, GFP_KERNEL);
83286856
CJ
8614 if (!request)
8615 return -ENOMEM;
2a519311 8616
2a519311 8617 if (n_ssids)
5ba63533 8618 request->ssids = (void *)&request->channels[n_channels];
2a519311 8619 request->n_ssids = n_ssids;
70692ad2 8620 if (ie_len) {
13874e4b 8621 if (n_ssids)
70692ad2
JM
8622 request->ie = (void *)(request->ssids + n_ssids);
8623 else
8624 request->ie = (void *)(request->channels + n_channels);
8625 }
2a519311 8626
584991dc 8627 i = 0;
2032f3b2 8628 if (scan_freqs) {
2a519311 8629 /* user specified, bail out if channel not found */
2032f3b2 8630 nla_for_each_nested(attr, scan_freqs, tmp) {
584991dc 8631 struct ieee80211_channel *chan;
2032f3b2 8632 int freq = nla_get_u32(attr);
584991dc 8633
2032f3b2
TP
8634 if (!scan_freqs_khz)
8635 freq = MHZ_TO_KHZ(freq);
584991dc 8636
2032f3b2 8637 chan = ieee80211_get_channel_khz(wiphy, freq);
584991dc 8638 if (!chan) {
2a519311
JB
8639 err = -EINVAL;
8640 goto out_free;
8641 }
584991dc
JB
8642
8643 /* ignore disabled channels */
8644 if (chan->flags & IEEE80211_CHAN_DISABLED)
8645 continue;
8646
8647 request->channels[i] = chan;
2a519311
JB
8648 i++;
8649 }
8650 } else {
57fbcce3 8651 enum nl80211_band band;
34850ab2 8652
2a519311 8653 /* all channels */
57fbcce3 8654 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 8655 int j;
7a087e74 8656
2a519311
JB
8657 if (!wiphy->bands[band])
8658 continue;
8659 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
8660 struct ieee80211_channel *chan;
8661
8662 chan = &wiphy->bands[band]->channels[j];
8663
8664 if (chan->flags & IEEE80211_CHAN_DISABLED)
8665 continue;
8666
8667 request->channels[i] = chan;
2a519311
JB
8668 i++;
8669 }
8670 }
8671 }
8672
584991dc
JB
8673 if (!i) {
8674 err = -EINVAL;
8675 goto out_free;
8676 }
8677
8678 request->n_channels = i;
8679
34373d12
VT
8680 wdev_lock(wdev);
8681 if (!cfg80211_off_channel_oper_allowed(wdev)) {
8682 struct ieee80211_channel *chan;
8683
8684 if (request->n_channels != 1) {
8685 wdev_unlock(wdev);
8686 err = -EBUSY;
8687 goto out_free;
8688 }
8689
8690 chan = request->channels[0];
8691 if (chan->center_freq != wdev->chandef.chan->center_freq) {
8692 wdev_unlock(wdev);
8693 err = -EBUSY;
8694 goto out_free;
8695 }
8696 }
8697 wdev_unlock(wdev);
8698
2a519311 8699 i = 0;
13874e4b 8700 if (n_ssids) {
2a519311 8701 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 8702 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
8703 err = -EINVAL;
8704 goto out_free;
8705 }
57a27e1d 8706 request->ssids[i].ssid_len = nla_len(attr);
2a519311 8707 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
8708 i++;
8709 }
8710 }
8711
70692ad2
JM
8712 if (info->attrs[NL80211_ATTR_IE]) {
8713 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
8714 memcpy((void *)request->ie,
8715 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
8716 request->ie_len);
8717 }
8718
57fbcce3 8719 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
8720 if (wiphy->bands[i])
8721 request->rates[i] =
8722 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
8723
8724 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
8725 nla_for_each_nested(attr,
8726 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
8727 tmp) {
57fbcce3 8728 enum nl80211_band band = nla_type(attr);
34850ab2 8729
57fbcce3 8730 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
8731 err = -EINVAL;
8732 goto out_free;
8733 }
1b09cd82
FF
8734
8735 if (!wiphy->bands[band])
8736 continue;
8737
34850ab2
JB
8738 err = ieee80211_get_ratemask(wiphy->bands[band],
8739 nla_data(attr),
8740 nla_len(attr),
8741 &request->rates[band]);
8742 if (err)
8743 goto out_free;
8744 }
8745 }
8746
1d76250b 8747 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
1d76250b
AS
8748 request->duration =
8749 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
8750 request->duration_mandatory =
8751 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
8752 }
8753
2d23d073
RZ
8754 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
8755 false);
8756 if (err)
8757 goto out_free;
ed473771 8758
e9f935e3
RM
8759 request->no_cck =
8760 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
8761
2fa436b3
VK
8762 /* Initial implementation used NL80211_ATTR_MAC to set the specific
8763 * BSSID to scan for. This was problematic because that same attribute
8764 * was already used for another purpose (local random MAC address). The
8765 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
8766 * compatibility with older userspace components, also use the
8767 * NL80211_ATTR_MAC value here if it can be determined to be used for
8768 * the specific BSSID use case instead of the random MAC address
8769 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
8770 */
8771 if (info->attrs[NL80211_ATTR_BSSID])
8772 memcpy(request->bssid,
8773 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
8774 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
8775 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
8776 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
8777 ETH_ALEN);
8778 else
8779 eth_broadcast_addr(request->bssid);
8780
fd014284 8781 request->wdev = wdev;
79c97e97 8782 request->wiphy = &rdev->wiphy;
15d6030b 8783 request->scan_start = jiffies;
2a519311 8784
79c97e97 8785 rdev->scan_req = request;
c8cb5b85 8786 err = cfg80211_scan(rdev);
2a519311 8787
504776be
CJ
8788 if (err)
8789 goto out_free;
8790
8791 nl80211_send_scan_start(rdev, wdev);
1160dfa1 8792 dev_hold(wdev->netdev);
504776be
CJ
8793
8794 return 0;
8795
2a519311 8796 out_free:
504776be
CJ
8797 rdev->scan_req = NULL;
8798 kfree(request);
3b85875a 8799
2a519311
JB
8800 return err;
8801}
8802
91d3ab46
VK
8803static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
8804{
8805 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8806 struct wireless_dev *wdev = info->user_ptr[1];
8807
8808 if (!rdev->ops->abort_scan)
8809 return -EOPNOTSUPP;
8810
8811 if (rdev->scan_msg)
8812 return 0;
8813
8814 if (!rdev->scan_req)
8815 return -ENOENT;
8816
8817 rdev_abort_scan(rdev, wdev);
8818 return 0;
8819}
8820
3b06d277
AS
8821static int
8822nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
8823 struct cfg80211_sched_scan_request *request,
8824 struct nlattr **attrs)
8825{
8826 int tmp, err, i = 0;
8827 struct nlattr *attr;
8828
8829 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
8830 u32 interval;
8831
8832 /*
8833 * If scan plans are not specified,
5a88de53 8834 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
8835 * case one scan plan will be set with the specified scan
8836 * interval and infinite number of iterations.
8837 */
3b06d277
AS
8838 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
8839 if (!interval)
8840 return -EINVAL;
8841
8842 request->scan_plans[0].interval =
8843 DIV_ROUND_UP(interval, MSEC_PER_SEC);
8844 if (!request->scan_plans[0].interval)
8845 return -EINVAL;
8846
8847 if (request->scan_plans[0].interval >
8848 wiphy->max_sched_scan_plan_interval)
8849 request->scan_plans[0].interval =
8850 wiphy->max_sched_scan_plan_interval;
8851
8852 return 0;
8853 }
8854
8855 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
8856 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
8857
8858 if (WARN_ON(i >= n_plans))
8859 return -EINVAL;
8860
8cb08174
JB
8861 err = nla_parse_nested_deprecated(plan,
8862 NL80211_SCHED_SCAN_PLAN_MAX,
8863 attr, nl80211_plan_policy,
8864 NULL);
3b06d277
AS
8865 if (err)
8866 return err;
8867
8868 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
8869 return -EINVAL;
8870
8871 request->scan_plans[i].interval =
8872 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
8873 if (!request->scan_plans[i].interval ||
8874 request->scan_plans[i].interval >
8875 wiphy->max_sched_scan_plan_interval)
8876 return -EINVAL;
8877
8878 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
8879 request->scan_plans[i].iterations =
8880 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
8881 if (!request->scan_plans[i].iterations ||
8882 (request->scan_plans[i].iterations >
8883 wiphy->max_sched_scan_plan_iterations))
8884 return -EINVAL;
8885 } else if (i < n_plans - 1) {
8886 /*
8887 * All scan plans but the last one must specify
8888 * a finite number of iterations
8889 */
8890 return -EINVAL;
8891 }
8892
8893 i++;
8894 }
8895
8896 /*
8897 * The last scan plan must not specify the number of
8898 * iterations, it is supposed to run infinitely
8899 */
8900 if (request->scan_plans[n_plans - 1].iterations)
8901 return -EINVAL;
8902
8903 return 0;
8904}
8905
1e1b11b6 8906static int
8907nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
8908 struct cfg80211_match_set *match_sets,
8909 struct nlattr *tb_band_rssi,
8910 s32 rssi_thold)
8911{
8912 struct nlattr *attr;
8913 int i, tmp, ret = 0;
8914
8915 if (!wiphy_ext_feature_isset(wiphy,
8916 NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
8917 if (tb_band_rssi)
8918 ret = -EOPNOTSUPP;
8919 else
8920 for (i = 0; i < NUM_NL80211_BANDS; i++)
8921 match_sets->per_band_rssi_thold[i] =
8922 NL80211_SCAN_RSSI_THOLD_OFF;
8923 return ret;
8924 }
8925
8926 for (i = 0; i < NUM_NL80211_BANDS; i++)
8927 match_sets->per_band_rssi_thold[i] = rssi_thold;
8928
8929 nla_for_each_nested(attr, tb_band_rssi, tmp) {
8930 enum nl80211_band band = nla_type(attr);
8931
8932 if (band < 0 || band >= NUM_NL80211_BANDS)
8933 return -EINVAL;
8934
8935 match_sets->per_band_rssi_thold[band] = nla_get_s32(attr);
8936 }
8937
8938 return 0;
8939}
8940
256da02d 8941static struct cfg80211_sched_scan_request *
ad2b26ab 8942nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
aad1e812 8943 struct nlattr **attrs, int max_match_sets)
807f8a8c
LC
8944{
8945 struct cfg80211_sched_scan_request *request;
807f8a8c 8946 struct nlattr *attr;
3b06d277 8947 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 8948 enum nl80211_band band;
807f8a8c 8949 size_t ie_len;
a1f1c21c 8950 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 8951 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 8952
256da02d 8953 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 8954 n_channels = validate_scan_freqs(
256da02d 8955 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 8956 if (!n_channels)
256da02d 8957 return ERR_PTR(-EINVAL);
807f8a8c 8958 } else {
bdfbec2d 8959 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
8960 }
8961
256da02d
LC
8962 if (attrs[NL80211_ATTR_SCAN_SSIDS])
8963 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
8964 tmp)
8965 n_ssids++;
8966
93b6aa69 8967 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 8968 return ERR_PTR(-EINVAL);
807f8a8c 8969
ea73cbce
JB
8970 /*
8971 * First, count the number of 'real' matchsets. Due to an issue with
8972 * the old implementation, matchsets containing only the RSSI attribute
8973 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
8974 * RSSI for all matchsets, rather than their own matchset for reporting
8975 * all APs with a strong RSSI. This is needed to be compatible with
8976 * older userspace that treated a matchset with only the RSSI as the
8977 * global RSSI for all other matchsets - if there are other matchsets.
8978 */
256da02d 8979 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 8980 nla_for_each_nested(attr,
256da02d 8981 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
8982 tmp) {
8983 struct nlattr *rssi;
8984
8cb08174
JB
8985 err = nla_parse_nested_deprecated(tb,
8986 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
8987 attr,
8988 nl80211_match_policy,
8989 NULL);
ea73cbce 8990 if (err)
256da02d 8991 return ERR_PTR(err);
3007e352
AVS
8992
8993 /* SSID and BSSID are mutually exclusive */
8994 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
8995 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
8996 return ERR_PTR(-EINVAL);
8997
ea73cbce 8998 /* add other standalone attributes here */
3007e352
AVS
8999 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
9000 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
ea73cbce
JB
9001 n_match_sets++;
9002 continue;
9003 }
9004 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
9005 if (rssi)
9006 default_match_rssi = nla_get_s32(rssi);
9007 }
9008 }
9009
9010 /* However, if there's no other matchset, add the RSSI one */
9011 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
9012 n_match_sets = 1;
a1f1c21c 9013
aad1e812 9014 if (n_match_sets > max_match_sets)
256da02d 9015 return ERR_PTR(-EINVAL);
a1f1c21c 9016
256da02d
LC
9017 if (attrs[NL80211_ATTR_IE])
9018 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
9019 else
9020 ie_len = 0;
9021
5a865bad 9022 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 9023 return ERR_PTR(-EINVAL);
c10841ca 9024
3b06d277
AS
9025 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
9026 /*
9027 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
9028 * each scan plan already specifies its own interval
9029 */
9030 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
9031 return ERR_PTR(-EINVAL);
9032
9033 nla_for_each_nested(attr,
9034 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
9035 n_plans++;
9036 } else {
9037 /*
9038 * The scan interval attribute is kept for backward
9039 * compatibility. If no scan plans are specified and sched scan
9040 * interval is specified, one scan plan will be set with this
9041 * scan interval and infinite number of iterations.
9042 */
9043 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
9044 return ERR_PTR(-EINVAL);
9045
9046 n_plans = 1;
9047 }
9048
9049 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
9050 return ERR_PTR(-EINVAL);
9051
bf95ecdb 9052 if (!wiphy_ext_feature_isset(
9053 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
9054 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
9055 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
9056 return ERR_PTR(-EINVAL);
9057
807f8a8c 9058 request = kzalloc(sizeof(*request)
a2cd43c5 9059 + sizeof(*request->ssids) * n_ssids
a1f1c21c 9060 + sizeof(*request->match_sets) * n_match_sets
3b06d277 9061 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 9062 + sizeof(*request->channels) * n_channels
807f8a8c 9063 + ie_len, GFP_KERNEL);
256da02d
LC
9064 if (!request)
9065 return ERR_PTR(-ENOMEM);
807f8a8c
LC
9066
9067 if (n_ssids)
9068 request->ssids = (void *)&request->channels[n_channels];
9069 request->n_ssids = n_ssids;
9070 if (ie_len) {
13874e4b 9071 if (n_ssids)
807f8a8c
LC
9072 request->ie = (void *)(request->ssids + n_ssids);
9073 else
9074 request->ie = (void *)(request->channels + n_channels);
9075 }
9076
a1f1c21c
LC
9077 if (n_match_sets) {
9078 if (request->ie)
9079 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 9080 else if (n_ssids)
a1f1c21c
LC
9081 request->match_sets =
9082 (void *)(request->ssids + n_ssids);
9083 else
9084 request->match_sets =
9085 (void *)(request->channels + n_channels);
9086 }
9087 request->n_match_sets = n_match_sets;
9088
3b06d277
AS
9089 if (n_match_sets)
9090 request->scan_plans = (void *)(request->match_sets +
9091 n_match_sets);
9092 else if (request->ie)
9093 request->scan_plans = (void *)(request->ie + ie_len);
9094 else if (n_ssids)
9095 request->scan_plans = (void *)(request->ssids + n_ssids);
9096 else
9097 request->scan_plans = (void *)(request->channels + n_channels);
9098
9099 request->n_scan_plans = n_plans;
9100
807f8a8c 9101 i = 0;
256da02d 9102 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
9103 /* user specified, bail out if channel not found */
9104 nla_for_each_nested(attr,
256da02d 9105 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
9106 tmp) {
9107 struct ieee80211_channel *chan;
9108
9109 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
9110
9111 if (!chan) {
9112 err = -EINVAL;
9113 goto out_free;
9114 }
9115
9116 /* ignore disabled channels */
9117 if (chan->flags & IEEE80211_CHAN_DISABLED)
9118 continue;
9119
9120 request->channels[i] = chan;
9121 i++;
9122 }
9123 } else {
9124 /* all channels */
57fbcce3 9125 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 9126 int j;
7a087e74 9127
807f8a8c
LC
9128 if (!wiphy->bands[band])
9129 continue;
9130 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
9131 struct ieee80211_channel *chan;
9132
9133 chan = &wiphy->bands[band]->channels[j];
9134
9135 if (chan->flags & IEEE80211_CHAN_DISABLED)
9136 continue;
9137
9138 request->channels[i] = chan;
9139 i++;
9140 }
9141 }
9142 }
9143
9144 if (!i) {
9145 err = -EINVAL;
9146 goto out_free;
9147 }
9148
9149 request->n_channels = i;
9150
9151 i = 0;
13874e4b 9152 if (n_ssids) {
256da02d 9153 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 9154 tmp) {
57a27e1d 9155 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
9156 err = -EINVAL;
9157 goto out_free;
9158 }
57a27e1d 9159 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
9160 memcpy(request->ssids[i].ssid, nla_data(attr),
9161 nla_len(attr));
807f8a8c
LC
9162 i++;
9163 }
9164 }
9165
a1f1c21c 9166 i = 0;
256da02d 9167 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 9168 nla_for_each_nested(attr,
256da02d 9169 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 9170 tmp) {
3007e352 9171 struct nlattr *ssid, *bssid, *rssi;
a1f1c21c 9172
8cb08174
JB
9173 err = nla_parse_nested_deprecated(tb,
9174 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
9175 attr,
9176 nl80211_match_policy,
9177 NULL);
ae811e21
JB
9178 if (err)
9179 goto out_free;
4a4ab0d7 9180 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
3007e352 9181 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
d39f3b4f
JB
9182
9183 if (!ssid && !bssid) {
9184 i++;
9185 continue;
9186 }
9187
9188 if (WARN_ON(i >= n_match_sets)) {
9189 /* this indicates a programming error,
9190 * the loop above should have verified
9191 * things properly
9192 */
9193 err = -EINVAL;
9194 goto out_free;
9195 }
9196
9197 if (ssid) {
d39f3b4f
JB
9198 memcpy(request->match_sets[i].ssid.ssid,
9199 nla_data(ssid), nla_len(ssid));
9200 request->match_sets[i].ssid.ssid_len =
9201 nla_len(ssid);
9202 }
cb9abd48 9203 if (bssid)
d39f3b4f
JB
9204 memcpy(request->match_sets[i].bssid,
9205 nla_data(bssid), ETH_ALEN);
3007e352 9206
d39f3b4f
JB
9207 /* special attribute - old implementation w/a */
9208 request->match_sets[i].rssi_thold = default_match_rssi;
9209 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
9210 if (rssi)
ea73cbce 9211 request->match_sets[i].rssi_thold =
d39f3b4f 9212 nla_get_s32(rssi);
1e1b11b6 9213
9214 /* Parse per band RSSI attribute */
9215 err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
9216 &request->match_sets[i],
9217 tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
9218 request->match_sets[i].rssi_thold);
9219 if (err)
9220 goto out_free;
9221
a1f1c21c
LC
9222 i++;
9223 }
ea73cbce
JB
9224
9225 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 9226 if (i == 0 && n_match_sets)
ea73cbce
JB
9227 request->match_sets[0].rssi_thold = default_match_rssi;
9228
9229 request->min_rssi_thold = INT_MAX;
9230 for (i = 0; i < n_match_sets; i++)
9231 request->min_rssi_thold =
9232 min(request->match_sets[i].rssi_thold,
9233 request->min_rssi_thold);
9234 } else {
9235 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
9236 }
9237
9900e484
JB
9238 if (ie_len) {
9239 request->ie_len = ie_len;
807f8a8c 9240 memcpy((void *)request->ie,
256da02d 9241 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
9242 request->ie_len);
9243 }
9244
2d23d073
RZ
9245 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
9246 if (err)
9247 goto out_free;
ed473771 9248
9c748934
LC
9249 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
9250 request->delay =
9251 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
9252
bf95ecdb 9253 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
9254 request->relative_rssi = nla_get_s8(
9255 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
9256 request->relative_rssi_set = true;
9257 }
9258
9259 if (request->relative_rssi_set &&
9260 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
9261 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
9262
9263 rssi_adjust = nla_data(
9264 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
9265 request->rssi_adjust.band = rssi_adjust->band;
9266 request->rssi_adjust.delta = rssi_adjust->delta;
9267 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
9268 err = -EINVAL;
9269 goto out_free;
9270 }
9271 }
9272
3b06d277
AS
9273 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
9274 if (err)
9275 goto out_free;
9276
15d6030b 9277 request->scan_start = jiffies;
807f8a8c 9278
256da02d 9279 return request;
807f8a8c
LC
9280
9281out_free:
9282 kfree(request);
256da02d
LC
9283 return ERR_PTR(err);
9284}
9285
9286static int nl80211_start_sched_scan(struct sk_buff *skb,
9287 struct genl_info *info)
9288{
9289 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9290 struct net_device *dev = info->user_ptr[1];
ad2b26ab 9291 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 9292 struct cfg80211_sched_scan_request *sched_scan_req;
ca986ad9 9293 bool want_multi;
256da02d
LC
9294 int err;
9295
ca986ad9 9296 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
256da02d
LC
9297 return -EOPNOTSUPP;
9298
ca986ad9
AVS
9299 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
9300 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
9301 if (err)
9302 return err;
256da02d 9303
31a60ed1 9304 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
aad1e812
AVS
9305 info->attrs,
9306 rdev->wiphy.max_match_sets);
31a60ed1
JR
9307
9308 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
9309 if (err)
9310 goto out_err;
9311
ca986ad9
AVS
9312 /* leave request id zero for legacy request
9313 * or if driver does not support multi-scheduled scan
9314 */
2fd351a8
DK
9315 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1)
9316 sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
ca986ad9 9317
31a60ed1 9318 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
9319 if (err)
9320 goto out_free;
9321
31a60ed1
JR
9322 sched_scan_req->dev = dev;
9323 sched_scan_req->wiphy = &rdev->wiphy;
9324
93a1e86c
JR
9325 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
9326 sched_scan_req->owner_nlportid = info->snd_portid;
9327
ca986ad9 9328 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
256da02d 9329
96b08fd6 9330 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
256da02d
LC
9331 return 0;
9332
9333out_free:
31a60ed1 9334 kfree(sched_scan_req);
256da02d 9335out_err:
807f8a8c
LC
9336 return err;
9337}
9338
9339static int nl80211_stop_sched_scan(struct sk_buff *skb,
9340 struct genl_info *info)
9341{
ca986ad9 9342 struct cfg80211_sched_scan_request *req;
807f8a8c 9343 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ca986ad9 9344 u64 cookie;
807f8a8c 9345
ca986ad9 9346 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
807f8a8c
LC
9347 return -EOPNOTSUPP;
9348
ca986ad9
AVS
9349 if (info->attrs[NL80211_ATTR_COOKIE]) {
9350 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9351 return __cfg80211_stop_sched_scan(rdev, cookie, false);
9352 }
9353
9354 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
9355 struct cfg80211_sched_scan_request,
9356 list);
9357 if (!req || req->reqid ||
9358 (req->owner_nlportid &&
9359 req->owner_nlportid != info->snd_portid))
9360 return -ENOENT;
9361
9362 return cfg80211_stop_sched_scan_req(rdev, req, false);
807f8a8c
LC
9363}
9364
04f39047
SW
9365static int nl80211_start_radar_detection(struct sk_buff *skb,
9366 struct genl_info *info)
9367{
9368 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9369 struct net_device *dev = info->user_ptr[1];
9370 struct wireless_dev *wdev = dev->ieee80211_ptr;
13cf6dec 9371 struct wiphy *wiphy = wdev->wiphy;
04f39047 9372 struct cfg80211_chan_def chandef;
55f7435c 9373 enum nl80211_dfs_regions dfs_region;
31559f35 9374 unsigned int cac_time_ms;
84158164
LB
9375 int err = -EINVAL;
9376
9377 flush_delayed_work(&rdev->dfs_update_channels_wk);
9378
9379 wiphy_lock(wiphy);
04f39047 9380
13cf6dec 9381 dfs_region = reg_get_dfs_region(wiphy);
55f7435c 9382 if (dfs_region == NL80211_DFS_UNSET)
84158164 9383 goto unlock;
55f7435c 9384
04f39047
SW
9385 err = nl80211_parse_chandef(rdev, info, &chandef);
9386 if (err)
84158164 9387 goto unlock;
04f39047 9388
13cf6dec 9389 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
04f39047 9390 if (err < 0)
84158164 9391 goto unlock;
04f39047 9392
84158164
LB
9393 if (err == 0) {
9394 err = -EINVAL;
9395 goto unlock;
9396 }
04f39047 9397
84158164
LB
9398 if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) {
9399 err = -EINVAL;
9400 goto unlock;
9401 }
04f39047 9402
a95bfb87
LB
9403 if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND])) {
9404 err = cfg80211_start_background_radar_detection(rdev, wdev,
9405 &chandef);
84158164
LB
9406 goto unlock;
9407 }
bc2dfc02 9408
84158164
LB
9409 if (netif_carrier_ok(dev)) {
9410 err = -EBUSY;
9411 goto unlock;
9412 }
bc2dfc02 9413
84158164
LB
9414 if (wdev->cac_started) {
9415 err = -EBUSY;
9416 goto unlock;
9417 }
bc2dfc02 9418
13cf6dec 9419 /* CAC start is offloaded to HW and can't be started manually */
84158164
LB
9420 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) {
9421 err = -EOPNOTSUPP;
9422 goto unlock;
9423 }
13cf6dec 9424
84158164
LB
9425 if (!rdev->ops->start_radar_detection) {
9426 err = -EOPNOTSUPP;
9427 goto unlock;
9428 }
04f39047 9429
31559f35
JD
9430 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
9431 if (WARN_ON(!cac_time_ms))
9432 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
9433
a1056b1b 9434 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 9435 if (!err) {
9e0e2961 9436 wdev->chandef = chandef;
04f39047
SW
9437 wdev->cac_started = true;
9438 wdev->cac_start_time = jiffies;
31559f35 9439 wdev->cac_time_ms = cac_time_ms;
04f39047 9440 }
84158164
LB
9441unlock:
9442 wiphy_unlock(wiphy);
9443
04f39047
SW
9444 return err;
9445}
9446
30c63115
S
9447static int nl80211_notify_radar_detection(struct sk_buff *skb,
9448 struct genl_info *info)
9449{
9450 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9451 struct net_device *dev = info->user_ptr[1];
9452 struct wireless_dev *wdev = dev->ieee80211_ptr;
9453 struct wiphy *wiphy = wdev->wiphy;
9454 struct cfg80211_chan_def chandef;
9455 enum nl80211_dfs_regions dfs_region;
9456 int err;
9457
9458 dfs_region = reg_get_dfs_region(wiphy);
9459 if (dfs_region == NL80211_DFS_UNSET) {
9460 GENL_SET_ERR_MSG(info,
9461 "DFS Region is not set. Unexpected Radar indication");
9462 return -EINVAL;
9463 }
9464
9465 err = nl80211_parse_chandef(rdev, info, &chandef);
9466 if (err) {
9467 GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
9468 return err;
9469 }
9470
9471 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
9472 if (err < 0) {
9473 GENL_SET_ERR_MSG(info, "chandef is invalid");
9474 return err;
9475 }
9476
9477 if (err == 0) {
9478 GENL_SET_ERR_MSG(info,
9479 "Unexpected Radar indication for chandef/iftype");
9480 return -EINVAL;
9481 }
9482
9483 /* Do not process this notification if radar is already detected
9484 * by kernel on this channel, and return success.
9485 */
9486 if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
9487 return 0;
9488
9489 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
9490
9491 cfg80211_sched_dfs_chan_update(rdev);
9492
a680fe46 9493 rdev->radar_chandef = chandef;
30c63115
S
9494
9495 /* Propagate this notification to other radios as well */
9496 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
9497
9498 return 0;
9499}
9500
16ef1fe2
SW
9501static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
9502{
9503 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9504 struct net_device *dev = info->user_ptr[1];
9505 struct wireless_dev *wdev = dev->ieee80211_ptr;
9506 struct cfg80211_csa_settings params;
a05829a7 9507 struct nlattr **csa_attrs = NULL;
16ef1fe2 9508 int err;
ee4bc9e7 9509 bool need_new_beacon = false;
8d9de16f 9510 bool need_handle_dfs_flag = true;
9a774c78 9511 int len, i;
252e07ca 9512 u32 cs_count;
16ef1fe2
SW
9513
9514 if (!rdev->ops->channel_switch ||
9515 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
9516 return -EOPNOTSUPP;
9517
ee4bc9e7
SW
9518 switch (dev->ieee80211_ptr->iftype) {
9519 case NL80211_IFTYPE_AP:
9520 case NL80211_IFTYPE_P2P_GO:
9521 need_new_beacon = true;
8d9de16f
BB
9522 /* For all modes except AP the handle_dfs flag needs to be
9523 * supplied to tell the kernel that userspace will handle radar
9524 * events when they happen. Otherwise a switch to a channel
9525 * requiring DFS will be rejected.
9526 */
9527 need_handle_dfs_flag = false;
ee4bc9e7
SW
9528
9529 /* useless if AP is not running */
9530 if (!wdev->beacon_interval)
1ff79dfa 9531 return -ENOTCONN;
ee4bc9e7
SW
9532 break;
9533 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
9534 if (!wdev->ssid_len)
9535 return -ENOTCONN;
9536 break;
c6da674a 9537 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
9538 if (!wdev->mesh_id_len)
9539 return -ENOTCONN;
ee4bc9e7
SW
9540 break;
9541 default:
16ef1fe2 9542 return -EOPNOTSUPP;
ee4bc9e7 9543 }
16ef1fe2
SW
9544
9545 memset(&params, 0, sizeof(params));
c177db2d 9546 params.beacon_csa.ftm_responder = -1;
16ef1fe2
SW
9547
9548 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
9549 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
9550 return -EINVAL;
9551
9552 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 9553 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
9554 return -EINVAL;
9555
252e07ca
LC
9556 /* Even though the attribute is u32, the specification says
9557 * u8, so let's make sure we don't overflow.
9558 */
9559 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
9560 if (cs_count > 255)
9561 return -EINVAL;
9562
9563 params.count = cs_count;
16ef1fe2 9564
ee4bc9e7
SW
9565 if (!need_new_beacon)
9566 goto skip_beacons;
9567
81e54d08 9568 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
16ef1fe2 9569 if (err)
dc1e3cb8 9570 goto free;
16ef1fe2 9571
a05829a7
JB
9572 csa_attrs = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*csa_attrs),
9573 GFP_KERNEL);
dc1e3cb8
JC
9574 if (!csa_attrs) {
9575 err = -ENOMEM;
9576 goto free;
9577 }
a05829a7 9578
8cb08174
JB
9579 err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
9580 info->attrs[NL80211_ATTR_CSA_IES],
9581 nl80211_policy, info->extack);
16ef1fe2 9582 if (err)
a05829a7 9583 goto free;
16ef1fe2 9584
81e54d08 9585 err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
16ef1fe2 9586 if (err)
a05829a7 9587 goto free;
16ef1fe2 9588
a05829a7
JB
9589 if (!csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
9590 err = -EINVAL;
9591 goto free;
9592 }
16ef1fe2 9593
00c207ed 9594 len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
a05829a7
JB
9595 if (!len || (len % sizeof(u16))) {
9596 err = -EINVAL;
9597 goto free;
9598 }
16ef1fe2 9599
9a774c78
AO
9600 params.n_counter_offsets_beacon = len / sizeof(u16);
9601 if (rdev->wiphy.max_num_csa_counters &&
9602 (params.n_counter_offsets_beacon >
a05829a7
JB
9603 rdev->wiphy.max_num_csa_counters)) {
9604 err = -EINVAL;
9605 goto free;
9606 }
16ef1fe2 9607
9a774c78 9608 params.counter_offsets_beacon =
00c207ed 9609 nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
9a774c78
AO
9610
9611 /* sanity checks - counters should fit and be the same */
9612 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
9613 u16 offset = params.counter_offsets_beacon[i];
9614
a05829a7
JB
9615 if (offset >= params.beacon_csa.tail_len) {
9616 err = -EINVAL;
9617 goto free;
9618 }
9a774c78 9619
a05829a7
JB
9620 if (params.beacon_csa.tail[offset] != params.count) {
9621 err = -EINVAL;
9622 goto free;
9623 }
9a774c78
AO
9624 }
9625
00c207ed
JC
9626 if (csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
9627 len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
a05829a7
JB
9628 if (!len || (len % sizeof(u16))) {
9629 err = -EINVAL;
9630 goto free;
9631 }
16ef1fe2 9632
9a774c78
AO
9633 params.n_counter_offsets_presp = len / sizeof(u16);
9634 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 9635 (params.n_counter_offsets_presp >
a05829a7
JB
9636 rdev->wiphy.max_num_csa_counters)) {
9637 err = -EINVAL;
9638 goto free;
9639 }
9a774c78
AO
9640
9641 params.counter_offsets_presp =
00c207ed 9642 nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
9a774c78
AO
9643
9644 /* sanity checks - counters should fit and be the same */
9645 for (i = 0; i < params.n_counter_offsets_presp; i++) {
9646 u16 offset = params.counter_offsets_presp[i];
9647
a05829a7
JB
9648 if (offset >= params.beacon_csa.probe_resp_len) {
9649 err = -EINVAL;
9650 goto free;
9651 }
9a774c78
AO
9652
9653 if (params.beacon_csa.probe_resp[offset] !=
a05829a7
JB
9654 params.count) {
9655 err = -EINVAL;
9656 goto free;
9657 }
9a774c78 9658 }
16ef1fe2
SW
9659 }
9660
ee4bc9e7 9661skip_beacons:
16ef1fe2
SW
9662 err = nl80211_parse_chandef(rdev, info, &params.chandef);
9663 if (err)
a05829a7 9664 goto free;
16ef1fe2 9665
923b352f 9666 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
a05829a7
JB
9667 wdev->iftype)) {
9668 err = -EINVAL;
9669 goto free;
9670 }
16ef1fe2 9671
2beb6dab
LC
9672 err = cfg80211_chandef_dfs_required(wdev->wiphy,
9673 &params.chandef,
9674 wdev->iftype);
9675 if (err < 0)
a05829a7 9676 goto free;
2beb6dab 9677
8d9de16f 9678 if (err > 0) {
2beb6dab 9679 params.radar_required = true;
8d9de16f
BB
9680 if (need_handle_dfs_flag &&
9681 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
a05829a7
JB
9682 err = -EINVAL;
9683 goto free;
8d9de16f
BB
9684 }
9685 }
16ef1fe2 9686
16ef1fe2
SW
9687 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
9688 params.block_tx = true;
9689
c56589ed
SW
9690 wdev_lock(wdev);
9691 err = rdev_channel_switch(rdev, dev, &params);
9692 wdev_unlock(wdev);
9693
a05829a7 9694free:
dc1e3cb8
JC
9695 kfree(params.beacon_after.mbssid_ies);
9696 kfree(params.beacon_csa.mbssid_ies);
a05829a7 9697 kfree(csa_attrs);
c56589ed 9698 return err;
16ef1fe2
SW
9699}
9700
9720bb3a
JB
9701static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
9702 u32 seq, int flags,
2a519311 9703 struct cfg80211_registered_device *rdev,
48ab905d
JB
9704 struct wireless_dev *wdev,
9705 struct cfg80211_internal_bss *intbss)
2a519311 9706{
48ab905d 9707 struct cfg80211_bss *res = &intbss->pub;
9caf0364 9708 const struct cfg80211_bss_ies *ies;
2a519311
JB
9709 void *hdr;
9710 struct nlattr *bss;
48ab905d
JB
9711
9712 ASSERT_WDEV_LOCK(wdev);
2a519311 9713
15e47304 9714 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
9715 NL80211_CMD_NEW_SCAN_RESULTS);
9716 if (!hdr)
9717 return -1;
9718
0a833c29 9719 genl_dump_check_consistent(cb, hdr);
9720bb3a 9720
97990a06
JB
9721 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
9722 goto nla_put_failure;
9723 if (wdev->netdev &&
9360ffd1
DM
9724 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
9725 goto nla_put_failure;
2dad624e
ND
9726 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
9727 NL80211_ATTR_PAD))
97990a06 9728 goto nla_put_failure;
2a519311 9729
ae0be8de 9730 bss = nla_nest_start_noflag(msg, NL80211_ATTR_BSS);
2a519311
JB
9731 if (!bss)
9732 goto nla_put_failure;
9360ffd1 9733 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 9734 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 9735 goto nla_put_failure;
9caf0364
JB
9736
9737 rcu_read_lock();
0e227084
JB
9738 /* indicate whether we have probe response data or not */
9739 if (rcu_access_pointer(res->proberesp_ies) &&
9740 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
9741 goto fail_unlock_rcu;
9742
9743 /* this pointer prefers to be pointed to probe response data
9744 * but is always valid
9745 */
9caf0364 9746 ies = rcu_dereference(res->ies);
8cef2c9d 9747 if (ies) {
2dad624e
ND
9748 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
9749 NL80211_BSS_PAD))
8cef2c9d 9750 goto fail_unlock_rcu;
8cef2c9d
JB
9751 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
9752 ies->len, ies->data))
9753 goto fail_unlock_rcu;
9caf0364 9754 }
0e227084
JB
9755
9756 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 9757 ies = rcu_dereference(res->beacon_ies);
0e227084 9758 if (ies && ies->from_beacon) {
2dad624e
ND
9759 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
9760 NL80211_BSS_PAD))
8cef2c9d
JB
9761 goto fail_unlock_rcu;
9762 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
9763 ies->len, ies->data))
9764 goto fail_unlock_rcu;
9caf0364
JB
9765 }
9766 rcu_read_unlock();
9767
9360ffd1
DM
9768 if (res->beacon_interval &&
9769 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
9770 goto nla_put_failure;
9771 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
9772 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
942ba88b
TP
9773 nla_put_u32(msg, NL80211_BSS_FREQUENCY_OFFSET,
9774 res->channel->freq_offset) ||
dcd6eac1 9775 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
9776 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
9777 jiffies_to_msecs(jiffies - intbss->ts)))
9778 goto nla_put_failure;
2a519311 9779
1d76250b
AS
9780 if (intbss->parent_tsf &&
9781 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
9782 intbss->parent_tsf, NL80211_BSS_PAD) ||
9783 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
9784 intbss->parent_bssid)))
9785 goto nla_put_failure;
9786
6e19bc4b 9787 if (intbss->ts_boottime &&
2dad624e
ND
9788 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
9789 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
9790 goto nla_put_failure;
9791
983dafaa
SD
9792 if (!nl80211_put_signal(msg, intbss->pub.chains,
9793 intbss->pub.chain_signal,
9794 NL80211_BSS_CHAIN_SIGNAL))
9795 goto nla_put_failure;
9796
77965c97 9797 switch (rdev->wiphy.signal_type) {
2a519311 9798 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
9799 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
9800 goto nla_put_failure;
2a519311
JB
9801 break;
9802 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
9803 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
9804 goto nla_put_failure;
2a519311
JB
9805 break;
9806 default:
9807 break;
9808 }
9809
48ab905d 9810 switch (wdev->iftype) {
074ac8df 9811 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 9812 case NL80211_IFTYPE_STATION:
9360ffd1
DM
9813 if (intbss == wdev->current_bss &&
9814 nla_put_u32(msg, NL80211_BSS_STATUS,
9815 NL80211_BSS_STATUS_ASSOCIATED))
9816 goto nla_put_failure;
48ab905d
JB
9817 break;
9818 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
9819 if (intbss == wdev->current_bss &&
9820 nla_put_u32(msg, NL80211_BSS_STATUS,
9821 NL80211_BSS_STATUS_IBSS_JOINED))
9822 goto nla_put_failure;
48ab905d
JB
9823 break;
9824 default:
9825 break;
9826 }
9827
2a519311
JB
9828 nla_nest_end(msg, bss);
9829
053c095a
JB
9830 genlmsg_end(msg, hdr);
9831 return 0;
2a519311 9832
8cef2c9d
JB
9833 fail_unlock_rcu:
9834 rcu_read_unlock();
2a519311
JB
9835 nla_put_failure:
9836 genlmsg_cancel(msg, hdr);
9837 return -EMSGSIZE;
9838}
9839
97990a06 9840static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 9841{
48ab905d 9842 struct cfg80211_registered_device *rdev;
2a519311 9843 struct cfg80211_internal_bss *scan;
48ab905d 9844 struct wireless_dev *wdev;
97990a06 9845 int start = cb->args[2], idx = 0;
2a519311
JB
9846 int err;
9847
ce6b6974 9848 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
a05829a7 9849 if (err)
67748893 9850 return err;
a05829a7
JB
9851 /* nl80211_prepare_wdev_dump acquired it in the successful case */
9852 __acquire(&rdev->wiphy.mtx);
2a519311 9853
48ab905d
JB
9854 wdev_lock(wdev);
9855 spin_lock_bh(&rdev->bss_lock);
d1e23c94
DK
9856
9857 /*
9858 * dump_scan will be called multiple times to break up the scan results
9859 * into multiple messages. It is unlikely that any more bss-es will be
9860 * expired after the first call, so only call only call this on the
9861 * first dump_scan invocation.
9862 */
9863 if (start == 0)
9864 cfg80211_bss_expire(rdev);
48ab905d 9865
9720bb3a
JB
9866 cb->seq = rdev->bss_generation;
9867
48ab905d 9868 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
9869 if (++idx <= start)
9870 continue;
9720bb3a 9871 if (nl80211_send_bss(skb, cb,
2a519311 9872 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 9873 rdev, wdev, scan) < 0) {
2a519311 9874 idx--;
67748893 9875 break;
2a519311
JB
9876 }
9877 }
9878
48ab905d
JB
9879 spin_unlock_bh(&rdev->bss_lock);
9880 wdev_unlock(wdev);
2a519311 9881
97990a06 9882 cb->args[2] = idx;
a05829a7 9883 wiphy_unlock(&rdev->wiphy);
2a519311 9884
67748893 9885 return skb->len;
2a519311
JB
9886}
9887
15e47304 9888static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
9889 int flags, struct net_device *dev,
9890 bool allow_radio_stats,
9891 struct survey_info *survey)
61fa713c
HS
9892{
9893 void *hdr;
9894 struct nlattr *infoattr;
9895
11f78ac3
JB
9896 /* skip radio stats if userspace didn't request them */
9897 if (!survey->channel && !allow_radio_stats)
9898 return 0;
9899
15e47304 9900 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
9901 NL80211_CMD_NEW_SURVEY_RESULTS);
9902 if (!hdr)
9903 return -ENOMEM;
9904
9360ffd1
DM
9905 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9906 goto nla_put_failure;
61fa713c 9907
ae0be8de 9908 infoattr = nla_nest_start_noflag(msg, NL80211_ATTR_SURVEY_INFO);
61fa713c
HS
9909 if (!infoattr)
9910 goto nla_put_failure;
9911
11f78ac3
JB
9912 if (survey->channel &&
9913 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
9914 survey->channel->center_freq))
9915 goto nla_put_failure;
58ef7c1b
TP
9916
9917 if (survey->channel && survey->channel->freq_offset &&
9918 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY_OFFSET,
9919 survey->channel->freq_offset))
9920 goto nla_put_failure;
9360ffd1
DM
9921
9922 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
9923 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
9924 goto nla_put_failure;
9925 if ((survey->filled & SURVEY_INFO_IN_USE) &&
9926 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
9927 goto nla_put_failure;
4ed20beb 9928 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
9929 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
9930 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 9931 goto nla_put_failure;
4ed20beb 9932 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
9933 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
9934 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9935 goto nla_put_failure;
4ed20beb 9936 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
9937 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
9938 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9939 goto nla_put_failure;
4ed20beb 9940 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
9941 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
9942 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9943 goto nla_put_failure;
4ed20beb 9944 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
9945 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
9946 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9947 goto nla_put_failure;
052536ab 9948 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
9949 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
9950 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 9951 goto nla_put_failure;
c8cd6e7f
FF
9952 if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) &&
9953 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX,
9954 survey->time_bss_rx, NL80211_SURVEY_INFO_PAD))
9955 goto nla_put_failure;
61fa713c
HS
9956
9957 nla_nest_end(msg, infoattr);
9958
053c095a
JB
9959 genlmsg_end(msg, hdr);
9960 return 0;
61fa713c
HS
9961
9962 nla_put_failure:
9963 genlmsg_cancel(msg, hdr);
9964 return -EMSGSIZE;
9965}
9966
11f78ac3 9967static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 9968{
50508d94 9969 struct nlattr **attrbuf;
61fa713c 9970 struct survey_info survey;
1b8ec87a 9971 struct cfg80211_registered_device *rdev;
97990a06
JB
9972 struct wireless_dev *wdev;
9973 int survey_idx = cb->args[2];
61fa713c 9974 int res;
11f78ac3 9975 bool radio_stats;
61fa713c 9976
50508d94
JB
9977 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
9978 if (!attrbuf)
9979 return -ENOMEM;
9980
ce6b6974 9981 res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, attrbuf);
a05829a7
JB
9982 if (res) {
9983 kfree(attrbuf);
9984 return res;
9985 }
9986 /* nl80211_prepare_wdev_dump acquired it in the successful case */
9987 __acquire(&rdev->wiphy.mtx);
61fa713c 9988
11f78ac3 9989 /* prepare_wdev_dump parsed the attributes */
c90c39da 9990 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 9991
97990a06
JB
9992 if (!wdev->netdev) {
9993 res = -EINVAL;
9994 goto out_err;
9995 }
9996
1b8ec87a 9997 if (!rdev->ops->dump_survey) {
61fa713c
HS
9998 res = -EOPNOTSUPP;
9999 goto out_err;
10000 }
10001
10002 while (1) {
1b8ec87a 10003 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
10004 if (res == -ENOENT)
10005 break;
10006 if (res)
10007 goto out_err;
10008
11f78ac3
JB
10009 /* don't send disabled channels, but do send non-channel data */
10010 if (survey.channel &&
10011 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
10012 survey_idx++;
10013 continue;
10014 }
10015
61fa713c 10016 if (nl80211_send_survey(skb,
15e47304 10017 NETLINK_CB(cb->skb).portid,
61fa713c 10018 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 10019 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
10020 goto out;
10021 survey_idx++;
10022 }
10023
10024 out:
97990a06 10025 cb->args[2] = survey_idx;
61fa713c
HS
10026 res = skb->len;
10027 out_err:
50508d94 10028 kfree(attrbuf);
a05829a7 10029 wiphy_unlock(&rdev->wiphy);
61fa713c
HS
10030 return res;
10031}
10032
b23aa676
SO
10033static bool nl80211_valid_wpa_versions(u32 wpa_versions)
10034{
10035 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
cc3e14c2
CHH
10036 NL80211_WPA_VERSION_2 |
10037 NL80211_WPA_VERSION_3));
b23aa676
SO
10038}
10039
636a5d36
JM
10040static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
10041{
4c476991
JB
10042 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10043 struct net_device *dev = info->user_ptr[1];
19957bb3 10044 struct ieee80211_channel *chan;
11b6b5a4
JM
10045 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
10046 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 10047 enum nl80211_auth_type auth_type;
fffd0934 10048 struct key_parse key;
d5cdfacb 10049 bool local_state_change;
942ba88b 10050 u32 freq;
636a5d36 10051
f4a11bb0
JB
10052 if (!info->attrs[NL80211_ATTR_MAC])
10053 return -EINVAL;
10054
1778092e
JM
10055 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
10056 return -EINVAL;
10057
19957bb3
JB
10058 if (!info->attrs[NL80211_ATTR_SSID])
10059 return -EINVAL;
10060
10061 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
10062 return -EINVAL;
10063
fffd0934
JB
10064 err = nl80211_parse_key(info, &key);
10065 if (err)
10066 return err;
10067
10068 if (key.idx >= 0) {
e31b8213
JB
10069 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
10070 return -EINVAL;
fffd0934
JB
10071 if (!key.p.key || !key.p.key_len)
10072 return -EINVAL;
10073 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
10074 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
10075 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
10076 key.p.key_len != WLAN_KEY_LEN_WEP104))
10077 return -EINVAL;
b6b5555b 10078 if (key.idx > 3)
fffd0934
JB
10079 return -EINVAL;
10080 } else {
10081 key.p.key_len = 0;
10082 key.p.key = NULL;
10083 }
10084
afea0b7a
JB
10085 if (key.idx >= 0) {
10086 int i;
10087 bool ok = false;
7a087e74 10088
afea0b7a
JB
10089 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
10090 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
10091 ok = true;
10092 break;
10093 }
10094 }
4c476991
JB
10095 if (!ok)
10096 return -EINVAL;
afea0b7a
JB
10097 }
10098
4c476991
JB
10099 if (!rdev->ops->auth)
10100 return -EOPNOTSUPP;
636a5d36 10101
074ac8df 10102 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10103 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10104 return -EOPNOTSUPP;
eec60b03 10105
19957bb3 10106 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
942ba88b
TP
10107 freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
10108 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
10109 freq +=
10110 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
10111
10112 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
664834de 10113 if (!chan)
4c476991 10114 return -EINVAL;
636a5d36 10115
19957bb3
JB
10116 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10117 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
10118
10119 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
10120 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10121 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10122 }
10123
19957bb3 10124 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 10125 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 10126 return -EINVAL;
636a5d36 10127
63181060
JM
10128 if ((auth_type == NL80211_AUTHTYPE_SAE ||
10129 auth_type == NL80211_AUTHTYPE_FILS_SK ||
10130 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
10131 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 10132 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
10133 return -EINVAL;
10134
11b6b5a4 10135 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
10136 if (auth_type != NL80211_AUTHTYPE_SAE &&
10137 auth_type != NL80211_AUTHTYPE_FILS_SK &&
10138 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
10139 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 10140 return -EINVAL;
11b6b5a4
JM
10141 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
10142 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e
JM
10143 }
10144
d5cdfacb
JM
10145 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10146
95de817b
JB
10147 /*
10148 * Since we no longer track auth state, ignore
10149 * requests to only change local state.
10150 */
10151 if (local_state_change)
10152 return 0;
10153
91bf9b26
JB
10154 wdev_lock(dev->ieee80211_ptr);
10155 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
10156 ssid, ssid_len, ie, ie_len,
10157 key.p.key, key.p.key_len, key.idx,
11b6b5a4 10158 auth_data, auth_data_len);
91bf9b26
JB
10159 wdev_unlock(dev->ieee80211_ptr);
10160 return err;
636a5d36
JM
10161}
10162
64bf3d4b
DK
10163static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
10164 struct genl_info *info)
10165{
10166 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10167 GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
10168 return -EINVAL;
10169 }
10170
10171 if (!rdev->ops->tx_control_port ||
10172 !wiphy_ext_feature_isset(&rdev->wiphy,
10173 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
10174 return -EOPNOTSUPP;
10175
10176 return 0;
10177}
10178
c0692b8f
JB
10179static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
10180 struct genl_info *info,
3dc27d25
JB
10181 struct cfg80211_crypto_settings *settings,
10182 int cipher_limit)
b23aa676 10183{
c0b2bbd8
JB
10184 memset(settings, 0, sizeof(*settings));
10185
b23aa676
SO
10186 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
10187
c0692b8f
JB
10188 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
10189 u16 proto;
7a087e74 10190
c0692b8f
JB
10191 proto = nla_get_u16(
10192 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
10193 settings->control_port_ethertype = cpu_to_be16(proto);
10194 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
10195 proto != ETH_P_PAE)
10196 return -EINVAL;
10197 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
10198 settings->control_port_no_encrypt = true;
10199 } else
10200 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
10201
64bf3d4b
DK
10202 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
10203 int r = validate_pae_over_nl80211(rdev, info);
10204
10205 if (r < 0)
10206 return r;
10207
10208 settings->control_port_over_nl80211 = true;
7f3f96ce
MT
10209
10210 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH])
10211 settings->control_port_no_preauth = true;
64bf3d4b
DK
10212 }
10213
b23aa676
SO
10214 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
10215 void *data;
10216 int len, i;
10217
10218 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
10219 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
10220 settings->n_ciphers_pairwise = len / sizeof(u32);
10221
10222 if (len % sizeof(u32))
10223 return -EINVAL;
10224
3dc27d25 10225 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
10226 return -EINVAL;
10227
10228 memcpy(settings->ciphers_pairwise, data, len);
10229
10230 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
10231 if (!cfg80211_supported_cipher_suite(
10232 &rdev->wiphy,
b23aa676
SO
10233 settings->ciphers_pairwise[i]))
10234 return -EINVAL;
10235 }
10236
10237 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
10238 settings->cipher_group =
10239 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
10240 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
10241 settings->cipher_group))
b23aa676
SO
10242 return -EINVAL;
10243 }
10244
10245 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
10246 settings->wpa_versions =
10247 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
10248 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
10249 return -EINVAL;
10250 }
10251
10252 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
10253 void *data;
6d30240e 10254 int len;
b23aa676
SO
10255
10256 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
10257 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
10258 settings->n_akm_suites = len / sizeof(u32);
10259
10260 if (len % sizeof(u32))
10261 return -EINVAL;
10262
1b9ca027
JM
10263 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
10264 return -EINVAL;
10265
b23aa676 10266 memcpy(settings->akm_suites, data, len);
b23aa676
SO
10267 }
10268
91b5ab62
EP
10269 if (info->attrs[NL80211_ATTR_PMK]) {
10270 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
10271 return -EINVAL;
10272 if (!wiphy_ext_feature_isset(&rdev->wiphy,
f9662274
CHH
10273 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) &&
10274 !wiphy_ext_feature_isset(&rdev->wiphy,
10275 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
91b5ab62
EP
10276 return -EINVAL;
10277 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
10278 }
10279
26f7044e
CHH
10280 if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
10281 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2831a631
CHH
10282 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
10283 !wiphy_ext_feature_isset(&rdev->wiphy,
10284 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP))
26f7044e
CHH
10285 return -EINVAL;
10286 settings->sae_pwd =
10287 nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
10288 settings->sae_pwd_len =
10289 nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
10290 }
10291
9f0ffa41
RD
10292 if (info->attrs[NL80211_ATTR_SAE_PWE])
10293 settings->sae_pwe =
10294 nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
10295 else
10296 settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
10297
b23aa676
SO
10298 return 0;
10299}
10300
636a5d36
JM
10301static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
10302{
4c476991
JB
10303 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10304 struct net_device *dev = info->user_ptr[1];
f444de05 10305 struct ieee80211_channel *chan;
f62fab73
JB
10306 struct cfg80211_assoc_request req = {};
10307 const u8 *bssid, *ssid;
10308 int err, ssid_len = 0;
942ba88b 10309 u32 freq;
636a5d36 10310
bad29297
AZ
10311 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10312 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10313 return -EPERM;
10314
f4a11bb0 10315 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
10316 !info->attrs[NL80211_ATTR_SSID] ||
10317 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
10318 return -EINVAL;
10319
4c476991
JB
10320 if (!rdev->ops->assoc)
10321 return -EOPNOTSUPP;
636a5d36 10322
074ac8df 10323 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10324 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10325 return -EOPNOTSUPP;
eec60b03 10326
19957bb3 10327 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 10328
942ba88b
TP
10329 freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
10330 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
10331 freq +=
10332 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
10333 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
664834de 10334 if (!chan)
4c476991 10335 return -EINVAL;
636a5d36 10336
19957bb3
JB
10337 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10338 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
10339
10340 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
10341 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10342 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10343 }
10344
dc6382ce 10345 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 10346 enum nl80211_mfp mfp =
dc6382ce 10347 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 10348 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 10349 req.use_mfp = true;
4c476991
JB
10350 else if (mfp != NL80211_MFP_NO)
10351 return -EINVAL;
dc6382ce
JM
10352 }
10353
3e5d7649 10354 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 10355 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 10356
7e7c8926 10357 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 10358 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
10359
10360 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
10361 memcpy(&req.ht_capa_mask,
10362 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10363 sizeof(req.ht_capa_mask));
7e7c8926
BG
10364
10365 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 10366 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 10367 return -EINVAL;
f62fab73
JB
10368 memcpy(&req.ht_capa,
10369 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10370 sizeof(req.ht_capa));
7e7c8926
BG
10371 }
10372
ee2aca34 10373 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 10374 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34 10375
b6db0f89
BG
10376 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
10377 req.flags |= ASSOC_REQ_DISABLE_HE;
10378
ee2aca34 10379 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
10380 memcpy(&req.vht_capa_mask,
10381 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
10382 sizeof(req.vht_capa_mask));
ee2aca34
JB
10383
10384 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 10385 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 10386 return -EINVAL;
f62fab73
JB
10387 memcpy(&req.vht_capa,
10388 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
10389 sizeof(req.vht_capa));
ee2aca34
JB
10390 }
10391
bab5ab7d 10392 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
10393 if (!((rdev->wiphy.features &
10394 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
10395 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
10396 !wiphy_ext_feature_isset(&rdev->wiphy,
10397 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
10398 return -EINVAL;
10399 req.flags |= ASSOC_REQ_USE_RRM;
10400 }
10401
348bd456
JM
10402 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
10403 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
10404 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
10405 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
10406 return -EINVAL;
10407 req.fils_nonces =
10408 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
10409 }
10410
d2b7588a
TP
10411 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]) {
10412 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY])
10413 return -EINVAL;
10414 memcpy(&req.s1g_capa_mask,
10415 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]),
10416 sizeof(req.s1g_capa_mask));
10417 }
10418
10419 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) {
10420 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK])
10421 return -EINVAL;
10422 memcpy(&req.s1g_capa,
10423 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]),
10424 sizeof(req.s1g_capa));
10425 }
10426
f62fab73 10427 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
10428 if (!err) {
10429 wdev_lock(dev->ieee80211_ptr);
bd2522b1 10430
f62fab73
JB
10431 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
10432 ssid, ssid_len, &req);
bd2522b1
AZ
10433
10434 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10435 dev->ieee80211_ptr->conn_owner_nlportid =
10436 info->snd_portid;
10437 memcpy(dev->ieee80211_ptr->disconnect_bssid,
10438 bssid, ETH_ALEN);
10439 }
10440
91bf9b26
JB
10441 wdev_unlock(dev->ieee80211_ptr);
10442 }
636a5d36 10443
636a5d36
JM
10444 return err;
10445}
10446
10447static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
10448{
4c476991
JB
10449 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10450 struct net_device *dev = info->user_ptr[1];
19957bb3 10451 const u8 *ie = NULL, *bssid;
91bf9b26 10452 int ie_len = 0, err;
19957bb3 10453 u16 reason_code;
d5cdfacb 10454 bool local_state_change;
636a5d36 10455
bad29297
AZ
10456 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10457 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10458 return -EPERM;
10459
f4a11bb0
JB
10460 if (!info->attrs[NL80211_ATTR_MAC])
10461 return -EINVAL;
10462
10463 if (!info->attrs[NL80211_ATTR_REASON_CODE])
10464 return -EINVAL;
10465
4c476991
JB
10466 if (!rdev->ops->deauth)
10467 return -EOPNOTSUPP;
636a5d36 10468
074ac8df 10469 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10470 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10471 return -EOPNOTSUPP;
eec60b03 10472
19957bb3 10473 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 10474
19957bb3
JB
10475 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
10476 if (reason_code == 0) {
f4a11bb0 10477 /* Reason Code 0 is reserved */
4c476991 10478 return -EINVAL;
255e737e 10479 }
636a5d36
JM
10480
10481 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
10482 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10483 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10484 }
10485
d5cdfacb
JM
10486 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10487
91bf9b26
JB
10488 wdev_lock(dev->ieee80211_ptr);
10489 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
10490 local_state_change);
10491 wdev_unlock(dev->ieee80211_ptr);
10492 return err;
636a5d36
JM
10493}
10494
10495static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
10496{
4c476991
JB
10497 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10498 struct net_device *dev = info->user_ptr[1];
19957bb3 10499 const u8 *ie = NULL, *bssid;
91bf9b26 10500 int ie_len = 0, err;
19957bb3 10501 u16 reason_code;
d5cdfacb 10502 bool local_state_change;
636a5d36 10503
bad29297
AZ
10504 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10505 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10506 return -EPERM;
10507
f4a11bb0
JB
10508 if (!info->attrs[NL80211_ATTR_MAC])
10509 return -EINVAL;
10510
10511 if (!info->attrs[NL80211_ATTR_REASON_CODE])
10512 return -EINVAL;
10513
4c476991
JB
10514 if (!rdev->ops->disassoc)
10515 return -EOPNOTSUPP;
636a5d36 10516
074ac8df 10517 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10518 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10519 return -EOPNOTSUPP;
eec60b03 10520
19957bb3 10521 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 10522
19957bb3
JB
10523 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
10524 if (reason_code == 0) {
f4a11bb0 10525 /* Reason Code 0 is reserved */
4c476991 10526 return -EINVAL;
255e737e 10527 }
636a5d36
JM
10528
10529 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
10530 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10531 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10532 }
10533
d5cdfacb
JM
10534 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10535
91bf9b26
JB
10536 wdev_lock(dev->ieee80211_ptr);
10537 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
10538 local_state_change);
10539 wdev_unlock(dev->ieee80211_ptr);
10540 return err;
636a5d36
JM
10541}
10542
dd5b4cc7
FF
10543static bool
10544nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 10545 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
10546 int rateval)
10547{
10548 struct wiphy *wiphy = &rdev->wiphy;
10549 bool found = false;
10550 int band, i;
10551
57fbcce3 10552 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
10553 struct ieee80211_supported_band *sband;
10554
10555 sband = wiphy->bands[band];
10556 if (!sband)
10557 continue;
10558
10559 for (i = 0; i < sband->n_bitrates; i++) {
10560 if (sband->bitrates[i].bitrate == rateval) {
10561 mcast_rate[band] = i + 1;
10562 found = true;
10563 break;
10564 }
10565 }
10566 }
10567
10568 return found;
10569}
10570
04a773ad
JB
10571static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
10572{
4c476991
JB
10573 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10574 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
10575 struct cfg80211_ibss_params ibss;
10576 struct wiphy *wiphy;
fffd0934 10577 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
10578 int err;
10579
8e30bc55
JB
10580 memset(&ibss, 0, sizeof(ibss));
10581
683b6d3b 10582 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
10583 !nla_len(info->attrs[NL80211_ATTR_SSID]))
10584 return -EINVAL;
10585
8e30bc55
JB
10586 ibss.beacon_interval = 100;
10587
12d20fc9 10588 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
10589 ibss.beacon_interval =
10590 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 10591
0c317a02
PK
10592 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
10593 ibss.beacon_interval);
12d20fc9
PK
10594 if (err)
10595 return err;
8e30bc55 10596
4c476991
JB
10597 if (!rdev->ops->join_ibss)
10598 return -EOPNOTSUPP;
04a773ad 10599
4c476991
JB
10600 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
10601 return -EOPNOTSUPP;
04a773ad 10602
79c97e97 10603 wiphy = &rdev->wiphy;
04a773ad 10604
39193498 10605 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 10606 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
10607
10608 if (!is_valid_ether_addr(ibss.bssid))
10609 return -EINVAL;
10610 }
04a773ad
JB
10611 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10612 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10613
10614 if (info->attrs[NL80211_ATTR_IE]) {
10615 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10616 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10617 }
10618
683b6d3b
JB
10619 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
10620 if (err)
10621 return err;
04a773ad 10622
174e0cd2
IP
10623 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
10624 NL80211_IFTYPE_ADHOC))
54858ee5
AS
10625 return -EINVAL;
10626
2f301ab2 10627 switch (ibss.chandef.width) {
bf372645
SW
10628 case NL80211_CHAN_WIDTH_5:
10629 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
10630 case NL80211_CHAN_WIDTH_20_NOHT:
10631 break;
10632 case NL80211_CHAN_WIDTH_20:
10633 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
10634 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
10635 return -EINVAL;
10636 break;
10637 case NL80211_CHAN_WIDTH_80:
10638 case NL80211_CHAN_WIDTH_80P80:
10639 case NL80211_CHAN_WIDTH_160:
10640 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
10641 return -EINVAL;
10642 if (!wiphy_ext_feature_isset(&rdev->wiphy,
10643 NL80211_EXT_FEATURE_VHT_IBSS))
10644 return -EINVAL;
10645 break;
3743bec6
JD
10646 case NL80211_CHAN_WIDTH_320:
10647 return -EINVAL;
2f301ab2 10648 default:
c04d6150 10649 return -EINVAL;
2f301ab2 10650 }
db9c64cf 10651
04a773ad 10652 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
10653 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
10654
fbd2c8dc
TP
10655 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
10656 u8 *rates =
10657 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10658 int n_rates =
10659 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10660 struct ieee80211_supported_band *sband =
683b6d3b 10661 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 10662
34850ab2
JB
10663 err = ieee80211_get_ratemask(sband, rates, n_rates,
10664 &ibss.basic_rates);
10665 if (err)
10666 return err;
fbd2c8dc 10667 }
dd5b4cc7 10668
803768f5
SW
10669 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10670 memcpy(&ibss.ht_capa_mask,
10671 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10672 sizeof(ibss.ht_capa_mask));
10673
10674 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
10675 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10676 return -EINVAL;
10677 memcpy(&ibss.ht_capa,
10678 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10679 sizeof(ibss.ht_capa));
10680 }
10681
dd5b4cc7
FF
10682 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
10683 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
10684 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
10685 return -EINVAL;
fbd2c8dc 10686
4c476991 10687 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
10688 bool no_ht = false;
10689
768075eb 10690 connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
4c476991
JB
10691 if (IS_ERR(connkeys))
10692 return PTR_ERR(connkeys);
de7044ee 10693
3d9d1d66
JB
10694 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
10695 no_ht) {
453431a5 10696 kfree_sensitive(connkeys);
de7044ee
SM
10697 return -EINVAL;
10698 }
4c476991 10699 }
04a773ad 10700
267335d6
AQ
10701 ibss.control_port =
10702 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
10703
c3bfe1f6
DK
10704 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
10705 int r = validate_pae_over_nl80211(rdev, info);
10706
d350a0f4 10707 if (r < 0) {
453431a5 10708 kfree_sensitive(connkeys);
c3bfe1f6 10709 return r;
d350a0f4 10710 }
c3bfe1f6
DK
10711
10712 ibss.control_port_over_nl80211 = true;
10713 }
10714
5336fa88
SW
10715 ibss.userspace_handles_dfs =
10716 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
10717
f8d16d3e
DK
10718 wdev_lock(dev->ieee80211_ptr);
10719 err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 10720 if (err)
453431a5 10721 kfree_sensitive(connkeys);
f8d16d3e
DK
10722 else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
10723 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10724 wdev_unlock(dev->ieee80211_ptr);
10725
04a773ad
JB
10726 return err;
10727}
10728
10729static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
10730{
4c476991
JB
10731 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10732 struct net_device *dev = info->user_ptr[1];
04a773ad 10733
4c476991
JB
10734 if (!rdev->ops->leave_ibss)
10735 return -EOPNOTSUPP;
04a773ad 10736
4c476991
JB
10737 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
10738 return -EOPNOTSUPP;
04a773ad 10739
4c476991 10740 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
10741}
10742
f4e583c8
AQ
10743static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
10744{
10745 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10746 struct net_device *dev = info->user_ptr[1];
57fbcce3 10747 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
10748 u32 nla_rate;
10749 int err;
10750
10751 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
10752 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
10753 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
10754 return -EOPNOTSUPP;
10755
10756 if (!rdev->ops->set_mcast_rate)
10757 return -EOPNOTSUPP;
10758
10759 memset(mcast_rate, 0, sizeof(mcast_rate));
10760
10761 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
10762 return -EINVAL;
10763
10764 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
10765 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
10766 return -EINVAL;
10767
a1056b1b 10768 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
10769
10770 return err;
10771}
10772
ad7e718c
JB
10773static struct sk_buff *
10774__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
10775 struct wireless_dev *wdev, int approxlen,
10776 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
10777 enum nl80211_attrs attr,
10778 const struct nl80211_vendor_cmd_info *info,
10779 gfp_t gfp)
ad7e718c
JB
10780{
10781 struct sk_buff *skb;
10782 void *hdr;
10783 struct nlattr *data;
10784
10785 skb = nlmsg_new(approxlen + 100, gfp);
10786 if (!skb)
10787 return NULL;
10788
10789 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
10790 if (!hdr) {
10791 kfree_skb(skb);
10792 return NULL;
10793 }
10794
10795 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
10796 goto nla_put_failure;
567ffc35
JB
10797
10798 if (info) {
10799 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
10800 info->vendor_id))
10801 goto nla_put_failure;
10802 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
10803 info->subcmd))
10804 goto nla_put_failure;
10805 }
10806
6c09e791 10807 if (wdev) {
2dad624e
ND
10808 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
10809 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
10810 goto nla_put_failure;
10811 if (wdev->netdev &&
10812 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
10813 wdev->netdev->ifindex))
10814 goto nla_put_failure;
10815 }
10816
ae0be8de 10817 data = nla_nest_start_noflag(skb, attr);
76e1fb4b
JB
10818 if (!data)
10819 goto nla_put_failure;
ad7e718c
JB
10820
10821 ((void **)skb->cb)[0] = rdev;
10822 ((void **)skb->cb)[1] = hdr;
10823 ((void **)skb->cb)[2] = data;
10824
10825 return skb;
10826
10827 nla_put_failure:
10828 kfree_skb(skb);
10829 return NULL;
10830}
f4e583c8 10831
e03ad6ea 10832struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 10833 struct wireless_dev *wdev,
e03ad6ea
JB
10834 enum nl80211_commands cmd,
10835 enum nl80211_attrs attr,
55c1fdf0 10836 unsigned int portid,
e03ad6ea
JB
10837 int vendor_event_idx,
10838 int approxlen, gfp_t gfp)
10839{
f26cbf40 10840 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
10841 const struct nl80211_vendor_cmd_info *info;
10842
10843 switch (cmd) {
10844 case NL80211_CMD_TESTMODE:
10845 if (WARN_ON(vendor_event_idx != -1))
10846 return NULL;
10847 info = NULL;
10848 break;
10849 case NL80211_CMD_VENDOR:
10850 if (WARN_ON(vendor_event_idx < 0 ||
10851 vendor_event_idx >= wiphy->n_vendor_events))
10852 return NULL;
10853 info = &wiphy->vendor_events[vendor_event_idx];
10854 break;
10855 default:
10856 WARN_ON(1);
10857 return NULL;
10858 }
10859
55c1fdf0 10860 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0,
e03ad6ea
JB
10861 cmd, attr, info, gfp);
10862}
10863EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
10864
10865void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
10866{
10867 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
10868 void *hdr = ((void **)skb->cb)[1];
55c1fdf0 10869 struct nlmsghdr *nlhdr = nlmsg_hdr(skb);
e03ad6ea
JB
10870 struct nlattr *data = ((void **)skb->cb)[2];
10871 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
10872
bd8c78e7
JB
10873 /* clear CB data for netlink core to own from now on */
10874 memset(skb->cb, 0, sizeof(skb->cb));
10875
e03ad6ea
JB
10876 nla_nest_end(skb, data);
10877 genlmsg_end(skb, hdr);
10878
55c1fdf0
JB
10879 if (nlhdr->nlmsg_pid) {
10880 genlmsg_unicast(wiphy_net(&rdev->wiphy), skb,
10881 nlhdr->nlmsg_pid);
10882 } else {
10883 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
10884 mcgrp = NL80211_MCGRP_VENDOR;
e03ad6ea 10885
55c1fdf0
JB
10886 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
10887 skb, 0, mcgrp, gfp);
10888 }
e03ad6ea
JB
10889}
10890EXPORT_SYMBOL(__cfg80211_send_event_skb);
10891
aff89a9b 10892#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
10893static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
10894{
4c476991 10895 struct cfg80211_registered_device *rdev = info->user_ptr[0];
a05829a7 10896 struct wireless_dev *wdev;
aff89a9b
JB
10897 int err;
10898
a05829a7
JB
10899 lockdep_assert_held(&rdev->wiphy.mtx);
10900
10901 wdev = __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
10902 info->attrs);
10903
fc73f11f
DS
10904 if (!rdev->ops->testmode_cmd)
10905 return -EOPNOTSUPP;
10906
10907 if (IS_ERR(wdev)) {
10908 err = PTR_ERR(wdev);
10909 if (err != -EINVAL)
10910 return err;
10911 wdev = NULL;
10912 } else if (wdev->wiphy != &rdev->wiphy) {
10913 return -EINVAL;
10914 }
10915
aff89a9b
JB
10916 if (!info->attrs[NL80211_ATTR_TESTDATA])
10917 return -EINVAL;
10918
ad7e718c 10919 rdev->cur_cmd_info = info;
fc73f11f 10920 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
10921 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
10922 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 10923 rdev->cur_cmd_info = NULL;
aff89a9b 10924
aff89a9b
JB
10925 return err;
10926}
10927
71063f0e
WYG
10928static int nl80211_testmode_dump(struct sk_buff *skb,
10929 struct netlink_callback *cb)
10930{
00918d33 10931 struct cfg80211_registered_device *rdev;
50508d94 10932 struct nlattr **attrbuf = NULL;
71063f0e
WYG
10933 int err;
10934 long phy_idx;
10935 void *data = NULL;
10936 int data_len = 0;
10937
5fe231e8
JB
10938 rtnl_lock();
10939
71063f0e
WYG
10940 if (cb->args[0]) {
10941 /*
10942 * 0 is a valid index, but not valid for args[0],
10943 * so we need to offset by 1.
10944 */
10945 phy_idx = cb->args[0] - 1;
a4956dca
LC
10946
10947 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
10948 if (!rdev) {
10949 err = -ENOENT;
10950 goto out_err;
10951 }
71063f0e 10952 } else {
50508d94
JB
10953 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
10954 GFP_KERNEL);
10955 if (!attrbuf) {
10956 err = -ENOMEM;
10957 goto out_err;
10958 }
c90c39da 10959
8cb08174
JB
10960 err = nlmsg_parse_deprecated(cb->nlh,
10961 GENL_HDRLEN + nl80211_fam.hdrsize,
10962 attrbuf, nl80211_fam.maxattr,
10963 nl80211_policy, NULL);
71063f0e 10964 if (err)
5fe231e8 10965 goto out_err;
00918d33 10966
c90c39da 10967 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 10968 if (IS_ERR(rdev)) {
5fe231e8
JB
10969 err = PTR_ERR(rdev);
10970 goto out_err;
00918d33 10971 }
2bd7e35d 10972 phy_idx = rdev->wiphy_idx;
2bd7e35d 10973
c90c39da
JB
10974 if (attrbuf[NL80211_ATTR_TESTDATA])
10975 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
10976 }
10977
10978 if (cb->args[1]) {
10979 data = nla_data((void *)cb->args[1]);
10980 data_len = nla_len((void *)cb->args[1]);
10981 }
10982
00918d33 10983 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
10984 err = -EOPNOTSUPP;
10985 goto out_err;
10986 }
10987
10988 while (1) {
15e47304 10989 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
10990 cb->nlh->nlmsg_seq, NLM_F_MULTI,
10991 NL80211_CMD_TESTMODE);
10992 struct nlattr *tmdata;
10993
cb35fba3
DC
10994 if (!hdr)
10995 break;
10996
9360ffd1 10997 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
10998 genlmsg_cancel(skb, hdr);
10999 break;
11000 }
11001
ae0be8de 11002 tmdata = nla_nest_start_noflag(skb, NL80211_ATTR_TESTDATA);
71063f0e
WYG
11003 if (!tmdata) {
11004 genlmsg_cancel(skb, hdr);
11005 break;
11006 }
e35e4d28 11007 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
11008 nla_nest_end(skb, tmdata);
11009
11010 if (err == -ENOBUFS || err == -ENOENT) {
11011 genlmsg_cancel(skb, hdr);
11012 break;
11013 } else if (err) {
11014 genlmsg_cancel(skb, hdr);
11015 goto out_err;
11016 }
11017
11018 genlmsg_end(skb, hdr);
11019 }
11020
11021 err = skb->len;
11022 /* see above */
11023 cb->args[0] = phy_idx + 1;
11024 out_err:
50508d94 11025 kfree(attrbuf);
5fe231e8 11026 rtnl_unlock();
71063f0e
WYG
11027 return err;
11028}
aff89a9b
JB
11029#endif
11030
b23aa676
SO
11031static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
11032{
4c476991
JB
11033 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11034 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
11035 struct cfg80211_connect_params connect;
11036 struct wiphy *wiphy;
fffd0934 11037 struct cfg80211_cached_keys *connkeys = NULL;
942ba88b 11038 u32 freq = 0;
b23aa676
SO
11039 int err;
11040
11041 memset(&connect, 0, sizeof(connect));
11042
b23aa676
SO
11043 if (!info->attrs[NL80211_ATTR_SSID] ||
11044 !nla_len(info->attrs[NL80211_ATTR_SSID]))
11045 return -EINVAL;
11046
11047 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
11048 connect.auth_type =
11049 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
11050 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
11051 NL80211_CMD_CONNECT))
b23aa676
SO
11052 return -EINVAL;
11053 } else
11054 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
11055
11056 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
11057
3a00df57
AS
11058 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
11059 !wiphy_ext_feature_isset(&rdev->wiphy,
11060 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
11061 return -EINVAL;
11062 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
11063
c0692b8f 11064 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 11065 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
11066 if (err)
11067 return err;
b23aa676 11068
074ac8df 11069 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11070 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11071 return -EOPNOTSUPP;
b23aa676 11072
79c97e97 11073 wiphy = &rdev->wiphy;
b23aa676 11074
4486ea98
BS
11075 connect.bg_scan_period = -1;
11076 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
11077 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
11078 connect.bg_scan_period =
11079 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
11080 }
11081
b23aa676
SO
11082 if (info->attrs[NL80211_ATTR_MAC])
11083 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
11084 else if (info->attrs[NL80211_ATTR_MAC_HINT])
11085 connect.bssid_hint =
11086 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
11087 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
11088 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
11089
11090 if (info->attrs[NL80211_ATTR_IE]) {
11091 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11092 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11093 }
11094
cee00a95
JM
11095 if (info->attrs[NL80211_ATTR_USE_MFP]) {
11096 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
65026002
EG
11097 if (connect.mfp == NL80211_MFP_OPTIONAL &&
11098 !wiphy_ext_feature_isset(&rdev->wiphy,
11099 NL80211_EXT_FEATURE_MFP_OPTIONAL))
11100 return -EOPNOTSUPP;
cee00a95
JM
11101 } else {
11102 connect.mfp = NL80211_MFP_NO;
11103 }
11104
ba6fbacf
JM
11105 if (info->attrs[NL80211_ATTR_PREV_BSSID])
11106 connect.prev_bssid =
11107 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
11108
942ba88b
TP
11109 if (info->attrs[NL80211_ATTR_WIPHY_FREQ])
11110 freq = MHZ_TO_KHZ(nla_get_u32(
11111 info->attrs[NL80211_ATTR_WIPHY_FREQ]));
11112 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
11113 freq +=
11114 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
11115
11116 if (freq) {
11117 connect.channel = nl80211_get_valid_chan(wiphy, freq);
664834de 11118 if (!connect.channel)
1df4a510
JM
11119 return -EINVAL;
11120 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
942ba88b
TP
11121 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
11122 freq = MHZ_TO_KHZ(freq);
11123 connect.channel_hint = nl80211_get_valid_chan(wiphy, freq);
664834de 11124 if (!connect.channel_hint)
4c476991 11125 return -EINVAL;
b23aa676
SO
11126 }
11127
2a38075c
AAL
11128 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
11129 connect.edmg.channels =
11130 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
11131
11132 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
11133 connect.edmg.bw_config =
11134 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
11135 }
11136
fffd0934 11137 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
768075eb 11138 connkeys = nl80211_parse_connkeys(rdev, info, NULL);
4c476991
JB
11139 if (IS_ERR(connkeys))
11140 return PTR_ERR(connkeys);
fffd0934
JB
11141 }
11142
7e7c8926
BG
11143 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
11144 connect.flags |= ASSOC_REQ_DISABLE_HT;
11145
11146 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
11147 memcpy(&connect.ht_capa_mask,
11148 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
11149 sizeof(connect.ht_capa_mask));
11150
11151 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 11152 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
453431a5 11153 kfree_sensitive(connkeys);
7e7c8926 11154 return -EINVAL;
b4e4f47e 11155 }
7e7c8926
BG
11156 memcpy(&connect.ht_capa,
11157 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
11158 sizeof(connect.ht_capa));
11159 }
11160
ee2aca34
JB
11161 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
11162 connect.flags |= ASSOC_REQ_DISABLE_VHT;
11163
b6db0f89
BG
11164 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
11165 connect.flags |= ASSOC_REQ_DISABLE_HE;
11166
ee2aca34
JB
11167 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
11168 memcpy(&connect.vht_capa_mask,
11169 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
11170 sizeof(connect.vht_capa_mask));
11171
11172 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
11173 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
453431a5 11174 kfree_sensitive(connkeys);
ee2aca34
JB
11175 return -EINVAL;
11176 }
11177 memcpy(&connect.vht_capa,
11178 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
11179 sizeof(connect.vht_capa));
11180 }
11181
bab5ab7d 11182 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
11183 if (!((rdev->wiphy.features &
11184 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
11185 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
11186 !wiphy_ext_feature_isset(&rdev->wiphy,
11187 NL80211_EXT_FEATURE_RRM)) {
453431a5 11188 kfree_sensitive(connkeys);
bab5ab7d 11189 return -EINVAL;
707554b4 11190 }
bab5ab7d
AK
11191 connect.flags |= ASSOC_REQ_USE_RRM;
11192 }
11193
34d50519 11194 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 11195 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
453431a5 11196 kfree_sensitive(connkeys);
34d50519
LD
11197 return -EOPNOTSUPP;
11198 }
11199
38de03d2
AS
11200 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
11201 /* bss selection makes no sense if bssid is set */
11202 if (connect.bssid) {
453431a5 11203 kfree_sensitive(connkeys);
38de03d2
AS
11204 return -EINVAL;
11205 }
11206
11207 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
11208 wiphy, &connect.bss_select);
11209 if (err) {
453431a5 11210 kfree_sensitive(connkeys);
38de03d2
AS
11211 return err;
11212 }
11213 }
11214
a3caf744
VK
11215 if (wiphy_ext_feature_isset(&rdev->wiphy,
11216 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
11217 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
11218 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
11219 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
11220 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
11221 connect.fils_erp_username =
11222 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
11223 connect.fils_erp_username_len =
11224 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
11225 connect.fils_erp_realm =
11226 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
11227 connect.fils_erp_realm_len =
11228 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
11229 connect.fils_erp_next_seq_num =
11230 nla_get_u16(
11231 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
11232 connect.fils_erp_rrk =
11233 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
11234 connect.fils_erp_rrk_len =
11235 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
11236 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
11237 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
11238 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
11239 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
453431a5 11240 kfree_sensitive(connkeys);
a3caf744
VK
11241 return -EINVAL;
11242 }
11243
40cbfa90
SD
11244 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
11245 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
453431a5 11246 kfree_sensitive(connkeys);
40cbfa90
SD
11247 GENL_SET_ERR_MSG(info,
11248 "external auth requires connection ownership");
11249 return -EINVAL;
11250 }
11251 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
11252 }
11253
83739b03 11254 wdev_lock(dev->ieee80211_ptr);
bd2522b1 11255
4ce2bd9c
JM
11256 err = cfg80211_connect(rdev, dev, &connect, connkeys,
11257 connect.prev_bssid);
fffd0934 11258 if (err)
453431a5 11259 kfree_sensitive(connkeys);
bd2522b1
AZ
11260
11261 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
11262 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
11263 if (connect.bssid)
11264 memcpy(dev->ieee80211_ptr->disconnect_bssid,
11265 connect.bssid, ETH_ALEN);
11266 else
3b1648f1 11267 eth_zero_addr(dev->ieee80211_ptr->disconnect_bssid);
bd2522b1
AZ
11268 }
11269
11270 wdev_unlock(dev->ieee80211_ptr);
11271
b23aa676
SO
11272 return err;
11273}
11274
088e8df8 11275static int nl80211_update_connect_params(struct sk_buff *skb,
11276 struct genl_info *info)
11277{
11278 struct cfg80211_connect_params connect = {};
11279 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11280 struct net_device *dev = info->user_ptr[1];
11281 struct wireless_dev *wdev = dev->ieee80211_ptr;
7f9a3e15
VK
11282 bool fils_sk_offload;
11283 u32 auth_type;
088e8df8 11284 u32 changed = 0;
11285 int ret;
11286
11287 if (!rdev->ops->update_connect_params)
11288 return -EOPNOTSUPP;
11289
11290 if (info->attrs[NL80211_ATTR_IE]) {
088e8df8 11291 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11292 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11293 changed |= UPDATE_ASSOC_IES;
11294 }
11295
7f9a3e15
VK
11296 fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
11297 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
11298
11299 /*
11300 * when driver supports fils-sk offload all attributes must be
11301 * provided. So the else covers "fils-sk-not-all" and
11302 * "no-fils-sk-any".
11303 */
11304 if (fils_sk_offload &&
11305 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
11306 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
11307 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
11308 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
11309 connect.fils_erp_username =
11310 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
11311 connect.fils_erp_username_len =
11312 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
11313 connect.fils_erp_realm =
11314 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
11315 connect.fils_erp_realm_len =
11316 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
11317 connect.fils_erp_next_seq_num =
11318 nla_get_u16(
11319 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
11320 connect.fils_erp_rrk =
11321 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
11322 connect.fils_erp_rrk_len =
11323 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
11324 changed |= UPDATE_FILS_ERP_INFO;
11325 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
11326 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
11327 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
11328 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
11329 return -EINVAL;
11330 }
11331
11332 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
11333 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
11334 if (!nl80211_valid_auth_type(rdev, auth_type,
11335 NL80211_CMD_CONNECT))
11336 return -EINVAL;
11337
11338 if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
11339 fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
11340 return -EINVAL;
11341
11342 connect.auth_type = auth_type;
11343 changed |= UPDATE_AUTH_TYPE;
11344 }
11345
088e8df8 11346 wdev_lock(dev->ieee80211_ptr);
11347 if (!wdev->current_bss)
11348 ret = -ENOLINK;
11349 else
11350 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
11351 wdev_unlock(dev->ieee80211_ptr);
11352
11353 return ret;
11354}
11355
b23aa676
SO
11356static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
11357{
4c476991
JB
11358 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11359 struct net_device *dev = info->user_ptr[1];
b23aa676 11360 u16 reason;
83739b03 11361 int ret;
b23aa676 11362
bad29297
AZ
11363 if (dev->ieee80211_ptr->conn_owner_nlportid &&
11364 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
11365 return -EPERM;
11366
b23aa676
SO
11367 if (!info->attrs[NL80211_ATTR_REASON_CODE])
11368 reason = WLAN_REASON_DEAUTH_LEAVING;
11369 else
11370 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
11371
11372 if (reason == 0)
11373 return -EINVAL;
11374
074ac8df 11375 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11376 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11377 return -EOPNOTSUPP;
b23aa676 11378
83739b03
JB
11379 wdev_lock(dev->ieee80211_ptr);
11380 ret = cfg80211_disconnect(rdev, dev, reason, true);
11381 wdev_unlock(dev->ieee80211_ptr);
11382 return ret;
b23aa676
SO
11383}
11384
463d0183
JB
11385static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
11386{
4c476991 11387 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
11388 struct net *net;
11389 int err;
463d0183 11390
4b681c82
VK
11391 if (info->attrs[NL80211_ATTR_PID]) {
11392 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
11393
11394 net = get_net_ns_by_pid(pid);
11395 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
11396 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 11397
4b681c82
VK
11398 net = get_net_ns_by_fd(fd);
11399 } else {
11400 return -EINVAL;
11401 }
463d0183 11402
4c476991
JB
11403 if (IS_ERR(net))
11404 return PTR_ERR(net);
463d0183
JB
11405
11406 err = 0;
11407
11408 /* check if anything to do */
4c476991
JB
11409 if (!net_eq(wiphy_net(&rdev->wiphy), net))
11410 err = cfg80211_switch_netns(rdev, net);
463d0183 11411
463d0183 11412 put_net(net);
463d0183
JB
11413 return err;
11414}
11415
67fbb16b
SO
11416static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
11417{
4c476991 11418 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
11419 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
11420 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 11421 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
11422 struct cfg80211_pmksa pmksa;
11423
11424 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
11425
67fbb16b
SO
11426 if (!info->attrs[NL80211_ATTR_PMKID])
11427 return -EINVAL;
11428
67fbb16b 11429 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
a3caf744
VK
11430
11431 if (info->attrs[NL80211_ATTR_MAC]) {
11432 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
11433 } else if (info->attrs[NL80211_ATTR_SSID] &&
11434 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
11435 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
11436 info->attrs[NL80211_ATTR_PMK])) {
11437 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
11438 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
11439 pmksa.cache_id =
11440 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
11441 } else {
11442 return -EINVAL;
11443 }
11444 if (info->attrs[NL80211_ATTR_PMK]) {
11445 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
11446 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
11447 }
67fbb16b 11448
7fc82af8
VJ
11449 if (info->attrs[NL80211_ATTR_PMK_LIFETIME])
11450 pmksa.pmk_lifetime =
11451 nla_get_u32(info->attrs[NL80211_ATTR_PMK_LIFETIME]);
11452
11453 if (info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD])
11454 pmksa.pmk_reauth_threshold =
11455 nla_get_u8(
11456 info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD]);
11457
074ac8df 11458 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
6c900360
LD
11459 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
11460 !(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP &&
11461 wiphy_ext_feature_isset(&rdev->wiphy,
11462 NL80211_EXT_FEATURE_AP_PMKSA_CACHING)))
4c476991 11463 return -EOPNOTSUPP;
67fbb16b
SO
11464
11465 switch (info->genlhdr->cmd) {
11466 case NL80211_CMD_SET_PMKSA:
11467 rdev_ops = rdev->ops->set_pmksa;
11468 break;
11469 case NL80211_CMD_DEL_PMKSA:
11470 rdev_ops = rdev->ops->del_pmksa;
11471 break;
11472 default:
11473 WARN_ON(1);
11474 break;
11475 }
11476
4c476991
JB
11477 if (!rdev_ops)
11478 return -EOPNOTSUPP;
67fbb16b 11479
4c476991 11480 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
11481}
11482
11483static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
11484{
4c476991
JB
11485 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11486 struct net_device *dev = info->user_ptr[1];
67fbb16b 11487
074ac8df 11488 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11489 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11490 return -EOPNOTSUPP;
67fbb16b 11491
4c476991
JB
11492 if (!rdev->ops->flush_pmksa)
11493 return -EOPNOTSUPP;
67fbb16b 11494
e35e4d28 11495 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
11496}
11497
109086ce
AN
11498static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
11499{
11500 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11501 struct net_device *dev = info->user_ptr[1];
11502 u8 action_code, dialog_token;
df942e7b 11503 u32 peer_capability = 0;
109086ce
AN
11504 u16 status_code;
11505 u8 *peer;
31fa97c5 11506 bool initiator;
109086ce
AN
11507
11508 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
11509 !rdev->ops->tdls_mgmt)
11510 return -EOPNOTSUPP;
11511
11512 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
11513 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
11514 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
11515 !info->attrs[NL80211_ATTR_IE] ||
11516 !info->attrs[NL80211_ATTR_MAC])
11517 return -EINVAL;
11518
11519 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11520 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
11521 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
11522 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 11523 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
11524 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
11525 peer_capability =
11526 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 11527
e35e4d28 11528 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 11529 dialog_token, status_code, peer_capability,
31fa97c5 11530 initiator,
e35e4d28
HG
11531 nla_data(info->attrs[NL80211_ATTR_IE]),
11532 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
11533}
11534
11535static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
11536{
11537 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11538 struct net_device *dev = info->user_ptr[1];
11539 enum nl80211_tdls_operation operation;
11540 u8 *peer;
11541
11542 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
11543 !rdev->ops->tdls_oper)
11544 return -EOPNOTSUPP;
11545
11546 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
11547 !info->attrs[NL80211_ATTR_MAC])
11548 return -EINVAL;
11549
11550 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
11551 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11552
e35e4d28 11553 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
11554}
11555
9588bbd5
JM
11556static int nl80211_remain_on_channel(struct sk_buff *skb,
11557 struct genl_info *info)
11558{
4c476991 11559 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11560 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 11561 struct cfg80211_chan_def chandef;
34373d12 11562 const struct cfg80211_chan_def *compat_chandef;
9588bbd5
JM
11563 struct sk_buff *msg;
11564 void *hdr;
11565 u64 cookie;
683b6d3b 11566 u32 duration;
9588bbd5
JM
11567 int err;
11568
11569 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
11570 !info->attrs[NL80211_ATTR_DURATION])
11571 return -EINVAL;
11572
11573 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
11574
ebf348fc
JB
11575 if (!rdev->ops->remain_on_channel ||
11576 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
11577 return -EOPNOTSUPP;
11578
9588bbd5 11579 /*
ebf348fc
JB
11580 * We should be on that channel for at least a minimum amount of
11581 * time (10ms) but no longer than the driver supports.
9588bbd5 11582 */
ebf348fc 11583 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 11584 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
11585 return -EINVAL;
11586
683b6d3b
JB
11587 err = nl80211_parse_chandef(rdev, info, &chandef);
11588 if (err)
11589 return err;
9588bbd5 11590
34373d12
VT
11591 wdev_lock(wdev);
11592 if (!cfg80211_off_channel_oper_allowed(wdev) &&
11593 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
11594 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
11595 &chandef);
11596 if (compat_chandef != &chandef) {
11597 wdev_unlock(wdev);
11598 return -EBUSY;
11599 }
11600 }
11601 wdev_unlock(wdev);
11602
9588bbd5 11603 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
11604 if (!msg)
11605 return -ENOMEM;
9588bbd5 11606
15e47304 11607 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 11608 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
11609 if (!hdr) {
11610 err = -ENOBUFS;
9588bbd5
JM
11611 goto free_msg;
11612 }
11613
683b6d3b
JB
11614 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
11615 duration, &cookie);
9588bbd5
JM
11616
11617 if (err)
11618 goto free_msg;
11619
2dad624e
ND
11620 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11621 NL80211_ATTR_PAD))
9360ffd1 11622 goto nla_put_failure;
9588bbd5
JM
11623
11624 genlmsg_end(msg, hdr);
4c476991
JB
11625
11626 return genlmsg_reply(msg, info);
9588bbd5
JM
11627
11628 nla_put_failure:
11629 err = -ENOBUFS;
11630 free_msg:
11631 nlmsg_free(msg);
9588bbd5
JM
11632 return err;
11633}
11634
11635static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
11636 struct genl_info *info)
11637{
4c476991 11638 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11639 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 11640 u64 cookie;
9588bbd5
JM
11641
11642 if (!info->attrs[NL80211_ATTR_COOKIE])
11643 return -EINVAL;
11644
4c476991
JB
11645 if (!rdev->ops->cancel_remain_on_channel)
11646 return -EOPNOTSUPP;
9588bbd5 11647
9588bbd5
JM
11648 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11649
e35e4d28 11650 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
11651}
11652
13ae75b1
JM
11653static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
11654 struct genl_info *info)
11655{
13ae75b1 11656 struct cfg80211_bitrate_mask mask;
a7c7fbff 11657 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 11658 struct net_device *dev = info->user_ptr[1];
a7c7fbff 11659 int err;
13ae75b1 11660
4c476991
JB
11661 if (!rdev->ops->set_bitrate_mask)
11662 return -EOPNOTSUPP;
13ae75b1 11663
9a5f6488 11664 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
eb89a6a6 11665 NL80211_ATTR_TX_RATES, &mask,
857b34c4 11666 dev, true);
a7c7fbff
PK
11667 if (err)
11668 return err;
13ae75b1 11669
e35e4d28 11670 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
11671}
11672
2e161f78 11673static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 11674{
4c476991 11675 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11676 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 11677 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
11678
11679 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
11680 return -EINVAL;
11681
2e161f78
JB
11682 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
11683 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 11684
71bbc994
JB
11685 switch (wdev->iftype) {
11686 case NL80211_IFTYPE_STATION:
11687 case NL80211_IFTYPE_ADHOC:
11688 case NL80211_IFTYPE_P2P_CLIENT:
11689 case NL80211_IFTYPE_AP:
11690 case NL80211_IFTYPE_AP_VLAN:
11691 case NL80211_IFTYPE_MESH_POINT:
11692 case NL80211_IFTYPE_P2P_GO:
98104fde 11693 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 11694 break;
cb3b7d87 11695 case NL80211_IFTYPE_NAN:
71bbc994 11696 default:
4c476991 11697 return -EOPNOTSUPP;
71bbc994 11698 }
026331c4
JM
11699
11700 /* not much point in registering if we can't reply */
4c476991
JB
11701 if (!rdev->ops->mgmt_tx)
11702 return -EOPNOTSUPP;
026331c4 11703
9dba48a6
JB
11704 if (info->attrs[NL80211_ATTR_RECEIVE_MULTICAST] &&
11705 !wiphy_ext_feature_isset(&rdev->wiphy,
11706 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS)) {
11707 GENL_SET_ERR_MSG(info,
11708 "multicast RX registrations are not supported");
11709 return -EOPNOTSUPP;
11710 }
11711
15e47304 11712 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
ff74c51e
IP
11713 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
11714 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]),
9dba48a6 11715 info->attrs[NL80211_ATTR_RECEIVE_MULTICAST],
ff74c51e 11716 info->extack);
026331c4
JM
11717}
11718
2e161f78 11719static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 11720{
4c476991 11721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11722 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 11723 struct cfg80211_chan_def chandef;
026331c4 11724 int err;
d64d373f 11725 void *hdr = NULL;
026331c4 11726 u64 cookie;
e247bd90 11727 struct sk_buff *msg = NULL;
b176e629
AO
11728 struct cfg80211_mgmt_tx_params params = {
11729 .dont_wait_for_ack =
11730 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
11731 };
026331c4 11732
683b6d3b 11733 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
11734 return -EINVAL;
11735
4c476991
JB
11736 if (!rdev->ops->mgmt_tx)
11737 return -EOPNOTSUPP;
026331c4 11738
71bbc994 11739 switch (wdev->iftype) {
ea141b75
AQ
11740 case NL80211_IFTYPE_P2P_DEVICE:
11741 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
11742 return -EINVAL;
d7832c71 11743 break;
71bbc994
JB
11744 case NL80211_IFTYPE_STATION:
11745 case NL80211_IFTYPE_ADHOC:
11746 case NL80211_IFTYPE_P2P_CLIENT:
11747 case NL80211_IFTYPE_AP:
11748 case NL80211_IFTYPE_AP_VLAN:
11749 case NL80211_IFTYPE_MESH_POINT:
11750 case NL80211_IFTYPE_P2P_GO:
11751 break;
cb3b7d87 11752 case NL80211_IFTYPE_NAN:
71bbc994 11753 default:
4c476991 11754 return -EOPNOTSUPP;
71bbc994 11755 }
026331c4 11756
f7ca38df 11757 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 11758 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 11759 return -EINVAL;
b176e629 11760 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
11761
11762 /*
11763 * We should wait on the channel for at least a minimum amount
11764 * of time (10ms) but no longer than the driver supports.
11765 */
b176e629
AO
11766 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
11767 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 11768 return -EINVAL;
f7ca38df
JB
11769 }
11770
b176e629 11771 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 11772
b176e629 11773 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
11774 return -EINVAL;
11775
b176e629 11776 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 11777
ea141b75
AQ
11778 /* get the channel if any has been specified, otherwise pass NULL to
11779 * the driver. The latter will use the current one
11780 */
11781 chandef.chan = NULL;
11782 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
11783 err = nl80211_parse_chandef(rdev, info, &chandef);
11784 if (err)
11785 return err;
11786 }
11787
b176e629 11788 if (!chandef.chan && params.offchan)
ea141b75 11789 return -EINVAL;
026331c4 11790
34373d12
VT
11791 wdev_lock(wdev);
11792 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
11793 wdev_unlock(wdev);
11794 return -EBUSY;
11795 }
11796 wdev_unlock(wdev);
11797
34d22ce2
AO
11798 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
11799 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
11800
11801 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
11802 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
11803 int i;
11804
11805 if (len % sizeof(u16))
11806 return -EINVAL;
11807
11808 params.n_csa_offsets = len / sizeof(u16);
11809 params.csa_offsets =
11810 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
11811
11812 /* check that all the offsets fit the frame */
11813 for (i = 0; i < params.n_csa_offsets; i++) {
11814 if (params.csa_offsets[i] >= params.len)
11815 return -EINVAL;
11816 }
11817 }
11818
b176e629 11819 if (!params.dont_wait_for_ack) {
e247bd90
JB
11820 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11821 if (!msg)
11822 return -ENOMEM;
026331c4 11823
15e47304 11824 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 11825 NL80211_CMD_FRAME);
cb35fba3
DC
11826 if (!hdr) {
11827 err = -ENOBUFS;
e247bd90
JB
11828 goto free_msg;
11829 }
026331c4 11830 }
e247bd90 11831
b176e629
AO
11832 params.chan = chandef.chan;
11833 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
11834 if (err)
11835 goto free_msg;
11836
e247bd90 11837 if (msg) {
2dad624e
ND
11838 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11839 NL80211_ATTR_PAD))
9360ffd1 11840 goto nla_put_failure;
026331c4 11841
e247bd90
JB
11842 genlmsg_end(msg, hdr);
11843 return genlmsg_reply(msg, info);
11844 }
11845
11846 return 0;
026331c4
JM
11847
11848 nla_put_failure:
11849 err = -ENOBUFS;
11850 free_msg:
11851 nlmsg_free(msg);
026331c4
JM
11852 return err;
11853}
11854
f7ca38df
JB
11855static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
11856{
11857 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11858 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
11859 u64 cookie;
11860
11861 if (!info->attrs[NL80211_ATTR_COOKIE])
11862 return -EINVAL;
11863
11864 if (!rdev->ops->mgmt_tx_cancel_wait)
11865 return -EOPNOTSUPP;
11866
71bbc994
JB
11867 switch (wdev->iftype) {
11868 case NL80211_IFTYPE_STATION:
11869 case NL80211_IFTYPE_ADHOC:
11870 case NL80211_IFTYPE_P2P_CLIENT:
11871 case NL80211_IFTYPE_AP:
11872 case NL80211_IFTYPE_AP_VLAN:
11873 case NL80211_IFTYPE_P2P_GO:
98104fde 11874 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 11875 break;
cb3b7d87 11876 case NL80211_IFTYPE_NAN:
71bbc994 11877 default:
f7ca38df 11878 return -EOPNOTSUPP;
71bbc994 11879 }
f7ca38df
JB
11880
11881 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11882
e35e4d28 11883 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
11884}
11885
ffb9eb3d
KV
11886static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
11887{
4c476991 11888 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 11889 struct wireless_dev *wdev;
4c476991 11890 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
11891 u8 ps_state;
11892 bool state;
11893 int err;
11894
4c476991
JB
11895 if (!info->attrs[NL80211_ATTR_PS_STATE])
11896 return -EINVAL;
ffb9eb3d
KV
11897
11898 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
11899
ffb9eb3d
KV
11900 wdev = dev->ieee80211_ptr;
11901
4c476991
JB
11902 if (!rdev->ops->set_power_mgmt)
11903 return -EOPNOTSUPP;
ffb9eb3d
KV
11904
11905 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
11906
11907 if (state == wdev->ps)
4c476991 11908 return 0;
ffb9eb3d 11909
e35e4d28 11910 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
11911 if (!err)
11912 wdev->ps = state;
ffb9eb3d
KV
11913 return err;
11914}
11915
11916static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
11917{
4c476991 11918 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
11919 enum nl80211_ps_state ps_state;
11920 struct wireless_dev *wdev;
4c476991 11921 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
11922 struct sk_buff *msg;
11923 void *hdr;
11924 int err;
11925
ffb9eb3d
KV
11926 wdev = dev->ieee80211_ptr;
11927
4c476991
JB
11928 if (!rdev->ops->set_power_mgmt)
11929 return -EOPNOTSUPP;
ffb9eb3d
KV
11930
11931 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
11932 if (!msg)
11933 return -ENOMEM;
ffb9eb3d 11934
15e47304 11935 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
11936 NL80211_CMD_GET_POWER_SAVE);
11937 if (!hdr) {
4c476991 11938 err = -ENOBUFS;
ffb9eb3d
KV
11939 goto free_msg;
11940 }
11941
11942 if (wdev->ps)
11943 ps_state = NL80211_PS_ENABLED;
11944 else
11945 ps_state = NL80211_PS_DISABLED;
11946
9360ffd1
DM
11947 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
11948 goto nla_put_failure;
ffb9eb3d
KV
11949
11950 genlmsg_end(msg, hdr);
4c476991 11951 return genlmsg_reply(msg, info);
ffb9eb3d 11952
4c476991 11953 nla_put_failure:
ffb9eb3d 11954 err = -ENOBUFS;
4c476991 11955 free_msg:
ffb9eb3d 11956 nlmsg_free(msg);
ffb9eb3d
KV
11957 return err;
11958}
11959
94e860f1
JB
11960static const struct nla_policy
11961nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
4a4b8169 11962 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
d6dc1a38
JO
11963 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
11964 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
11965 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
11966 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
11967 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
bee427b8 11968 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
d6dc1a38
JO
11969};
11970
84f10708 11971static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 11972 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
11973{
11974 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 11975 struct net_device *dev = info->user_ptr[1];
1da5fcc8 11976 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 11977
d9d8b019 11978 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
11979 return -EINVAL;
11980
84f10708
TP
11981 if (!rdev->ops->set_cqm_txe_config)
11982 return -EOPNOTSUPP;
11983
11984 if (wdev->iftype != NL80211_IFTYPE_STATION &&
11985 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
11986 return -EOPNOTSUPP;
11987
e35e4d28 11988 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
11989}
11990
4a4b8169
AZ
11991static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
11992 struct net_device *dev)
11993{
11994 struct wireless_dev *wdev = dev->ieee80211_ptr;
11995 s32 last, low, high;
11996 u32 hyst;
1222a160 11997 int i, n, low_index;
4a4b8169
AZ
11998 int err;
11999
12000 /* RSSI reporting disabled? */
12001 if (!wdev->cqm_config)
12002 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
12003
12004 /*
12005 * Obtain current RSSI value if possible, if not and no RSSI threshold
12006 * event has been received yet, we should receive an event after a
12007 * connection is established and enough beacons received to calculate
12008 * the average.
12009 */
12010 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
12011 rdev->ops->get_station) {
73887fd9 12012 struct station_info sinfo = {};
4a4b8169
AZ
12013 u8 *mac_addr;
12014
12015 mac_addr = wdev->current_bss->pub.bssid;
12016
73887fd9
JB
12017 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
12018 if (err)
4a4b8169
AZ
12019 return err;
12020
df16737d 12021 cfg80211_sinfo_release_content(&sinfo);
397c657a 12022 if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
4a4b8169 12023 wdev->cqm_config->last_rssi_event_value =
73887fd9 12024 (s8) sinfo.rx_beacon_signal_avg;
4a4b8169
AZ
12025 }
12026
12027 last = wdev->cqm_config->last_rssi_event_value;
12028 hyst = wdev->cqm_config->rssi_hyst;
12029 n = wdev->cqm_config->n_rssi_thresholds;
12030
4b2c5a14
MH
12031 for (i = 0; i < n; i++) {
12032 i = array_index_nospec(i, n);
4a4b8169
AZ
12033 if (last < wdev->cqm_config->rssi_thresholds[i])
12034 break;
4b2c5a14 12035 }
4a4b8169 12036
1222a160
MH
12037 low_index = i - 1;
12038 if (low_index >= 0) {
12039 low_index = array_index_nospec(low_index, n);
12040 low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
12041 } else {
12042 low = S32_MIN;
12043 }
12044 if (i < n) {
12045 i = array_index_nospec(i, n);
12046 high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
12047 } else {
12048 high = S32_MAX;
12049 }
4a4b8169
AZ
12050
12051 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
12052}
12053
d6dc1a38 12054static int nl80211_set_cqm_rssi(struct genl_info *info,
4a4b8169
AZ
12055 const s32 *thresholds, int n_thresholds,
12056 u32 hysteresis)
d6dc1a38 12057{
4c476991 12058 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 12059 struct net_device *dev = info->user_ptr[1];
1da5fcc8 12060 struct wireless_dev *wdev = dev->ieee80211_ptr;
4a4b8169
AZ
12061 int i, err;
12062 s32 prev = S32_MIN;
d6dc1a38 12063
4a4b8169
AZ
12064 /* Check all values negative and sorted */
12065 for (i = 0; i < n_thresholds; i++) {
12066 if (thresholds[i] > 0 || thresholds[i] <= prev)
12067 return -EINVAL;
d6dc1a38 12068
4a4b8169
AZ
12069 prev = thresholds[i];
12070 }
d6dc1a38 12071
074ac8df 12072 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
12073 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
12074 return -EOPNOTSUPP;
d6dc1a38 12075
4a4b8169
AZ
12076 wdev_lock(wdev);
12077 cfg80211_cqm_config_free(wdev);
12078 wdev_unlock(wdev);
12079
12080 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
12081 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
12082 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
12083
12084 return rdev_set_cqm_rssi_config(rdev, dev,
12085 thresholds[0], hysteresis);
12086 }
12087
12088 if (!wiphy_ext_feature_isset(&rdev->wiphy,
12089 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
12090 return -EOPNOTSUPP;
12091
12092 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
12093 n_thresholds = 0;
12094
12095 wdev_lock(wdev);
12096 if (n_thresholds) {
12097 struct cfg80211_cqm_config *cqm_config;
12098
40f231e7
LB
12099 cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds,
12100 n_thresholds),
12101 GFP_KERNEL);
4a4b8169
AZ
12102 if (!cqm_config) {
12103 err = -ENOMEM;
12104 goto unlock;
12105 }
12106
12107 cqm_config->rssi_hyst = hysteresis;
12108 cqm_config->n_rssi_thresholds = n_thresholds;
12109 memcpy(cqm_config->rssi_thresholds, thresholds,
40f231e7
LB
12110 flex_array_size(cqm_config, rssi_thresholds,
12111 n_thresholds));
4a4b8169
AZ
12112
12113 wdev->cqm_config = cqm_config;
12114 }
12115
12116 err = cfg80211_cqm_rssi_update(rdev, dev);
12117
12118unlock:
12119 wdev_unlock(wdev);
12120
12121 return err;
d6dc1a38
JO
12122}
12123
12124static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
12125{
12126 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
12127 struct nlattr *cqm;
12128 int err;
12129
12130 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
12131 if (!cqm)
12132 return -EINVAL;
d6dc1a38 12133
8cb08174
JB
12134 err = nla_parse_nested_deprecated(attrs, NL80211_ATTR_CQM_MAX, cqm,
12135 nl80211_attr_cqm_policy,
12136 info->extack);
d6dc1a38 12137 if (err)
1da5fcc8 12138 return err;
d6dc1a38
JO
12139
12140 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
12141 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4a4b8169
AZ
12142 const s32 *thresholds =
12143 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
12144 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
1da5fcc8 12145 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 12146
4a4b8169
AZ
12147 if (len % 4)
12148 return -EINVAL;
12149
12150 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
12151 hysteresis);
1da5fcc8
JB
12152 }
12153
12154 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
12155 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
12156 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
12157 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
12158 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
12159 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
12160
12161 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
12162 }
12163
12164 return -EINVAL;
d6dc1a38
JO
12165}
12166
6e0bd6c3
RL
12167static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
12168{
12169 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12170 struct net_device *dev = info->user_ptr[1];
12171 struct ocb_setup setup = {};
12172 int err;
12173
12174 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
12175 if (err)
12176 return err;
12177
12178 return cfg80211_join_ocb(rdev, dev, &setup);
12179}
12180
12181static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
12182{
12183 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12184 struct net_device *dev = info->user_ptr[1];
12185
12186 return cfg80211_leave_ocb(rdev, dev);
12187}
12188
29cbe68c
JB
12189static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
12190{
12191 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12192 struct net_device *dev = info->user_ptr[1];
12193 struct mesh_config cfg;
c80d545d 12194 struct mesh_setup setup;
29cbe68c
JB
12195 int err;
12196
12197 /* start with default */
12198 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 12199 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 12200
24bdd9f4 12201 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 12202 /* and parse parameters if given */
24bdd9f4 12203 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
12204 if (err)
12205 return err;
12206 }
12207
12208 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
12209 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
12210 return -EINVAL;
12211
c80d545d
JC
12212 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
12213 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
12214
4bb62344
CYY
12215 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
12216 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
12217 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
12218 return -EINVAL;
12219
9bdbf04d
MP
12220 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
12221 setup.beacon_interval =
12222 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 12223
0c317a02
PK
12224 err = cfg80211_validate_beacon_int(rdev,
12225 NL80211_IFTYPE_MESH_POINT,
12226 setup.beacon_interval);
12d20fc9
PK
12227 if (err)
12228 return err;
9bdbf04d
MP
12229 }
12230
12231 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
12232 setup.dtim_period =
12233 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
12234 if (setup.dtim_period < 1 || setup.dtim_period > 100)
12235 return -EINVAL;
12236 }
12237
c80d545d
JC
12238 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
12239 /* parse additional setup parameters if given */
12240 err = nl80211_parse_mesh_setup(info, &setup);
12241 if (err)
12242 return err;
12243 }
12244
d37bb18a
TP
12245 if (setup.user_mpm)
12246 cfg.auto_open_plinks = false;
12247
cc1d2806 12248 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
12249 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
12250 if (err)
12251 return err;
cc1d2806 12252 } else {
188c1b3c 12253 /* __cfg80211_join_mesh() will sort it out */
683b6d3b 12254 setup.chandef.chan = NULL;
cc1d2806
JB
12255 }
12256
ffb3cf30
AN
12257 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
12258 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
12259 int n_rates =
12260 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
12261 struct ieee80211_supported_band *sband;
12262
12263 if (!setup.chandef.chan)
12264 return -EINVAL;
12265
12266 sband = rdev->wiphy.bands[setup.chandef.chan->band];
12267
12268 err = ieee80211_get_ratemask(sband, rates, n_rates,
12269 &setup.basic_rates);
12270 if (err)
12271 return err;
12272 }
12273
8564e382 12274 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9a5f6488
TC
12275 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
12276 NL80211_ATTR_TX_RATES,
eb89a6a6 12277 &setup.beacon_rate,
857b34c4 12278 dev, false);
8564e382
JB
12279 if (err)
12280 return err;
12281
265698d7
JB
12282 if (!setup.chandef.chan)
12283 return -EINVAL;
12284
8564e382
JB
12285 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
12286 &setup.beacon_rate);
12287 if (err)
12288 return err;
12289 }
12290
d37d49c2
BB
12291 setup.userspace_handles_dfs =
12292 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
12293
1224f583
DK
12294 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
12295 int r = validate_pae_over_nl80211(rdev, info);
12296
12297 if (r < 0)
12298 return r;
12299
12300 setup.control_port_over_nl80211 = true;
12301 }
12302
188c1b3c
DK
12303 wdev_lock(dev->ieee80211_ptr);
12304 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
12305 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
12306 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
12307 wdev_unlock(dev->ieee80211_ptr);
12308
12309 return err;
29cbe68c
JB
12310}
12311
12312static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
12313{
12314 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12315 struct net_device *dev = info->user_ptr[1];
12316
12317 return cfg80211_leave_mesh(rdev, dev);
12318}
12319
dfb89c56 12320#ifdef CONFIG_PM
bb92d199
AK
12321static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
12322 struct cfg80211_registered_device *rdev)
12323{
6abb9cb9 12324 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
12325 struct nlattr *nl_pats, *nl_pat;
12326 int i, pat_len;
12327
6abb9cb9 12328 if (!wowlan->n_patterns)
bb92d199
AK
12329 return 0;
12330
ae0be8de 12331 nl_pats = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
bb92d199
AK
12332 if (!nl_pats)
12333 return -ENOBUFS;
12334
6abb9cb9 12335 for (i = 0; i < wowlan->n_patterns; i++) {
ae0be8de 12336 nl_pat = nla_nest_start_noflag(msg, i + 1);
bb92d199
AK
12337 if (!nl_pat)
12338 return -ENOBUFS;
6abb9cb9 12339 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 12340 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 12341 wowlan->patterns[i].mask) ||
50ac6607
AK
12342 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
12343 wowlan->patterns[i].pattern) ||
12344 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 12345 wowlan->patterns[i].pkt_offset))
bb92d199
AK
12346 return -ENOBUFS;
12347 nla_nest_end(msg, nl_pat);
12348 }
12349 nla_nest_end(msg, nl_pats);
12350
12351 return 0;
12352}
12353
2a0e047e
JB
12354static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
12355 struct cfg80211_wowlan_tcp *tcp)
12356{
12357 struct nlattr *nl_tcp;
12358
12359 if (!tcp)
12360 return 0;
12361
ae0be8de
MK
12362 nl_tcp = nla_nest_start_noflag(msg,
12363 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
2a0e047e
JB
12364 if (!nl_tcp)
12365 return -ENOBUFS;
12366
930345ea
JB
12367 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
12368 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
12369 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
12370 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
12371 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
12372 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
12373 tcp->payload_len, tcp->payload) ||
12374 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
12375 tcp->data_interval) ||
12376 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
12377 tcp->wake_len, tcp->wake_data) ||
12378 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
12379 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
12380 return -ENOBUFS;
12381
12382 if (tcp->payload_seq.len &&
12383 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
12384 sizeof(tcp->payload_seq), &tcp->payload_seq))
12385 return -ENOBUFS;
12386
12387 if (tcp->payload_tok.len &&
12388 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
12389 sizeof(tcp->payload_tok) + tcp->tokens_size,
12390 &tcp->payload_tok))
12391 return -ENOBUFS;
12392
e248ad30
JB
12393 nla_nest_end(msg, nl_tcp);
12394
2a0e047e
JB
12395 return 0;
12396}
12397
75453ccb
LC
12398static int nl80211_send_wowlan_nd(struct sk_buff *msg,
12399 struct cfg80211_sched_scan_request *req)
12400{
3b06d277 12401 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
12402 int i;
12403
12404 if (!req)
12405 return 0;
12406
ae0be8de 12407 nd = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
75453ccb
LC
12408 if (!nd)
12409 return -ENOBUFS;
12410
3b06d277
AS
12411 if (req->n_scan_plans == 1 &&
12412 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
12413 req->scan_plans[0].interval * 1000))
75453ccb
LC
12414 return -ENOBUFS;
12415
21fea567
LC
12416 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
12417 return -ENOBUFS;
12418
bf95ecdb 12419 if (req->relative_rssi_set) {
12420 struct nl80211_bss_select_rssi_adjust rssi_adjust;
12421
12422 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
12423 req->relative_rssi))
12424 return -ENOBUFS;
12425
12426 rssi_adjust.band = req->rssi_adjust.band;
12427 rssi_adjust.delta = req->rssi_adjust.delta;
12428 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
12429 sizeof(rssi_adjust), &rssi_adjust))
12430 return -ENOBUFS;
12431 }
12432
ae0be8de 12433 freqs = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
75453ccb
LC
12434 if (!freqs)
12435 return -ENOBUFS;
12436
53b18980
JB
12437 for (i = 0; i < req->n_channels; i++) {
12438 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
12439 return -ENOBUFS;
12440 }
75453ccb
LC
12441
12442 nla_nest_end(msg, freqs);
12443
12444 if (req->n_match_sets) {
ae0be8de
MK
12445 matches = nla_nest_start_noflag(msg,
12446 NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
12447 if (!matches)
12448 return -ENOBUFS;
12449
75453ccb 12450 for (i = 0; i < req->n_match_sets; i++) {
ae0be8de 12451 match = nla_nest_start_noflag(msg, i);
76e1fb4b
JB
12452 if (!match)
12453 return -ENOBUFS;
12454
53b18980
JB
12455 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
12456 req->match_sets[i].ssid.ssid_len,
12457 req->match_sets[i].ssid.ssid))
12458 return -ENOBUFS;
75453ccb
LC
12459 nla_nest_end(msg, match);
12460 }
12461 nla_nest_end(msg, matches);
12462 }
12463
ae0be8de 12464 scan_plans = nla_nest_start_noflag(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
3b06d277
AS
12465 if (!scan_plans)
12466 return -ENOBUFS;
12467
12468 for (i = 0; i < req->n_scan_plans; i++) {
ae0be8de 12469 scan_plan = nla_nest_start_noflag(msg, i + 1);
76e1fb4b
JB
12470 if (!scan_plan)
12471 return -ENOBUFS;
12472
67626964 12473 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
3b06d277
AS
12474 req->scan_plans[i].interval) ||
12475 (req->scan_plans[i].iterations &&
12476 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
12477 req->scan_plans[i].iterations)))
12478 return -ENOBUFS;
12479 nla_nest_end(msg, scan_plan);
12480 }
12481 nla_nest_end(msg, scan_plans);
12482
75453ccb
LC
12483 nla_nest_end(msg, nd);
12484
12485 return 0;
12486}
12487
ff1b6e69
JB
12488static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
12489{
12490 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12491 struct sk_buff *msg;
12492 void *hdr;
2a0e047e 12493 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 12494
964dc9e2 12495 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
12496 return -EOPNOTSUPP;
12497
6abb9cb9 12498 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 12499 /* adjust size to have room for all the data */
6abb9cb9
JB
12500 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
12501 rdev->wiphy.wowlan_config->tcp->payload_len +
12502 rdev->wiphy.wowlan_config->tcp->wake_len +
12503 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
12504 }
12505
12506 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
12507 if (!msg)
12508 return -ENOMEM;
12509
15e47304 12510 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
12511 NL80211_CMD_GET_WOWLAN);
12512 if (!hdr)
12513 goto nla_put_failure;
12514
6abb9cb9 12515 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
12516 struct nlattr *nl_wowlan;
12517
ae0be8de
MK
12518 nl_wowlan = nla_nest_start_noflag(msg,
12519 NL80211_ATTR_WOWLAN_TRIGGERS);
ff1b6e69
JB
12520 if (!nl_wowlan)
12521 goto nla_put_failure;
12522
6abb9cb9 12523 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 12524 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 12525 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 12526 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 12527 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 12528 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 12529 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 12530 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 12531 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 12532 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 12533 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 12534 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 12535 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
12536 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
12537 goto nla_put_failure;
2a0e047e 12538
bb92d199
AK
12539 if (nl80211_send_wowlan_patterns(msg, rdev))
12540 goto nla_put_failure;
2a0e047e 12541
6abb9cb9
JB
12542 if (nl80211_send_wowlan_tcp(msg,
12543 rdev->wiphy.wowlan_config->tcp))
2a0e047e 12544 goto nla_put_failure;
75453ccb
LC
12545
12546 if (nl80211_send_wowlan_nd(
12547 msg,
12548 rdev->wiphy.wowlan_config->nd_config))
12549 goto nla_put_failure;
2a0e047e 12550
ff1b6e69
JB
12551 nla_nest_end(msg, nl_wowlan);
12552 }
12553
12554 genlmsg_end(msg, hdr);
12555 return genlmsg_reply(msg, info);
12556
12557nla_put_failure:
12558 nlmsg_free(msg);
12559 return -ENOBUFS;
12560}
12561
2a0e047e
JB
12562static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
12563 struct nlattr *attr,
12564 struct cfg80211_wowlan *trig)
12565{
12566 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
12567 struct cfg80211_wowlan_tcp *cfg;
12568 struct nl80211_wowlan_tcp_data_token *tok = NULL;
12569 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
12570 u32 size;
12571 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
12572 int err, port;
12573
964dc9e2 12574 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
12575 return -EINVAL;
12576
8cb08174
JB
12577 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TCP, attr,
12578 nl80211_wowlan_tcp_policy, NULL);
2a0e047e
JB
12579 if (err)
12580 return err;
12581
12582 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
12583 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
12584 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
12585 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
12586 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
12587 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
12588 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
12589 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
12590 return -EINVAL;
12591
12592 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 12593 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
12594 return -EINVAL;
12595
12596 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 12597 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 12598 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
12599 return -EINVAL;
12600
12601 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 12602 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
12603 return -EINVAL;
12604
12605 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
12606 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
12607 return -EINVAL;
12608
12609 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
12610 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
12611
12612 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
12613 tokens_size = tokln - sizeof(*tok);
12614
12615 if (!tok->len || tokens_size % tok->len)
12616 return -EINVAL;
964dc9e2 12617 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 12618 return -EINVAL;
964dc9e2 12619 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 12620 return -EINVAL;
964dc9e2 12621 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 12622 return -EINVAL;
964dc9e2 12623 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
12624 return -EINVAL;
12625 if (tok->offset + tok->len > data_size)
12626 return -EINVAL;
12627 }
12628
12629 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
12630 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 12631 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
12632 return -EINVAL;
12633 if (seq->len == 0 || seq->len > 4)
12634 return -EINVAL;
12635 if (seq->len + seq->offset > data_size)
12636 return -EINVAL;
12637 }
12638
12639 size = sizeof(*cfg);
12640 size += data_size;
12641 size += wake_size + wake_mask_size;
12642 size += tokens_size;
12643
12644 cfg = kzalloc(size, GFP_KERNEL);
12645 if (!cfg)
12646 return -ENOMEM;
67b61f6c
JB
12647 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
12648 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
12649 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
12650 ETH_ALEN);
12651 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
12652 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
12653 else
12654 port = 0;
12655#ifdef CONFIG_INET
12656 /* allocate a socket and port for it and use it */
12657 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
12658 IPPROTO_TCP, &cfg->sock, 1);
12659 if (err) {
12660 kfree(cfg);
12661 return err;
12662 }
12663 if (inet_csk_get_port(cfg->sock->sk, port)) {
12664 sock_release(cfg->sock);
12665 kfree(cfg);
12666 return -EADDRINUSE;
12667 }
12668 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
12669#else
12670 if (!port) {
12671 kfree(cfg);
12672 return -EINVAL;
12673 }
12674 cfg->src_port = port;
12675#endif
12676
12677 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
12678 cfg->payload_len = data_size;
12679 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
12680 memcpy((void *)cfg->payload,
12681 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
12682 data_size);
12683 if (seq)
12684 cfg->payload_seq = *seq;
12685 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
12686 cfg->wake_len = wake_size;
12687 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
12688 memcpy((void *)cfg->wake_data,
12689 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
12690 wake_size);
12691 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
12692 data_size + wake_size;
12693 memcpy((void *)cfg->wake_mask,
12694 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
12695 wake_mask_size);
12696 if (tok) {
12697 cfg->tokens_size = tokens_size;
12698 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
12699 }
12700
12701 trig->tcp = cfg;
12702
12703 return 0;
12704}
12705
8cd4d456
LC
12706static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
12707 const struct wiphy_wowlan_support *wowlan,
12708 struct nlattr *attr,
12709 struct cfg80211_wowlan *trig)
12710{
12711 struct nlattr **tb;
12712 int err;
12713
6396bb22 12714 tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
8cd4d456
LC
12715 if (!tb)
12716 return -ENOMEM;
12717
12718 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
12719 err = -EOPNOTSUPP;
12720 goto out;
12721 }
12722
8cb08174
JB
12723 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_MAX, attr,
12724 nl80211_policy, NULL);
8cd4d456
LC
12725 if (err)
12726 goto out;
12727
aad1e812
AVS
12728 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
12729 wowlan->max_nd_match_sets);
8cd4d456
LC
12730 err = PTR_ERR_OR_ZERO(trig->nd_config);
12731 if (err)
12732 trig->nd_config = NULL;
12733
12734out:
12735 kfree(tb);
12736 return err;
12737}
12738
ff1b6e69
JB
12739static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
12740{
12741 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12742 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 12743 struct cfg80211_wowlan new_triggers = {};
ae33bd81 12744 struct cfg80211_wowlan *ntrig;
964dc9e2 12745 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 12746 int err, i;
6abb9cb9 12747 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 12748 bool regular = false;
ff1b6e69 12749
964dc9e2 12750 if (!wowlan)
ff1b6e69
JB
12751 return -EOPNOTSUPP;
12752
ae33bd81
JB
12753 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
12754 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 12755 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
12756 goto set_wakeup;
12757 }
ff1b6e69 12758
8cb08174
JB
12759 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TRIG,
12760 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
12761 nl80211_wowlan_policy, info->extack);
ff1b6e69
JB
12762 if (err)
12763 return err;
12764
12765 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
12766 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
12767 return -EINVAL;
12768 new_triggers.any = true;
12769 }
12770
12771 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
12772 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
12773 return -EINVAL;
12774 new_triggers.disconnect = true;
98fc4386 12775 regular = true;
ff1b6e69
JB
12776 }
12777
12778 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
12779 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
12780 return -EINVAL;
12781 new_triggers.magic_pkt = true;
98fc4386 12782 regular = true;
ff1b6e69
JB
12783 }
12784
77dbbb13
JB
12785 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
12786 return -EINVAL;
12787
12788 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
12789 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
12790 return -EINVAL;
12791 new_triggers.gtk_rekey_failure = true;
98fc4386 12792 regular = true;
77dbbb13
JB
12793 }
12794
12795 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
12796 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
12797 return -EINVAL;
12798 new_triggers.eap_identity_req = true;
98fc4386 12799 regular = true;
77dbbb13
JB
12800 }
12801
12802 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
12803 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
12804 return -EINVAL;
12805 new_triggers.four_way_handshake = true;
98fc4386 12806 regular = true;
77dbbb13
JB
12807 }
12808
12809 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
12810 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
12811 return -EINVAL;
12812 new_triggers.rfkill_release = true;
98fc4386 12813 regular = true;
77dbbb13
JB
12814 }
12815
ff1b6e69
JB
12816 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
12817 struct nlattr *pat;
12818 int n_patterns = 0;
bb92d199 12819 int rem, pat_len, mask_len, pkt_offset;
50ac6607 12820 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 12821
98fc4386
JB
12822 regular = true;
12823
ff1b6e69
JB
12824 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
12825 rem)
12826 n_patterns++;
12827 if (n_patterns > wowlan->n_patterns)
12828 return -EINVAL;
12829
12830 new_triggers.patterns = kcalloc(n_patterns,
12831 sizeof(new_triggers.patterns[0]),
12832 GFP_KERNEL);
12833 if (!new_triggers.patterns)
12834 return -ENOMEM;
12835
12836 new_triggers.n_patterns = n_patterns;
12837 i = 0;
12838
12839 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
12840 rem) {
922bd80f
JB
12841 u8 *mask_pat;
12842
8cb08174
JB
12843 err = nla_parse_nested_deprecated(pat_tb,
12844 MAX_NL80211_PKTPAT,
12845 pat,
12846 nl80211_packet_pattern_policy,
12847 info->extack);
95bca62f
JB
12848 if (err)
12849 goto error;
12850
ff1b6e69 12851 err = -EINVAL;
50ac6607
AK
12852 if (!pat_tb[NL80211_PKTPAT_MASK] ||
12853 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 12854 goto error;
50ac6607 12855 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 12856 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 12857 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
12858 goto error;
12859 if (pat_len > wowlan->pattern_max_len ||
12860 pat_len < wowlan->pattern_min_len)
12861 goto error;
12862
50ac6607 12863 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
12864 pkt_offset = 0;
12865 else
12866 pkt_offset = nla_get_u32(
50ac6607 12867 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
12868 if (pkt_offset > wowlan->max_pkt_offset)
12869 goto error;
12870 new_triggers.patterns[i].pkt_offset = pkt_offset;
12871
922bd80f
JB
12872 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
12873 if (!mask_pat) {
ff1b6e69
JB
12874 err = -ENOMEM;
12875 goto error;
12876 }
922bd80f
JB
12877 new_triggers.patterns[i].mask = mask_pat;
12878 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 12879 mask_len);
922bd80f
JB
12880 mask_pat += mask_len;
12881 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 12882 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 12883 memcpy(mask_pat,
50ac6607 12884 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
12885 pat_len);
12886 i++;
12887 }
12888 }
12889
2a0e047e 12890 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 12891 regular = true;
2a0e047e
JB
12892 err = nl80211_parse_wowlan_tcp(
12893 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
12894 &new_triggers);
12895 if (err)
12896 goto error;
12897 }
12898
8cd4d456 12899 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 12900 regular = true;
8cd4d456
LC
12901 err = nl80211_parse_wowlan_nd(
12902 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
12903 &new_triggers);
12904 if (err)
12905 goto error;
12906 }
12907
98fc4386
JB
12908 /* The 'any' trigger means the device continues operating more or less
12909 * as in its normal operation mode and wakes up the host on most of the
12910 * normal interrupts (like packet RX, ...)
12911 * It therefore makes little sense to combine with the more constrained
12912 * wakeup trigger modes.
12913 */
12914 if (new_triggers.any && regular) {
12915 err = -EINVAL;
12916 goto error;
12917 }
12918
ae33bd81
JB
12919 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
12920 if (!ntrig) {
12921 err = -ENOMEM;
12922 goto error;
ff1b6e69 12923 }
ae33bd81 12924 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 12925 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 12926
ae33bd81 12927 set_wakeup:
6abb9cb9
JB
12928 if (rdev->ops->set_wakeup &&
12929 prev_enabled != !!rdev->wiphy.wowlan_config)
12930 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 12931
ff1b6e69
JB
12932 return 0;
12933 error:
12934 for (i = 0; i < new_triggers.n_patterns; i++)
12935 kfree(new_triggers.patterns[i].mask);
12936 kfree(new_triggers.patterns);
2a0e047e
JB
12937 if (new_triggers.tcp && new_triggers.tcp->sock)
12938 sock_release(new_triggers.tcp->sock);
12939 kfree(new_triggers.tcp);
e5dbe070 12940 kfree(new_triggers.nd_config);
ff1b6e69
JB
12941 return err;
12942}
dfb89c56 12943#endif
ff1b6e69 12944
be29b99a
AK
12945static int nl80211_send_coalesce_rules(struct sk_buff *msg,
12946 struct cfg80211_registered_device *rdev)
12947{
12948 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
12949 int i, j, pat_len;
12950 struct cfg80211_coalesce_rules *rule;
12951
12952 if (!rdev->coalesce->n_rules)
12953 return 0;
12954
ae0be8de 12955 nl_rules = nla_nest_start_noflag(msg, NL80211_ATTR_COALESCE_RULE);
be29b99a
AK
12956 if (!nl_rules)
12957 return -ENOBUFS;
12958
12959 for (i = 0; i < rdev->coalesce->n_rules; i++) {
ae0be8de 12960 nl_rule = nla_nest_start_noflag(msg, i + 1);
be29b99a
AK
12961 if (!nl_rule)
12962 return -ENOBUFS;
12963
12964 rule = &rdev->coalesce->rules[i];
12965 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
12966 rule->delay))
12967 return -ENOBUFS;
12968
12969 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
12970 rule->condition))
12971 return -ENOBUFS;
12972
ae0be8de
MK
12973 nl_pats = nla_nest_start_noflag(msg,
12974 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
be29b99a
AK
12975 if (!nl_pats)
12976 return -ENOBUFS;
12977
12978 for (j = 0; j < rule->n_patterns; j++) {
ae0be8de 12979 nl_pat = nla_nest_start_noflag(msg, j + 1);
be29b99a
AK
12980 if (!nl_pat)
12981 return -ENOBUFS;
12982 pat_len = rule->patterns[j].pattern_len;
12983 if (nla_put(msg, NL80211_PKTPAT_MASK,
12984 DIV_ROUND_UP(pat_len, 8),
12985 rule->patterns[j].mask) ||
12986 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
12987 rule->patterns[j].pattern) ||
12988 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
12989 rule->patterns[j].pkt_offset))
12990 return -ENOBUFS;
12991 nla_nest_end(msg, nl_pat);
12992 }
12993 nla_nest_end(msg, nl_pats);
12994 nla_nest_end(msg, nl_rule);
12995 }
12996 nla_nest_end(msg, nl_rules);
12997
12998 return 0;
12999}
13000
13001static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
13002{
13003 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13004 struct sk_buff *msg;
13005 void *hdr;
13006
13007 if (!rdev->wiphy.coalesce)
13008 return -EOPNOTSUPP;
13009
13010 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13011 if (!msg)
13012 return -ENOMEM;
13013
13014 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13015 NL80211_CMD_GET_COALESCE);
13016 if (!hdr)
13017 goto nla_put_failure;
13018
13019 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
13020 goto nla_put_failure;
13021
13022 genlmsg_end(msg, hdr);
13023 return genlmsg_reply(msg, info);
13024
13025nla_put_failure:
13026 nlmsg_free(msg);
13027 return -ENOBUFS;
13028}
13029
13030void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
13031{
13032 struct cfg80211_coalesce *coalesce = rdev->coalesce;
13033 int i, j;
13034 struct cfg80211_coalesce_rules *rule;
13035
13036 if (!coalesce)
13037 return;
13038
13039 for (i = 0; i < coalesce->n_rules; i++) {
13040 rule = &coalesce->rules[i];
13041 for (j = 0; j < rule->n_patterns; j++)
13042 kfree(rule->patterns[j].mask);
13043 kfree(rule->patterns);
13044 }
13045 kfree(coalesce->rules);
13046 kfree(coalesce);
13047 rdev->coalesce = NULL;
13048}
13049
13050static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
13051 struct nlattr *rule,
13052 struct cfg80211_coalesce_rules *new_rule)
13053{
13054 int err, i;
13055 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
13056 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
13057 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
13058 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
13059
8cb08174
JB
13060 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_COALESCE_RULE_MAX,
13061 rule, nl80211_coalesce_policy, NULL);
be29b99a
AK
13062 if (err)
13063 return err;
13064
13065 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
13066 new_rule->delay =
13067 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
13068 if (new_rule->delay > coalesce->max_delay)
13069 return -EINVAL;
13070
13071 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
13072 new_rule->condition =
13073 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
be29b99a
AK
13074
13075 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
13076 return -EINVAL;
13077
13078 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
13079 rem)
13080 n_patterns++;
13081 if (n_patterns > coalesce->n_patterns)
13082 return -EINVAL;
13083
13084 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
13085 GFP_KERNEL);
13086 if (!new_rule->patterns)
13087 return -ENOMEM;
13088
13089 new_rule->n_patterns = n_patterns;
13090 i = 0;
13091
13092 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
13093 rem) {
922bd80f
JB
13094 u8 *mask_pat;
13095
8cb08174
JB
13096 err = nla_parse_nested_deprecated(pat_tb, MAX_NL80211_PKTPAT,
13097 pat,
13098 nl80211_packet_pattern_policy,
13099 NULL);
95bca62f
JB
13100 if (err)
13101 return err;
13102
be29b99a
AK
13103 if (!pat_tb[NL80211_PKTPAT_MASK] ||
13104 !pat_tb[NL80211_PKTPAT_PATTERN])
13105 return -EINVAL;
13106 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
13107 mask_len = DIV_ROUND_UP(pat_len, 8);
13108 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
13109 return -EINVAL;
13110 if (pat_len > coalesce->pattern_max_len ||
13111 pat_len < coalesce->pattern_min_len)
13112 return -EINVAL;
13113
13114 if (!pat_tb[NL80211_PKTPAT_OFFSET])
13115 pkt_offset = 0;
13116 else
13117 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
13118 if (pkt_offset > coalesce->max_pkt_offset)
13119 return -EINVAL;
13120 new_rule->patterns[i].pkt_offset = pkt_offset;
13121
922bd80f
JB
13122 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
13123 if (!mask_pat)
be29b99a 13124 return -ENOMEM;
922bd80f
JB
13125
13126 new_rule->patterns[i].mask = mask_pat;
13127 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
13128 mask_len);
13129
13130 mask_pat += mask_len;
13131 new_rule->patterns[i].pattern = mask_pat;
be29b99a 13132 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
13133 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
13134 pat_len);
be29b99a
AK
13135 i++;
13136 }
13137
13138 return 0;
13139}
13140
13141static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
13142{
13143 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13144 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
13145 struct cfg80211_coalesce new_coalesce = {};
13146 struct cfg80211_coalesce *n_coalesce;
13147 int err, rem_rule, n_rules = 0, i, j;
13148 struct nlattr *rule;
13149 struct cfg80211_coalesce_rules *tmp_rule;
13150
13151 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
13152 return -EOPNOTSUPP;
13153
13154 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
13155 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 13156 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
13157 return 0;
13158 }
13159
13160 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
13161 rem_rule)
13162 n_rules++;
13163 if (n_rules > coalesce->n_rules)
13164 return -EINVAL;
13165
13166 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
13167 GFP_KERNEL);
13168 if (!new_coalesce.rules)
13169 return -ENOMEM;
13170
13171 new_coalesce.n_rules = n_rules;
13172 i = 0;
13173
13174 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
13175 rem_rule) {
13176 err = nl80211_parse_coalesce_rule(rdev, rule,
13177 &new_coalesce.rules[i]);
13178 if (err)
13179 goto error;
13180
13181 i++;
13182 }
13183
a1056b1b 13184 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
13185 if (err)
13186 goto error;
13187
13188 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
13189 if (!n_coalesce) {
13190 err = -ENOMEM;
13191 goto error;
13192 }
13193 cfg80211_rdev_free_coalesce(rdev);
13194 rdev->coalesce = n_coalesce;
13195
13196 return 0;
13197error:
13198 for (i = 0; i < new_coalesce.n_rules; i++) {
13199 tmp_rule = &new_coalesce.rules[i];
13200 for (j = 0; j < tmp_rule->n_patterns; j++)
13201 kfree(tmp_rule->patterns[j].mask);
13202 kfree(tmp_rule->patterns);
13203 }
13204 kfree(new_coalesce.rules);
13205
13206 return err;
13207}
13208
e5497d76
JB
13209static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
13210{
13211 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13212 struct net_device *dev = info->user_ptr[1];
13213 struct wireless_dev *wdev = dev->ieee80211_ptr;
13214 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
f495acd8 13215 struct cfg80211_gtk_rekey_data rekey_data = {};
e5497d76
JB
13216 int err;
13217
13218 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
13219 return -EINVAL;
13220
8cb08174
JB
13221 err = nla_parse_nested_deprecated(tb, MAX_NL80211_REKEY_DATA,
13222 info->attrs[NL80211_ATTR_REKEY_DATA],
13223 nl80211_rekey_policy, info->extack);
e5497d76
JB
13224 if (err)
13225 return err;
13226
e785fa0a
VD
13227 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
13228 !tb[NL80211_REKEY_DATA_KCK])
13229 return -EINVAL;
093a48d2
NE
13230 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
13231 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
13232 nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
e5497d76 13233 return -ERANGE;
093a48d2
NE
13234 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
13235 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
13236 nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
e5497d76
JB
13237 return -ERANGE;
13238
78f686ca
JB
13239 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
13240 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
13241 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
093a48d2
NE
13242 rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
13243 rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]);
13244 if (tb[NL80211_REKEY_DATA_AKM])
13245 rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
e5497d76
JB
13246
13247 wdev_lock(wdev);
13248 if (!wdev->current_bss) {
13249 err = -ENOTCONN;
13250 goto out;
13251 }
13252
13253 if (!rdev->ops->set_rekey_data) {
13254 err = -EOPNOTSUPP;
13255 goto out;
13256 }
13257
e35e4d28 13258 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
13259 out:
13260 wdev_unlock(wdev);
13261 return err;
13262}
13263
28946da7
JB
13264static int nl80211_register_unexpected_frame(struct sk_buff *skb,
13265 struct genl_info *info)
13266{
13267 struct net_device *dev = info->user_ptr[1];
13268 struct wireless_dev *wdev = dev->ieee80211_ptr;
13269
13270 if (wdev->iftype != NL80211_IFTYPE_AP &&
13271 wdev->iftype != NL80211_IFTYPE_P2P_GO)
13272 return -EINVAL;
13273
15e47304 13274 if (wdev->ap_unexpected_nlportid)
28946da7
JB
13275 return -EBUSY;
13276
15e47304 13277 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
13278 return 0;
13279}
13280
7f6cf311
JB
13281static int nl80211_probe_client(struct sk_buff *skb,
13282 struct genl_info *info)
13283{
13284 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13285 struct net_device *dev = info->user_ptr[1];
13286 struct wireless_dev *wdev = dev->ieee80211_ptr;
13287 struct sk_buff *msg;
13288 void *hdr;
13289 const u8 *addr;
13290 u64 cookie;
13291 int err;
13292
13293 if (wdev->iftype != NL80211_IFTYPE_AP &&
13294 wdev->iftype != NL80211_IFTYPE_P2P_GO)
13295 return -EOPNOTSUPP;
13296
13297 if (!info->attrs[NL80211_ATTR_MAC])
13298 return -EINVAL;
13299
13300 if (!rdev->ops->probe_client)
13301 return -EOPNOTSUPP;
13302
13303 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13304 if (!msg)
13305 return -ENOMEM;
13306
15e47304 13307 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 13308 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
13309 if (!hdr) {
13310 err = -ENOBUFS;
7f6cf311
JB
13311 goto free_msg;
13312 }
13313
13314 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
13315
e35e4d28 13316 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
13317 if (err)
13318 goto free_msg;
13319
2dad624e
ND
13320 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13321 NL80211_ATTR_PAD))
9360ffd1 13322 goto nla_put_failure;
7f6cf311
JB
13323
13324 genlmsg_end(msg, hdr);
13325
13326 return genlmsg_reply(msg, info);
13327
13328 nla_put_failure:
13329 err = -ENOBUFS;
13330 free_msg:
13331 nlmsg_free(msg);
13332 return err;
13333}
13334
5e760230
JB
13335static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
13336{
13337 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
13338 struct cfg80211_beacon_registration *reg, *nreg;
13339 int rv;
5e760230
JB
13340
13341 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
13342 return -EOPNOTSUPP;
13343
37c73b5f
BG
13344 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
13345 if (!nreg)
13346 return -ENOMEM;
13347
13348 /* First, check if already registered. */
13349 spin_lock_bh(&rdev->beacon_registrations_lock);
13350 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
13351 if (reg->nlportid == info->snd_portid) {
13352 rv = -EALREADY;
13353 goto out_err;
13354 }
13355 }
13356 /* Add it to the list */
13357 nreg->nlportid = info->snd_portid;
13358 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 13359
37c73b5f 13360 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
13361
13362 return 0;
37c73b5f
BG
13363out_err:
13364 spin_unlock_bh(&rdev->beacon_registrations_lock);
13365 kfree(nreg);
13366 return rv;
5e760230
JB
13367}
13368
98104fde
JB
13369static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
13370{
13371 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13372 struct wireless_dev *wdev = info->user_ptr[1];
13373 int err;
13374
13375 if (!rdev->ops->start_p2p_device)
13376 return -EOPNOTSUPP;
13377
13378 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
13379 return -EOPNOTSUPP;
13380
73c7da3d 13381 if (wdev_running(wdev))
98104fde
JB
13382 return 0;
13383
358ae888 13384 if (rfkill_blocked(rdev->wiphy.rfkill))
b6a55015 13385 return -ERFKILL;
98104fde 13386
eeb126e9 13387 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
13388 if (err)
13389 return err;
13390
73c7da3d 13391 wdev->is_running = true;
98104fde 13392 rdev->opencount++;
98104fde
JB
13393
13394 return 0;
13395}
13396
13397static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
13398{
13399 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13400 struct wireless_dev *wdev = info->user_ptr[1];
13401
13402 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
13403 return -EOPNOTSUPP;
13404
13405 if (!rdev->ops->stop_p2p_device)
13406 return -EOPNOTSUPP;
13407
f9f47529 13408 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
13409
13410 return 0;
13411}
13412
cb3b7d87
AB
13413static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
13414{
13415 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13416 struct wireless_dev *wdev = info->user_ptr[1];
13417 struct cfg80211_nan_conf conf = {};
13418 int err;
13419
13420 if (wdev->iftype != NL80211_IFTYPE_NAN)
13421 return -EOPNOTSUPP;
13422
eeb04a96 13423 if (wdev_running(wdev))
cb3b7d87
AB
13424 return -EEXIST;
13425
358ae888 13426 if (rfkill_blocked(rdev->wiphy.rfkill))
cb3b7d87
AB
13427 return -ERFKILL;
13428
13429 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
13430 return -EINVAL;
13431
cb3b7d87
AB
13432 conf.master_pref =
13433 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
cb3b7d87 13434
8585989d
LC
13435 if (info->attrs[NL80211_ATTR_BANDS]) {
13436 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
13437
13438 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
13439 return -EOPNOTSUPP;
13440
13441 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
13442 return -EINVAL;
13443
13444 conf.bands = bands;
13445 }
cb3b7d87
AB
13446
13447 err = rdev_start_nan(rdev, wdev, &conf);
13448 if (err)
13449 return err;
13450
73c7da3d 13451 wdev->is_running = true;
cb3b7d87
AB
13452 rdev->opencount++;
13453
13454 return 0;
13455}
13456
13457static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
13458{
13459 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13460 struct wireless_dev *wdev = info->user_ptr[1];
13461
13462 if (wdev->iftype != NL80211_IFTYPE_NAN)
13463 return -EOPNOTSUPP;
13464
13465 cfg80211_stop_nan(rdev, wdev);
13466
13467 return 0;
13468}
13469
a442b761
AB
13470static int validate_nan_filter(struct nlattr *filter_attr)
13471{
13472 struct nlattr *attr;
13473 int len = 0, n_entries = 0, rem;
13474
13475 nla_for_each_nested(attr, filter_attr, rem) {
13476 len += nla_len(attr);
13477 n_entries++;
13478 }
13479
13480 if (len >= U8_MAX)
13481 return -EINVAL;
13482
13483 return n_entries;
13484}
13485
13486static int handle_nan_filter(struct nlattr *attr_filter,
13487 struct cfg80211_nan_func *func,
13488 bool tx)
13489{
13490 struct nlattr *attr;
13491 int n_entries, rem, i;
13492 struct cfg80211_nan_func_filter *filter;
13493
13494 n_entries = validate_nan_filter(attr_filter);
13495 if (n_entries < 0)
13496 return n_entries;
13497
13498 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
13499
13500 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
13501 if (!filter)
13502 return -ENOMEM;
13503
13504 i = 0;
13505 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 13506 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
6ad27f52
JJ
13507 if (!filter[i].filter)
13508 goto err;
13509
a442b761
AB
13510 filter[i].len = nla_len(attr);
13511 i++;
13512 }
13513 if (tx) {
13514 func->num_tx_filters = n_entries;
13515 func->tx_filters = filter;
13516 } else {
13517 func->num_rx_filters = n_entries;
13518 func->rx_filters = filter;
13519 }
13520
13521 return 0;
6ad27f52
JJ
13522
13523err:
13524 i = 0;
13525 nla_for_each_nested(attr, attr_filter, rem) {
13526 kfree(filter[i].filter);
13527 i++;
13528 }
13529 kfree(filter);
13530 return -ENOMEM;
a442b761
AB
13531}
13532
13533static int nl80211_nan_add_func(struct sk_buff *skb,
13534 struct genl_info *info)
13535{
13536 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13537 struct wireless_dev *wdev = info->user_ptr[1];
13538 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
13539 struct cfg80211_nan_func *func;
13540 struct sk_buff *msg = NULL;
13541 void *hdr = NULL;
13542 int err = 0;
13543
13544 if (wdev->iftype != NL80211_IFTYPE_NAN)
13545 return -EOPNOTSUPP;
13546
73c7da3d 13547 if (!wdev_running(wdev))
a442b761
AB
13548 return -ENOTCONN;
13549
13550 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
13551 return -EINVAL;
13552
8cb08174
JB
13553 err = nla_parse_nested_deprecated(tb, NL80211_NAN_FUNC_ATTR_MAX,
13554 info->attrs[NL80211_ATTR_NAN_FUNC],
13555 nl80211_nan_func_policy,
13556 info->extack);
a442b761
AB
13557 if (err)
13558 return err;
13559
13560 func = kzalloc(sizeof(*func), GFP_KERNEL);
13561 if (!func)
13562 return -ENOMEM;
13563
b60ad348 13564 func->cookie = cfg80211_assign_cookie(rdev);
a442b761 13565
cb9abd48 13566 if (!tb[NL80211_NAN_FUNC_TYPE]) {
a442b761
AB
13567 err = -EINVAL;
13568 goto out;
13569 }
13570
13571
13572 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
13573
13574 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
13575 err = -EINVAL;
13576 goto out;
13577 }
13578
13579 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
13580 sizeof(func->service_id));
13581
13582 func->close_range =
13583 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
13584
13585 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
13586 func->serv_spec_info_len =
13587 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
13588 func->serv_spec_info =
13589 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
13590 func->serv_spec_info_len,
13591 GFP_KERNEL);
13592 if (!func->serv_spec_info) {
13593 err = -ENOMEM;
13594 goto out;
13595 }
13596 }
13597
13598 if (tb[NL80211_NAN_FUNC_TTL])
13599 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
13600
13601 switch (func->type) {
13602 case NL80211_NAN_FUNC_PUBLISH:
13603 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
13604 err = -EINVAL;
13605 goto out;
13606 }
13607
13608 func->publish_type =
13609 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
13610 func->publish_bcast =
13611 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
13612
13613 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
13614 func->publish_bcast) {
13615 err = -EINVAL;
13616 goto out;
13617 }
13618 break;
13619 case NL80211_NAN_FUNC_SUBSCRIBE:
13620 func->subscribe_active =
13621 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
13622 break;
13623 case NL80211_NAN_FUNC_FOLLOW_UP:
13624 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
3ea15452
HC
13625 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
13626 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
a442b761
AB
13627 err = -EINVAL;
13628 goto out;
13629 }
13630
13631 func->followup_id =
13632 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
13633 func->followup_reqid =
13634 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
13635 memcpy(func->followup_dest.addr,
13636 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
13637 sizeof(func->followup_dest.addr));
13638 if (func->ttl) {
13639 err = -EINVAL;
13640 goto out;
13641 }
13642 break;
13643 default:
13644 err = -EINVAL;
13645 goto out;
13646 }
13647
13648 if (tb[NL80211_NAN_FUNC_SRF]) {
13649 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
13650
8cb08174
JB
13651 err = nla_parse_nested_deprecated(srf_tb,
13652 NL80211_NAN_SRF_ATTR_MAX,
13653 tb[NL80211_NAN_FUNC_SRF],
13654 nl80211_nan_srf_policy,
13655 info->extack);
a442b761
AB
13656 if (err)
13657 goto out;
13658
13659 func->srf_include =
13660 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
13661
13662 if (srf_tb[NL80211_NAN_SRF_BF]) {
13663 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
13664 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
13665 err = -EINVAL;
13666 goto out;
13667 }
13668
13669 func->srf_bf_len =
13670 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
13671 func->srf_bf =
13672 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
13673 func->srf_bf_len, GFP_KERNEL);
13674 if (!func->srf_bf) {
13675 err = -ENOMEM;
13676 goto out;
13677 }
13678
13679 func->srf_bf_idx =
13680 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
13681 } else {
13682 struct nlattr *attr, *mac_attr =
13683 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
13684 int n_entries, rem, i = 0;
13685
13686 if (!mac_attr) {
13687 err = -EINVAL;
13688 goto out;
13689 }
13690
13691 n_entries = validate_acl_mac_addrs(mac_attr);
13692 if (n_entries <= 0) {
13693 err = -EINVAL;
13694 goto out;
13695 }
13696
13697 func->srf_num_macs = n_entries;
13698 func->srf_macs =
6396bb22 13699 kcalloc(n_entries, sizeof(*func->srf_macs),
a442b761
AB
13700 GFP_KERNEL);
13701 if (!func->srf_macs) {
13702 err = -ENOMEM;
13703 goto out;
13704 }
13705
13706 nla_for_each_nested(attr, mac_attr, rem)
13707 memcpy(func->srf_macs[i++].addr, nla_data(attr),
13708 sizeof(*func->srf_macs));
13709 }
13710 }
13711
13712 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
13713 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
13714 func, true);
13715 if (err)
13716 goto out;
13717 }
13718
13719 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
13720 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
13721 func, false);
13722 if (err)
13723 goto out;
13724 }
13725
13726 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13727 if (!msg) {
13728 err = -ENOMEM;
13729 goto out;
13730 }
13731
13732 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13733 NL80211_CMD_ADD_NAN_FUNCTION);
13734 /* This can't really happen - we just allocated 4KB */
13735 if (WARN_ON(!hdr)) {
13736 err = -ENOMEM;
13737 goto out;
13738 }
13739
13740 err = rdev_add_nan_func(rdev, wdev, func);
13741out:
13742 if (err < 0) {
13743 cfg80211_free_nan_func(func);
13744 nlmsg_free(msg);
13745 return err;
13746 }
13747
13748 /* propagate the instance id and cookie to userspace */
13749 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
13750 NL80211_ATTR_PAD))
13751 goto nla_put_failure;
13752
ae0be8de 13753 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
a442b761
AB
13754 if (!func_attr)
13755 goto nla_put_failure;
13756
13757 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
13758 func->instance_id))
13759 goto nla_put_failure;
13760
13761 nla_nest_end(msg, func_attr);
13762
13763 genlmsg_end(msg, hdr);
13764 return genlmsg_reply(msg, info);
13765
13766nla_put_failure:
13767 nlmsg_free(msg);
13768 return -ENOBUFS;
13769}
13770
13771static int nl80211_nan_del_func(struct sk_buff *skb,
13772 struct genl_info *info)
13773{
13774 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13775 struct wireless_dev *wdev = info->user_ptr[1];
13776 u64 cookie;
13777
13778 if (wdev->iftype != NL80211_IFTYPE_NAN)
13779 return -EOPNOTSUPP;
13780
73c7da3d 13781 if (!wdev_running(wdev))
a442b761
AB
13782 return -ENOTCONN;
13783
13784 if (!info->attrs[NL80211_ATTR_COOKIE])
13785 return -EINVAL;
13786
a442b761
AB
13787 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
13788
13789 rdev_del_nan_func(rdev, wdev, cookie);
13790
13791 return 0;
13792}
13793
a5a9dcf2
AB
13794static int nl80211_nan_change_config(struct sk_buff *skb,
13795 struct genl_info *info)
13796{
13797 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13798 struct wireless_dev *wdev = info->user_ptr[1];
13799 struct cfg80211_nan_conf conf = {};
13800 u32 changed = 0;
13801
13802 if (wdev->iftype != NL80211_IFTYPE_NAN)
13803 return -EOPNOTSUPP;
13804
73c7da3d 13805 if (!wdev_running(wdev))
a5a9dcf2
AB
13806 return -ENOTCONN;
13807
13808 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
13809 conf.master_pref =
13810 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
13811 if (conf.master_pref <= 1 || conf.master_pref == 255)
13812 return -EINVAL;
13813
13814 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
13815 }
13816
8585989d
LC
13817 if (info->attrs[NL80211_ATTR_BANDS]) {
13818 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
13819
13820 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
13821 return -EOPNOTSUPP;
13822
13823 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
13824 return -EINVAL;
13825
13826 conf.bands = bands;
13827 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
13828 }
13829
13830 if (!changed)
13831 return -EINVAL;
13832
13833 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
13834}
13835
50bcd31d
AB
13836void cfg80211_nan_match(struct wireless_dev *wdev,
13837 struct cfg80211_nan_match_params *match, gfp_t gfp)
13838{
13839 struct wiphy *wiphy = wdev->wiphy;
13840 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13841 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
13842 struct sk_buff *msg;
13843 void *hdr;
13844
13845 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
13846 return;
13847
13848 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13849 if (!msg)
13850 return;
13851
13852 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
13853 if (!hdr) {
13854 nlmsg_free(msg);
13855 return;
13856 }
13857
13858 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13859 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13860 wdev->netdev->ifindex)) ||
13861 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13862 NL80211_ATTR_PAD))
13863 goto nla_put_failure;
13864
13865 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
13866 NL80211_ATTR_PAD) ||
13867 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
13868 goto nla_put_failure;
13869
ae0be8de 13870 match_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_MATCH);
50bcd31d
AB
13871 if (!match_attr)
13872 goto nla_put_failure;
13873
ae0be8de
MK
13874 local_func_attr = nla_nest_start_noflag(msg,
13875 NL80211_NAN_MATCH_FUNC_LOCAL);
50bcd31d
AB
13876 if (!local_func_attr)
13877 goto nla_put_failure;
13878
13879 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
13880 goto nla_put_failure;
13881
13882 nla_nest_end(msg, local_func_attr);
13883
ae0be8de
MK
13884 peer_func_attr = nla_nest_start_noflag(msg,
13885 NL80211_NAN_MATCH_FUNC_PEER);
50bcd31d
AB
13886 if (!peer_func_attr)
13887 goto nla_put_failure;
13888
13889 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
13890 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
13891 goto nla_put_failure;
13892
13893 if (match->info && match->info_len &&
13894 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
13895 match->info))
13896 goto nla_put_failure;
13897
13898 nla_nest_end(msg, peer_func_attr);
13899 nla_nest_end(msg, match_attr);
13900 genlmsg_end(msg, hdr);
13901
13902 if (!wdev->owner_nlportid)
13903 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
13904 msg, 0, NL80211_MCGRP_NAN, gfp);
13905 else
13906 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
13907 wdev->owner_nlportid);
13908
13909 return;
13910
13911nla_put_failure:
13912 nlmsg_free(msg);
13913}
13914EXPORT_SYMBOL(cfg80211_nan_match);
13915
368e5a7b
AB
13916void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
13917 u8 inst_id,
13918 enum nl80211_nan_func_term_reason reason,
13919 u64 cookie, gfp_t gfp)
13920{
13921 struct wiphy *wiphy = wdev->wiphy;
13922 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13923 struct sk_buff *msg;
13924 struct nlattr *func_attr;
13925 void *hdr;
13926
13927 if (WARN_ON(!inst_id))
13928 return;
13929
13930 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13931 if (!msg)
13932 return;
13933
13934 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
13935 if (!hdr) {
13936 nlmsg_free(msg);
13937 return;
13938 }
13939
13940 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13941 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13942 wdev->netdev->ifindex)) ||
13943 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13944 NL80211_ATTR_PAD))
13945 goto nla_put_failure;
13946
13947 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13948 NL80211_ATTR_PAD))
13949 goto nla_put_failure;
13950
ae0be8de 13951 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
368e5a7b
AB
13952 if (!func_attr)
13953 goto nla_put_failure;
13954
13955 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
13956 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
13957 goto nla_put_failure;
13958
13959 nla_nest_end(msg, func_attr);
13960 genlmsg_end(msg, hdr);
13961
13962 if (!wdev->owner_nlportid)
13963 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
13964 msg, 0, NL80211_MCGRP_NAN, gfp);
13965 else
13966 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
13967 wdev->owner_nlportid);
13968
13969 return;
13970
13971nla_put_failure:
13972 nlmsg_free(msg);
13973}
13974EXPORT_SYMBOL(cfg80211_nan_func_terminated);
13975
3713b4e3
JB
13976static int nl80211_get_protocol_features(struct sk_buff *skb,
13977 struct genl_info *info)
13978{
13979 void *hdr;
13980 struct sk_buff *msg;
13981
13982 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13983 if (!msg)
13984 return -ENOMEM;
13985
13986 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13987 NL80211_CMD_GET_PROTOCOL_FEATURES);
13988 if (!hdr)
13989 goto nla_put_failure;
13990
13991 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
13992 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
13993 goto nla_put_failure;
13994
13995 genlmsg_end(msg, hdr);
13996 return genlmsg_reply(msg, info);
13997
13998 nla_put_failure:
13999 kfree_skb(msg);
14000 return -ENOBUFS;
14001}
14002
355199e0
JM
14003static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
14004{
14005 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14006 struct cfg80211_update_ft_ies_params ft_params;
14007 struct net_device *dev = info->user_ptr[1];
14008
14009 if (!rdev->ops->update_ft_ies)
14010 return -EOPNOTSUPP;
14011
14012 if (!info->attrs[NL80211_ATTR_MDID] ||
3d7af878 14013 !info->attrs[NL80211_ATTR_IE])
355199e0
JM
14014 return -EINVAL;
14015
14016 memset(&ft_params, 0, sizeof(ft_params));
14017 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
14018 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
14019 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
14020
14021 return rdev_update_ft_ies(rdev, dev, &ft_params);
14022}
14023
5de17984
AS
14024static int nl80211_crit_protocol_start(struct sk_buff *skb,
14025 struct genl_info *info)
14026{
14027 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14028 struct wireless_dev *wdev = info->user_ptr[1];
14029 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
14030 u16 duration;
14031 int ret;
14032
14033 if (!rdev->ops->crit_proto_start)
14034 return -EOPNOTSUPP;
14035
14036 if (WARN_ON(!rdev->ops->crit_proto_stop))
14037 return -EINVAL;
14038
14039 if (rdev->crit_proto_nlportid)
14040 return -EBUSY;
14041
14042 /* determine protocol if provided */
14043 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
14044 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
14045
14046 if (proto >= NUM_NL80211_CRIT_PROTO)
14047 return -EINVAL;
14048
14049 /* timeout must be provided */
14050 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
14051 return -EINVAL;
14052
14053 duration =
14054 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
14055
5de17984
AS
14056 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
14057 if (!ret)
14058 rdev->crit_proto_nlportid = info->snd_portid;
14059
14060 return ret;
14061}
14062
14063static int nl80211_crit_protocol_stop(struct sk_buff *skb,
14064 struct genl_info *info)
14065{
14066 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14067 struct wireless_dev *wdev = info->user_ptr[1];
14068
14069 if (!rdev->ops->crit_proto_stop)
14070 return -EOPNOTSUPP;
14071
14072 if (rdev->crit_proto_nlportid) {
14073 rdev->crit_proto_nlportid = 0;
14074 rdev_crit_proto_stop(rdev, wdev);
14075 }
14076 return 0;
14077}
14078
901bb989
JB
14079static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
14080 struct nlattr *attr,
14081 struct netlink_ext_ack *extack)
14082{
14083 if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
14084 if (attr->nla_type & NLA_F_NESTED) {
14085 NL_SET_ERR_MSG_ATTR(extack, attr,
14086 "unexpected nested data");
14087 return -EINVAL;
14088 }
14089
14090 return 0;
14091 }
14092
14093 if (!(attr->nla_type & NLA_F_NESTED)) {
14094 NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
14095 return -EINVAL;
14096 }
14097
32d5109a 14098 return nla_validate_nested(attr, vcmd->maxattr, vcmd->policy, extack);
901bb989
JB
14099}
14100
ad7e718c
JB
14101static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
14102{
14103 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14104 struct wireless_dev *wdev =
a05829a7
JB
14105 __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
14106 info->attrs);
ad7e718c
JB
14107 int i, err;
14108 u32 vid, subcmd;
14109
14110 if (!rdev->wiphy.vendor_commands)
14111 return -EOPNOTSUPP;
14112
14113 if (IS_ERR(wdev)) {
14114 err = PTR_ERR(wdev);
14115 if (err != -EINVAL)
14116 return err;
14117 wdev = NULL;
14118 } else if (wdev->wiphy != &rdev->wiphy) {
14119 return -EINVAL;
14120 }
14121
14122 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
14123 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
14124 return -EINVAL;
14125
14126 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
14127 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
14128 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
14129 const struct wiphy_vendor_command *vcmd;
14130 void *data = NULL;
14131 int len = 0;
14132
14133 vcmd = &rdev->wiphy.vendor_commands[i];
14134
14135 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
14136 continue;
14137
14138 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
14139 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
14140 if (!wdev)
14141 return -EINVAL;
14142 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
14143 !wdev->netdev)
14144 return -EINVAL;
14145
14146 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 14147 if (!wdev_running(wdev))
ad7e718c
JB
14148 return -ENETDOWN;
14149 }
14150 } else {
14151 wdev = NULL;
14152 }
14153
4052d3d2
JS
14154 if (!vcmd->doit)
14155 return -EOPNOTSUPP;
14156
ad7e718c
JB
14157 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
14158 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
14159 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
14160
14161 err = nl80211_vendor_check_policy(vcmd,
14162 info->attrs[NL80211_ATTR_VENDOR_DATA],
14163 info->extack);
14164 if (err)
14165 return err;
ad7e718c
JB
14166 }
14167
14168 rdev->cur_cmd_info = info;
901bb989 14169 err = vcmd->doit(&rdev->wiphy, wdev, data, len);
ad7e718c
JB
14170 rdev->cur_cmd_info = NULL;
14171 return err;
14172 }
14173
14174 return -EOPNOTSUPP;
14175}
14176
7bdbe400
JB
14177static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
14178 struct netlink_callback *cb,
14179 struct cfg80211_registered_device **rdev,
14180 struct wireless_dev **wdev)
14181{
50508d94 14182 struct nlattr **attrbuf;
7bdbe400
JB
14183 u32 vid, subcmd;
14184 unsigned int i;
14185 int vcmd_idx = -1;
14186 int err;
14187 void *data = NULL;
14188 unsigned int data_len = 0;
14189
7bdbe400
JB
14190 if (cb->args[0]) {
14191 /* subtract the 1 again here */
14192 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
14193 struct wireless_dev *tmp;
14194
ea90e0dc
JB
14195 if (!wiphy)
14196 return -ENODEV;
7bdbe400
JB
14197 *rdev = wiphy_to_rdev(wiphy);
14198 *wdev = NULL;
14199
14200 if (cb->args[1]) {
53873f13 14201 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
14202 if (tmp->identifier == cb->args[1] - 1) {
14203 *wdev = tmp;
14204 break;
14205 }
14206 }
14207 }
14208
14209 /* keep rtnl locked in successful case */
14210 return 0;
14211 }
14212
50508d94
JB
14213 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
14214 if (!attrbuf)
14215 return -ENOMEM;
14216
8cb08174
JB
14217 err = nlmsg_parse_deprecated(cb->nlh,
14218 GENL_HDRLEN + nl80211_fam.hdrsize,
14219 attrbuf, nl80211_fam.maxattr,
14220 nl80211_policy, NULL);
7bdbe400 14221 if (err)
50508d94 14222 goto out;
7bdbe400 14223
c90c39da 14224 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
50508d94
JB
14225 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
14226 err = -EINVAL;
14227 goto out;
14228 }
7bdbe400 14229
a05829a7 14230 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(skb->sk), attrbuf);
7bdbe400
JB
14231 if (IS_ERR(*wdev))
14232 *wdev = NULL;
14233
c90c39da 14234 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
50508d94
JB
14235 if (IS_ERR(*rdev)) {
14236 err = PTR_ERR(*rdev);
14237 goto out;
14238 }
7bdbe400 14239
c90c39da
JB
14240 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
14241 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
14242
14243 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
14244 const struct wiphy_vendor_command *vcmd;
14245
14246 vcmd = &(*rdev)->wiphy.vendor_commands[i];
14247
14248 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
14249 continue;
14250
50508d94
JB
14251 if (!vcmd->dumpit) {
14252 err = -EOPNOTSUPP;
14253 goto out;
14254 }
7bdbe400
JB
14255
14256 vcmd_idx = i;
14257 break;
14258 }
14259
50508d94
JB
14260 if (vcmd_idx < 0) {
14261 err = -EOPNOTSUPP;
14262 goto out;
14263 }
7bdbe400 14264
c90c39da
JB
14265 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
14266 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
14267 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
14268
14269 err = nl80211_vendor_check_policy(
14270 &(*rdev)->wiphy.vendor_commands[vcmd_idx],
14271 attrbuf[NL80211_ATTR_VENDOR_DATA],
14272 cb->extack);
14273 if (err)
50508d94 14274 goto out;
7bdbe400
JB
14275 }
14276
14277 /* 0 is the first index - add 1 to parse only once */
14278 cb->args[0] = (*rdev)->wiphy_idx + 1;
14279 /* add 1 to know if it was NULL */
14280 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
14281 cb->args[2] = vcmd_idx;
14282 cb->args[3] = (unsigned long)data;
14283 cb->args[4] = data_len;
14284
14285 /* keep rtnl locked in successful case */
50508d94
JB
14286 err = 0;
14287out:
14288 kfree(attrbuf);
14289 return err;
7bdbe400
JB
14290}
14291
14292static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
14293 struct netlink_callback *cb)
14294{
14295 struct cfg80211_registered_device *rdev;
14296 struct wireless_dev *wdev;
14297 unsigned int vcmd_idx;
14298 const struct wiphy_vendor_command *vcmd;
14299 void *data;
14300 int data_len;
14301 int err;
14302 struct nlattr *vendor_data;
14303
ea90e0dc 14304 rtnl_lock();
7bdbe400
JB
14305 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
14306 if (err)
ea90e0dc 14307 goto out;
7bdbe400
JB
14308
14309 vcmd_idx = cb->args[2];
14310 data = (void *)cb->args[3];
14311 data_len = cb->args[4];
14312 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
14313
14314 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
14315 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
14316 if (!wdev) {
14317 err = -EINVAL;
14318 goto out;
14319 }
7bdbe400 14320 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
14321 !wdev->netdev) {
14322 err = -EINVAL;
14323 goto out;
14324 }
7bdbe400
JB
14325
14326 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
14327 if (!wdev_running(wdev)) {
14328 err = -ENETDOWN;
14329 goto out;
14330 }
7bdbe400
JB
14331 }
14332 }
14333
14334 while (1) {
14335 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
14336 cb->nlh->nlmsg_seq, NLM_F_MULTI,
14337 NL80211_CMD_VENDOR);
14338 if (!hdr)
14339 break;
14340
14341 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
14342 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
14343 wdev_id(wdev),
14344 NL80211_ATTR_PAD))) {
7bdbe400
JB
14345 genlmsg_cancel(skb, hdr);
14346 break;
14347 }
14348
ae0be8de
MK
14349 vendor_data = nla_nest_start_noflag(skb,
14350 NL80211_ATTR_VENDOR_DATA);
7bdbe400
JB
14351 if (!vendor_data) {
14352 genlmsg_cancel(skb, hdr);
14353 break;
14354 }
14355
14356 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
14357 (unsigned long *)&cb->args[5]);
14358 nla_nest_end(skb, vendor_data);
14359
14360 if (err == -ENOBUFS || err == -ENOENT) {
14361 genlmsg_cancel(skb, hdr);
14362 break;
9c167b2d 14363 } else if (err <= 0) {
7bdbe400
JB
14364 genlmsg_cancel(skb, hdr);
14365 goto out;
14366 }
14367
14368 genlmsg_end(skb, hdr);
14369 }
14370
14371 err = skb->len;
14372 out:
14373 rtnl_unlock();
14374 return err;
14375}
14376
ad7e718c
JB
14377struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
14378 enum nl80211_commands cmd,
14379 enum nl80211_attrs attr,
14380 int approxlen)
14381{
f26cbf40 14382 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
14383
14384 if (WARN_ON(!rdev->cur_cmd_info))
14385 return NULL;
14386
6c09e791 14387 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
14388 rdev->cur_cmd_info->snd_portid,
14389 rdev->cur_cmd_info->snd_seq,
567ffc35 14390 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
14391}
14392EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
14393
14394int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
14395{
14396 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
14397 void *hdr = ((void **)skb->cb)[1];
14398 struct nlattr *data = ((void **)skb->cb)[2];
14399
bd8c78e7
JB
14400 /* clear CB data for netlink core to own from now on */
14401 memset(skb->cb, 0, sizeof(skb->cb));
14402
ad7e718c
JB
14403 if (WARN_ON(!rdev->cur_cmd_info)) {
14404 kfree_skb(skb);
14405 return -EINVAL;
14406 }
14407
14408 nla_nest_end(skb, data);
14409 genlmsg_end(skb, hdr);
14410 return genlmsg_reply(skb, rdev->cur_cmd_info);
14411}
14412EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
14413
55c1fdf0
JB
14414unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy)
14415{
14416 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14417
14418 if (WARN_ON(!rdev->cur_cmd_info))
14419 return 0;
14420
14421 return rdev->cur_cmd_info->snd_portid;
14422}
14423EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender);
14424
fa9ffc74
KP
14425static int nl80211_set_qos_map(struct sk_buff *skb,
14426 struct genl_info *info)
14427{
14428 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14429 struct cfg80211_qos_map *qos_map = NULL;
14430 struct net_device *dev = info->user_ptr[1];
14431 u8 *pos, len, num_des, des_len, des;
14432 int ret;
14433
14434 if (!rdev->ops->set_qos_map)
14435 return -EOPNOTSUPP;
14436
14437 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
14438 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
14439 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
14440
c8b82802 14441 if (len % 2)
fa9ffc74
KP
14442 return -EINVAL;
14443
14444 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
14445 if (!qos_map)
14446 return -ENOMEM;
14447
14448 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
14449 if (num_des) {
14450 des_len = num_des *
14451 sizeof(struct cfg80211_dscp_exception);
14452 memcpy(qos_map->dscp_exception, pos, des_len);
14453 qos_map->num_des = num_des;
14454 for (des = 0; des < num_des; des++) {
14455 if (qos_map->dscp_exception[des].up > 7) {
14456 kfree(qos_map);
14457 return -EINVAL;
14458 }
14459 }
14460 pos += des_len;
14461 }
14462 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
14463 }
14464
14465 wdev_lock(dev->ieee80211_ptr);
14466 ret = nl80211_key_allowed(dev->ieee80211_ptr);
14467 if (!ret)
14468 ret = rdev_set_qos_map(rdev, dev, qos_map);
14469 wdev_unlock(dev->ieee80211_ptr);
14470
14471 kfree(qos_map);
14472 return ret;
14473}
14474
960d01ac
JB
14475static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
14476{
14477 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14478 struct net_device *dev = info->user_ptr[1];
14479 struct wireless_dev *wdev = dev->ieee80211_ptr;
14480 const u8 *peer;
14481 u8 tsid, up;
14482 u16 admitted_time = 0;
14483 int err;
14484
723e73ac 14485 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
14486 return -EOPNOTSUPP;
14487
14488 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
14489 !info->attrs[NL80211_ATTR_USER_PRIO])
14490 return -EINVAL;
14491
14492 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
960d01ac 14493 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
960d01ac
JB
14494
14495 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 14496 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 14497 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
14498 * need more attributes for that (e.g. BA session requirement);
14499 * change the WMM adminssion test above to allow both then
960d01ac
JB
14500 */
14501 return -EINVAL;
14502 }
14503
14504 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14505
14506 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
14507 admitted_time =
14508 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
14509 if (!admitted_time)
14510 return -EINVAL;
14511 }
14512
14513 wdev_lock(wdev);
14514 switch (wdev->iftype) {
14515 case NL80211_IFTYPE_STATION:
14516 case NL80211_IFTYPE_P2P_CLIENT:
14517 if (wdev->current_bss)
14518 break;
14519 err = -ENOTCONN;
14520 goto out;
14521 default:
14522 err = -EOPNOTSUPP;
14523 goto out;
14524 }
14525
14526 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
14527
14528 out:
14529 wdev_unlock(wdev);
14530 return err;
14531}
14532
14533static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
14534{
14535 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14536 struct net_device *dev = info->user_ptr[1];
14537 struct wireless_dev *wdev = dev->ieee80211_ptr;
14538 const u8 *peer;
14539 u8 tsid;
14540 int err;
14541
14542 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
14543 return -EINVAL;
14544
14545 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
14546 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14547
14548 wdev_lock(wdev);
14549 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
14550 wdev_unlock(wdev);
14551
14552 return err;
14553}
14554
1057d35e
AN
14555static int nl80211_tdls_channel_switch(struct sk_buff *skb,
14556 struct genl_info *info)
14557{
14558 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14559 struct net_device *dev = info->user_ptr[1];
14560 struct wireless_dev *wdev = dev->ieee80211_ptr;
14561 struct cfg80211_chan_def chandef = {};
14562 const u8 *addr;
14563 u8 oper_class;
14564 int err;
14565
14566 if (!rdev->ops->tdls_channel_switch ||
14567 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
14568 return -EOPNOTSUPP;
14569
14570 switch (dev->ieee80211_ptr->iftype) {
14571 case NL80211_IFTYPE_STATION:
14572 case NL80211_IFTYPE_P2P_CLIENT:
14573 break;
14574 default:
14575 return -EOPNOTSUPP;
14576 }
14577
14578 if (!info->attrs[NL80211_ATTR_MAC] ||
14579 !info->attrs[NL80211_ATTR_OPER_CLASS])
14580 return -EINVAL;
14581
14582 err = nl80211_parse_chandef(rdev, info, &chandef);
14583 if (err)
14584 return err;
14585
14586 /*
14587 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
14588 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
14589 * specification is not defined for them.
14590 */
57fbcce3 14591 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
14592 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
14593 chandef.width != NL80211_CHAN_WIDTH_20)
14594 return -EINVAL;
14595
14596 /* we will be active on the TDLS link */
923b352f
AN
14597 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
14598 wdev->iftype))
1057d35e
AN
14599 return -EINVAL;
14600
14601 /* don't allow switching to DFS channels */
14602 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
14603 return -EINVAL;
14604
14605 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
14606 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
14607
14608 wdev_lock(wdev);
14609 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
14610 wdev_unlock(wdev);
14611
14612 return err;
14613}
14614
14615static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
14616 struct genl_info *info)
14617{
14618 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14619 struct net_device *dev = info->user_ptr[1];
14620 struct wireless_dev *wdev = dev->ieee80211_ptr;
14621 const u8 *addr;
14622
14623 if (!rdev->ops->tdls_channel_switch ||
14624 !rdev->ops->tdls_cancel_channel_switch ||
14625 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
14626 return -EOPNOTSUPP;
14627
14628 switch (dev->ieee80211_ptr->iftype) {
14629 case NL80211_IFTYPE_STATION:
14630 case NL80211_IFTYPE_P2P_CLIENT:
14631 break;
14632 default:
14633 return -EOPNOTSUPP;
14634 }
14635
14636 if (!info->attrs[NL80211_ATTR_MAC])
14637 return -EINVAL;
14638
14639 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
14640
14641 wdev_lock(wdev);
14642 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
14643 wdev_unlock(wdev);
14644
14645 return 0;
14646}
14647
ce0ce13a
MB
14648static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
14649 struct genl_info *info)
14650{
14651 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14652 struct net_device *dev = info->user_ptr[1];
14653 struct wireless_dev *wdev = dev->ieee80211_ptr;
14654 const struct nlattr *nla;
14655 bool enabled;
14656
ce0ce13a
MB
14657 if (!rdev->ops->set_multicast_to_unicast)
14658 return -EOPNOTSUPP;
14659
14660 if (wdev->iftype != NL80211_IFTYPE_AP &&
14661 wdev->iftype != NL80211_IFTYPE_P2P_GO)
14662 return -EOPNOTSUPP;
14663
14664 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
14665 enabled = nla_get_flag(nla);
14666
14667 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
14668}
14669
3a00df57
AS
14670static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
14671{
14672 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14673 struct net_device *dev = info->user_ptr[1];
14674 struct wireless_dev *wdev = dev->ieee80211_ptr;
14675 struct cfg80211_pmk_conf pmk_conf = {};
14676 int ret;
14677
14678 if (wdev->iftype != NL80211_IFTYPE_STATION &&
14679 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
14680 return -EOPNOTSUPP;
14681
14682 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14683 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
14684 return -EOPNOTSUPP;
14685
14686 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
14687 return -EINVAL;
14688
14689 wdev_lock(wdev);
14690 if (!wdev->current_bss) {
14691 ret = -ENOTCONN;
14692 goto out;
14693 }
14694
14695 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
14696 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
14697 ret = -EINVAL;
14698 goto out;
14699 }
14700
14701 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
14702 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
14703 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
14704 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
14705 ret = -EINVAL;
14706 goto out;
14707 }
14708
cb9abd48 14709 if (info->attrs[NL80211_ATTR_PMKR0_NAME])
3a00df57
AS
14710 pmk_conf.pmk_r0_name =
14711 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
3a00df57
AS
14712
14713 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
14714out:
14715 wdev_unlock(wdev);
14716 return ret;
14717}
14718
14719static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
14720{
14721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14722 struct net_device *dev = info->user_ptr[1];
14723 struct wireless_dev *wdev = dev->ieee80211_ptr;
14724 const u8 *aa;
14725 int ret;
14726
14727 if (wdev->iftype != NL80211_IFTYPE_STATION &&
14728 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
14729 return -EOPNOTSUPP;
14730
14731 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14732 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
14733 return -EOPNOTSUPP;
14734
14735 if (!info->attrs[NL80211_ATTR_MAC])
14736 return -EINVAL;
14737
14738 wdev_lock(wdev);
14739 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
14740 ret = rdev_del_pmk(rdev, dev, aa);
14741 wdev_unlock(wdev);
14742
14743 return ret;
14744}
14745
40cbfa90
SD
14746static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
14747{
14748 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14749 struct net_device *dev = info->user_ptr[1];
14750 struct cfg80211_external_auth_params params;
14751
db8d93a7 14752 if (!rdev->ops->external_auth)
40cbfa90
SD
14753 return -EOPNOTSUPP;
14754
fe494370
SD
14755 if (!info->attrs[NL80211_ATTR_SSID] &&
14756 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
14757 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
40cbfa90
SD
14758 return -EINVAL;
14759
14760 if (!info->attrs[NL80211_ATTR_BSSID])
14761 return -EINVAL;
14762
14763 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
14764 return -EINVAL;
14765
14766 memset(&params, 0, sizeof(params));
14767
fe494370
SD
14768 if (info->attrs[NL80211_ATTR_SSID]) {
14769 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
cb9abd48 14770 if (params.ssid.ssid_len == 0)
fe494370
SD
14771 return -EINVAL;
14772 memcpy(params.ssid.ssid,
14773 nla_data(info->attrs[NL80211_ATTR_SSID]),
14774 params.ssid.ssid_len);
14775 }
40cbfa90
SD
14776
14777 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
14778 ETH_ALEN);
14779
14780 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
14781
fe494370
SD
14782 if (info->attrs[NL80211_ATTR_PMKID])
14783 params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
14784
40cbfa90
SD
14785 return rdev_external_auth(rdev, dev, &params);
14786}
14787
2576a9ac
DK
14788static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
14789{
dca9ca2d 14790 bool dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
2576a9ac
DK
14791 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14792 struct net_device *dev = info->user_ptr[1];
14793 struct wireless_dev *wdev = dev->ieee80211_ptr;
14794 const u8 *buf;
14795 size_t len;
14796 u8 *dest;
14797 u16 proto;
14798 bool noencrypt;
dca9ca2d 14799 u64 cookie = 0;
2576a9ac
DK
14800 int err;
14801
14802 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14803 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
14804 return -EOPNOTSUPP;
14805
14806 if (!rdev->ops->tx_control_port)
14807 return -EOPNOTSUPP;
14808
14809 if (!info->attrs[NL80211_ATTR_FRAME] ||
14810 !info->attrs[NL80211_ATTR_MAC] ||
14811 !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
14812 GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
14813 return -EINVAL;
14814 }
14815
14816 wdev_lock(wdev);
14817
14818 switch (wdev->iftype) {
14819 case NL80211_IFTYPE_AP:
14820 case NL80211_IFTYPE_P2P_GO:
14821 case NL80211_IFTYPE_MESH_POINT:
14822 break;
14823 case NL80211_IFTYPE_ADHOC:
14824 case NL80211_IFTYPE_STATION:
14825 case NL80211_IFTYPE_P2P_CLIENT:
14826 if (wdev->current_bss)
14827 break;
14828 err = -ENOTCONN;
14829 goto out;
14830 default:
14831 err = -EOPNOTSUPP;
14832 goto out;
14833 }
14834
14835 wdev_unlock(wdev);
14836
14837 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
14838 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
14839 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
14840 proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
14841 noencrypt =
14842 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
14843
dca9ca2d
MT
14844 err = rdev_tx_control_port(rdev, dev, buf, len,
14845 dest, cpu_to_be16(proto), noencrypt,
14846 dont_wait_for_ack ? NULL : &cookie);
14847 if (!err && !dont_wait_for_ack)
14848 nl_set_extack_cookie_u64(info->extack, cookie);
14849 return err;
2576a9ac
DK
14850 out:
14851 wdev_unlock(wdev);
14852 return err;
14853}
14854
81e54d08
PKC
14855static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
14856 struct genl_info *info)
14857{
14858 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14859 struct net_device *dev = info->user_ptr[1];
14860 struct wireless_dev *wdev = dev->ieee80211_ptr;
14861 struct cfg80211_ftm_responder_stats ftm_stats = {};
14862 struct sk_buff *msg;
14863 void *hdr;
14864 struct nlattr *ftm_stats_attr;
14865 int err;
14866
14867 if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval)
14868 return -EOPNOTSUPP;
14869
14870 err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
14871 if (err)
14872 return err;
14873
14874 if (!ftm_stats.filled)
14875 return -ENODATA;
14876
14877 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14878 if (!msg)
14879 return -ENOMEM;
14880
14881 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
14882 NL80211_CMD_GET_FTM_RESPONDER_STATS);
14883 if (!hdr)
1399c59f 14884 goto nla_put_failure;
81e54d08
PKC
14885
14886 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
14887 goto nla_put_failure;
14888
ae0be8de
MK
14889 ftm_stats_attr = nla_nest_start_noflag(msg,
14890 NL80211_ATTR_FTM_RESPONDER_STATS);
81e54d08
PKC
14891 if (!ftm_stats_attr)
14892 goto nla_put_failure;
14893
14894#define SET_FTM(field, name, type) \
14895 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
14896 nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name, \
14897 ftm_stats.field)) \
14898 goto nla_put_failure; } while (0)
14899#define SET_FTM_U64(field, name) \
14900 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
14901 nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name, \
14902 ftm_stats.field, NL80211_FTM_STATS_PAD)) \
14903 goto nla_put_failure; } while (0)
14904
14905 SET_FTM(success_num, SUCCESS_NUM, u32);
14906 SET_FTM(partial_num, PARTIAL_NUM, u32);
14907 SET_FTM(failed_num, FAILED_NUM, u32);
14908 SET_FTM(asap_num, ASAP_NUM, u32);
14909 SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
14910 SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
14911 SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
14912 SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
14913 SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
14914#undef SET_FTM
14915
14916 nla_nest_end(msg, ftm_stats_attr);
14917
14918 genlmsg_end(msg, hdr);
14919 return genlmsg_reply(msg, info);
14920
14921nla_put_failure:
14922 nlmsg_free(msg);
14923 return -ENOBUFS;
14924}
14925
cb74e977
SD
14926static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
14927{
14928 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14929 struct cfg80211_update_owe_info owe_info;
14930 struct net_device *dev = info->user_ptr[1];
14931
14932 if (!rdev->ops->update_owe_info)
14933 return -EOPNOTSUPP;
14934
14935 if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
14936 !info->attrs[NL80211_ATTR_MAC])
14937 return -EINVAL;
14938
14939 memset(&owe_info, 0, sizeof(owe_info));
14940 owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
14941 nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
14942
14943 if (info->attrs[NL80211_ATTR_IE]) {
14944 owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
14945 owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
14946 }
14947
14948 return rdev_update_owe_info(rdev, dev, &owe_info);
14949}
14950
5ab92e7f
RM
14951static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
14952{
14953 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14954 struct net_device *dev = info->user_ptr[1];
14955 struct wireless_dev *wdev = dev->ieee80211_ptr;
14956 struct station_info sinfo = {};
14957 const u8 *buf;
14958 size_t len;
14959 u8 *dest;
14960 int err;
14961
14962 if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
14963 return -EOPNOTSUPP;
14964
14965 if (!info->attrs[NL80211_ATTR_MAC] ||
14966 !info->attrs[NL80211_ATTR_FRAME]) {
14967 GENL_SET_ERR_MSG(info, "Frame or MAC missing");
14968 return -EINVAL;
14969 }
14970
14971 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
14972 return -EOPNOTSUPP;
14973
14974 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
14975 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
14976 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
14977
14978 if (len < sizeof(struct ethhdr))
14979 return -EINVAL;
14980
14981 if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
14982 !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
14983 return -EINVAL;
14984
14985 err = rdev_get_station(rdev, dev, dest, &sinfo);
14986 if (err)
14987 return err;
14988
2a279b34
FF
14989 cfg80211_sinfo_release_content(&sinfo);
14990
5ab92e7f
RM
14991 return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
14992}
14993
77f576de
T
14994static int parse_tid_conf(struct cfg80211_registered_device *rdev,
14995 struct nlattr *attrs[], struct net_device *dev,
3710a8a6 14996 struct cfg80211_tid_cfg *tid_conf,
77f576de
T
14997 struct genl_info *info, const u8 *peer)
14998{
14999 struct netlink_ext_ack *extack = info->extack;
3710a8a6 15000 u64 mask;
77f576de
T
15001 int err;
15002
15003 if (!attrs[NL80211_TID_CONFIG_ATTR_TIDS])
15004 return -EINVAL;
15005
15006 tid_conf->config_override =
15007 nla_get_flag(attrs[NL80211_TID_CONFIG_ATTR_OVERRIDE]);
3710a8a6 15008 tid_conf->tids = nla_get_u16(attrs[NL80211_TID_CONFIG_ATTR_TIDS]);
77f576de
T
15009
15010 if (tid_conf->config_override) {
15011 if (rdev->ops->reset_tid_config) {
15012 err = rdev_reset_tid_config(rdev, dev, peer,
3710a8a6 15013 tid_conf->tids);
c0336955 15014 if (err)
77f576de
T
15015 return err;
15016 } else {
15017 return -EINVAL;
15018 }
15019 }
15020
15021 if (attrs[NL80211_TID_CONFIG_ATTR_NOACK]) {
3710a8a6 15022 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_NOACK);
77f576de
T
15023 tid_conf->noack =
15024 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_NOACK]);
15025 }
15026
6a21d16c
T
15027 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]) {
15028 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT);
15029 tid_conf->retry_short =
15030 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]);
15031
15032 if (tid_conf->retry_short > rdev->wiphy.max_data_retry_count)
15033 return -EINVAL;
15034 }
15035
15036 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]) {
15037 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
15038 tid_conf->retry_long =
15039 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]);
15040
15041 if (tid_conf->retry_long > rdev->wiphy.max_data_retry_count)
15042 return -EINVAL;
15043 }
15044
ade274b2
T
15045 if (attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]) {
15046 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
15047 tid_conf->ampdu =
15048 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]);
15049 }
15050
04f7d142
T
15051 if (attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]) {
15052 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
15053 tid_conf->rtscts =
15054 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]);
15055 }
15056
33462e68
SM
15057 if (attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]) {
15058 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL);
15059 tid_conf->amsdu =
15060 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]);
15061 }
15062
9a5f6488
TC
15063 if (attrs[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE]) {
15064 u32 idx = NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, attr;
15065
15066 tid_conf->txrate_type = nla_get_u8(attrs[idx]);
15067
15068 if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) {
15069 attr = NL80211_TID_CONFIG_ATTR_TX_RATE;
15070 err = nl80211_parse_tx_bitrate_mask(info, attrs, attr,
857b34c4
RM
15071 &tid_conf->txrate_mask, dev,
15072 true);
9a5f6488
TC
15073 if (err)
15074 return err;
15075
15076 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE);
15077 }
15078 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);
15079 }
15080
3710a8a6
JB
15081 if (peer)
15082 mask = rdev->wiphy.tid_config_support.peer;
15083 else
15084 mask = rdev->wiphy.tid_config_support.vif;
15085
15086 if (tid_conf->mask & ~mask) {
15087 NL_SET_ERR_MSG(extack, "unsupported TID configuration");
15088 return -ENOTSUPP;
15089 }
15090
77f576de
T
15091 return 0;
15092}
15093
15094static int nl80211_set_tid_config(struct sk_buff *skb,
15095 struct genl_info *info)
15096{
15097 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15098 struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1];
15099 struct net_device *dev = info->user_ptr[1];
3710a8a6 15100 struct cfg80211_tid_config *tid_config;
77f576de
T
15101 struct nlattr *tid;
15102 int conf_idx = 0, rem_conf;
15103 int ret = -EINVAL;
15104 u32 num_conf = 0;
15105
15106 if (!info->attrs[NL80211_ATTR_TID_CONFIG])
15107 return -EINVAL;
15108
15109 if (!rdev->ops->set_tid_config)
15110 return -EOPNOTSUPP;
15111
15112 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
15113 rem_conf)
15114 num_conf++;
15115
15116 tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf),
15117 GFP_KERNEL);
15118 if (!tid_config)
15119 return -ENOMEM;
15120
15121 tid_config->n_tid_conf = num_conf;
15122
15123 if (info->attrs[NL80211_ATTR_MAC])
15124 tid_config->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
15125
15126 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
15127 rem_conf) {
15128 ret = nla_parse_nested(attrs, NL80211_TID_CONFIG_ATTR_MAX,
15129 tid, NULL, NULL);
15130
15131 if (ret)
15132 goto bad_tid_conf;
15133
15134 ret = parse_tid_conf(rdev, attrs, dev,
15135 &tid_config->tid_conf[conf_idx],
15136 info, tid_config->peer);
15137 if (ret)
15138 goto bad_tid_conf;
15139
15140 conf_idx++;
15141 }
15142
15143 ret = rdev_set_tid_config(rdev, dev, tid_config);
15144
15145bad_tid_conf:
15146 kfree(tid_config);
15147 return ret;
15148}
15149
0d2ab3ae
JC
15150static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info)
15151{
15152 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15153 struct cfg80211_color_change_settings params = {};
15154 struct net_device *dev = info->user_ptr[1];
15155 struct wireless_dev *wdev = dev->ieee80211_ptr;
15156 struct nlattr **tb;
15157 u16 offset;
15158 int err;
15159
15160 if (!rdev->ops->color_change)
15161 return -EOPNOTSUPP;
15162
15163 if (!wiphy_ext_feature_isset(&rdev->wiphy,
15164 NL80211_EXT_FEATURE_BSS_COLOR))
15165 return -EOPNOTSUPP;
15166
15167 if (wdev->iftype != NL80211_IFTYPE_AP)
15168 return -EOPNOTSUPP;
15169
15170 if (!info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT] ||
15171 !info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR] ||
15172 !info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS])
15173 return -EINVAL;
15174
15175 params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]);
15176 params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]);
15177
15178 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_next);
15179 if (err)
15180 return err;
15181
15182 tb = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*tb), GFP_KERNEL);
15183 if (!tb)
15184 return -ENOMEM;
15185
15186 err = nla_parse_nested(tb, NL80211_ATTR_MAX,
15187 info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS],
15188 nl80211_policy, info->extack);
15189 if (err)
15190 goto out;
15191
15192 err = nl80211_parse_beacon(rdev, tb, &params.beacon_color_change);
15193 if (err)
15194 goto out;
15195
15196 if (!tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
15197 err = -EINVAL;
15198 goto out;
15199 }
15200
15201 if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) != sizeof(u16)) {
15202 err = -EINVAL;
15203 goto out;
15204 }
15205
15206 offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
15207 if (offset >= params.beacon_color_change.tail_len) {
15208 err = -EINVAL;
15209 goto out;
15210 }
15211
15212 if (params.beacon_color_change.tail[offset] != params.count) {
15213 err = -EINVAL;
15214 goto out;
15215 }
15216
15217 params.counter_offset_beacon = offset;
15218
15219 if (tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
15220 if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) !=
15221 sizeof(u16)) {
15222 err = -EINVAL;
15223 goto out;
15224 }
15225
15226 offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
15227 if (offset >= params.beacon_color_change.probe_resp_len) {
15228 err = -EINVAL;
15229 goto out;
15230 }
15231
15232 if (params.beacon_color_change.probe_resp[offset] !=
15233 params.count) {
15234 err = -EINVAL;
15235 goto out;
15236 }
15237
15238 params.counter_offset_presp = offset;
15239 }
15240
15241 wdev_lock(wdev);
15242 err = rdev_color_change(rdev, dev, &params);
15243 wdev_unlock(wdev);
15244
15245out:
dc1e3cb8
JC
15246 kfree(params.beacon_next.mbssid_ies);
15247 kfree(params.beacon_color_change.mbssid_ies);
0d2ab3ae
JC
15248 kfree(tb);
15249 return err;
15250}
15251
e306784a
SM
15252static int nl80211_set_fils_aad(struct sk_buff *skb,
15253 struct genl_info *info)
15254{
15255 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15256 struct net_device *dev = info->user_ptr[1];
15257 struct cfg80211_fils_aad fils_aad = {};
15258 u8 *nonces;
15259
15260 if (!info->attrs[NL80211_ATTR_MAC] ||
15261 !info->attrs[NL80211_ATTR_FILS_KEK] ||
15262 !info->attrs[NL80211_ATTR_FILS_NONCES])
15263 return -EINVAL;
15264
15265 fils_aad.macaddr = nla_data(info->attrs[NL80211_ATTR_MAC]);
15266 fils_aad.kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
15267 fils_aad.kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
15268 nonces = nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
15269 fils_aad.snonce = nonces;
15270 fils_aad.anonce = nonces + FILS_NONCE_LEN;
15271
15272 return rdev_set_fils_aad(rdev, dev, &fils_aad);
15273}
15274
4c476991
JB
15275#define NL80211_FLAG_NEED_WIPHY 0x01
15276#define NL80211_FLAG_NEED_NETDEV 0x02
15277#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
15278#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
15279#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
15280 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 15281#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 15282/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
15283#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
15284 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 15285#define NL80211_FLAG_CLEAR_SKB 0x20
77cbf790 15286#define NL80211_FLAG_NO_WIPHY_MTX 0x40
4c476991 15287
f84f771d 15288static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
15289 struct genl_info *info)
15290{
a05829a7 15291 struct cfg80211_registered_device *rdev = NULL;
89a54e48 15292 struct wireless_dev *wdev;
4c476991 15293 struct net_device *dev;
4c476991 15294
a05829a7 15295 rtnl_lock();
4c476991 15296 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 15297 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991 15298 if (IS_ERR(rdev)) {
a05829a7 15299 rtnl_unlock();
4c476991
JB
15300 return PTR_ERR(rdev);
15301 }
15302 info->user_ptr[0] = rdev;
1bf614ef
JB
15303 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
15304 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
a05829a7 15305 wdev = __cfg80211_wdev_from_attrs(NULL, genl_info_net(info),
89a54e48
JB
15306 info->attrs);
15307 if (IS_ERR(wdev)) {
a05829a7 15308 rtnl_unlock();
89a54e48 15309 return PTR_ERR(wdev);
4c476991 15310 }
89a54e48 15311
89a54e48 15312 dev = wdev->netdev;
f26cbf40 15313 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 15314
1bf614ef
JB
15315 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
15316 if (!dev) {
a05829a7 15317 rtnl_unlock();
1bf614ef
JB
15318 return -EINVAL;
15319 }
15320
15321 info->user_ptr[1] = dev;
15322 } else {
15323 info->user_ptr[1] = wdev;
41265714 15324 }
1bf614ef 15325
73c7da3d
AVS
15326 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
15327 !wdev_running(wdev)) {
a05829a7 15328 rtnl_unlock();
73c7da3d
AVS
15329 return -ENETDOWN;
15330 }
1bf614ef 15331
1160dfa1 15332 dev_hold(dev);
4c476991 15333 info->user_ptr[0] = rdev;
4c476991
JB
15334 }
15335
77cbf790 15336 if (rdev && !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
a05829a7
JB
15337 wiphy_lock(&rdev->wiphy);
15338 /* we keep the mutex locked until post_doit */
15339 __release(&rdev->wiphy.mtx);
15340 }
15341 if (!(ops->internal_flags & NL80211_FLAG_NEED_RTNL))
15342 rtnl_unlock();
15343
4c476991
JB
15344 return 0;
15345}
15346
f84f771d 15347static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
15348 struct genl_info *info)
15349{
1bf614ef
JB
15350 if (info->user_ptr[1]) {
15351 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
15352 struct wireless_dev *wdev = info->user_ptr[1];
15353
1160dfa1 15354 dev_put(wdev->netdev);
1bf614ef
JB
15355 } else {
15356 dev_put(info->user_ptr[1]);
15357 }
15358 }
5393b917 15359
77cbf790
JB
15360 if (info->user_ptr[0] &&
15361 !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
a05829a7
JB
15362 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15363
15364 /* we kept the mutex locked since pre_doit */
15365 __acquire(&rdev->wiphy.mtx);
15366 wiphy_unlock(&rdev->wiphy);
15367 }
15368
4c476991
JB
15369 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
15370 rtnl_unlock();
5393b917
JB
15371
15372 /* If needed, clear the netlink message payload from the SKB
15373 * as it might contain key data that shouldn't stick around on
15374 * the heap after the SKB is freed. The netlink message header
15375 * is still needed for further processing, so leave it intact.
15376 */
15377 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
15378 struct nlmsghdr *nlh = nlmsg_hdr(skb);
15379
15380 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
15381 }
4c476991
JB
15382}
15383
6bdb68ce
CH
15384static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
15385 struct cfg80211_sar_specs *sar_specs,
15386 struct nlattr *spec[], int index)
15387{
15388 u32 range_index, i;
15389
15390 if (!sar_specs || !spec)
15391 return -EINVAL;
15392
15393 if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
15394 !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
15395 return -EINVAL;
15396
15397 range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
15398
15399 /* check if range_index exceeds num_freq_ranges */
15400 if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
15401 return -EINVAL;
15402
15403 /* check if range_index duplicates */
15404 for (i = 0; i < index; i++) {
15405 if (sar_specs->sub_specs[i].freq_range_index == range_index)
15406 return -EINVAL;
15407 }
15408
15409 sar_specs->sub_specs[index].power =
15410 nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
15411
15412 sar_specs->sub_specs[index].freq_range_index = range_index;
15413
15414 return 0;
15415}
15416
15417static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
15418{
15419 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15420 struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
15421 struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
15422 struct cfg80211_sar_specs *sar_spec;
15423 enum nl80211_sar_type type;
15424 struct nlattr *spec_list;
15425 u32 specs;
15426 int rem, err;
15427
15428 if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
15429 return -EOPNOTSUPP;
15430
15431 if (!info->attrs[NL80211_ATTR_SAR_SPEC])
15432 return -EINVAL;
15433
15434 nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
15435 info->attrs[NL80211_ATTR_SAR_SPEC],
15436 NULL, NULL);
15437
15438 if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
15439 return -EINVAL;
15440
15441 type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
15442 if (type != rdev->wiphy.sar_capa->type)
15443 return -EINVAL;
15444
15445 specs = 0;
15446 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
15447 specs++;
15448
15449 if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
15450 return -EINVAL;
15451
40f231e7 15452 sar_spec = kzalloc(struct_size(sar_spec, sub_specs, specs), GFP_KERNEL);
6bdb68ce
CH
15453 if (!sar_spec)
15454 return -ENOMEM;
15455
15456 sar_spec->type = type;
15457 specs = 0;
15458 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
15459 nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
15460 spec_list, NULL, NULL);
15461
15462 switch (type) {
15463 case NL80211_SAR_TYPE_POWER:
15464 if (nl80211_set_sar_sub_specs(rdev, sar_spec,
15465 spec, specs)) {
15466 err = -EINVAL;
15467 goto error;
15468 }
15469 break;
15470 default:
15471 err = -EINVAL;
15472 goto error;
15473 }
15474 specs++;
15475 }
15476
15477 sar_spec->num_sub_specs = specs;
15478
15479 rdev->cur_cmd_info = info;
15480 err = rdev_set_sar_specs(rdev, sar_spec);
15481 rdev->cur_cmd_info = NULL;
15482error:
15483 kfree(sar_spec);
15484 return err;
15485}
15486
4534de83 15487static const struct genl_ops nl80211_ops[] = {
55682965
JB
15488 {
15489 .cmd = NL80211_CMD_GET_WIPHY,
ef6243ac 15490 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
15491 .doit = nl80211_get_wiphy,
15492 .dumpit = nl80211_dump_wiphy,
86e8cf98 15493 .done = nl80211_dump_wiphy_done,
55682965 15494 /* can be retrieved by unprivileged users */
a05829a7 15495 .internal_flags = NL80211_FLAG_NEED_WIPHY,
55682965 15496 },
66a9b928
JK
15497};
15498
15499static const struct genl_small_ops nl80211_small_ops[] = {
55682965
JB
15500 {
15501 .cmd = NL80211_CMD_SET_WIPHY,
ef6243ac 15502 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15503 .doit = nl80211_set_wiphy,
5617c6cd 15504 .flags = GENL_UNS_ADMIN_PERM,
55682965
JB
15505 },
15506 {
15507 .cmd = NL80211_CMD_GET_INTERFACE,
ef6243ac 15508 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
15509 .doit = nl80211_get_interface,
15510 .dumpit = nl80211_dump_interface,
55682965 15511 /* can be retrieved by unprivileged users */
a05829a7 15512 .internal_flags = NL80211_FLAG_NEED_WDEV,
55682965
JB
15513 },
15514 {
15515 .cmd = NL80211_CMD_SET_INTERFACE,
ef6243ac 15516 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15517 .doit = nl80211_set_interface,
5617c6cd 15518 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
15519 .internal_flags = NL80211_FLAG_NEED_NETDEV |
15520 NL80211_FLAG_NEED_RTNL,
55682965
JB
15521 },
15522 {
15523 .cmd = NL80211_CMD_NEW_INTERFACE,
ef6243ac 15524 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15525 .doit = nl80211_new_interface,
5617c6cd 15526 .flags = GENL_UNS_ADMIN_PERM,
4c476991 15527 .internal_flags = NL80211_FLAG_NEED_WIPHY |
ea6b2098
JB
15528 NL80211_FLAG_NEED_RTNL |
15529 /* we take the wiphy mutex later ourselves */
15530 NL80211_FLAG_NO_WIPHY_MTX,
55682965
JB
15531 },
15532 {
15533 .cmd = NL80211_CMD_DEL_INTERFACE,
ef6243ac 15534 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15535 .doit = nl80211_del_interface,
5617c6cd 15536 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 15537 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 15538 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
15539 },
15540 {
15541 .cmd = NL80211_CMD_GET_KEY,
ef6243ac 15542 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15543 .doit = nl80211_get_key,
5617c6cd 15544 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15545 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
41ade00f
JB
15546 },
15547 {
15548 .cmd = NL80211_CMD_SET_KEY,
ef6243ac 15549 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15550 .doit = nl80211_set_key,
5617c6cd 15551 .flags = GENL_UNS_ADMIN_PERM,
41265714 15552 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917 15553 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
15554 },
15555 {
15556 .cmd = NL80211_CMD_NEW_KEY,
ef6243ac 15557 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15558 .doit = nl80211_new_key,
5617c6cd 15559 .flags = GENL_UNS_ADMIN_PERM,
41265714 15560 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917 15561 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
15562 },
15563 {
15564 .cmd = NL80211_CMD_DEL_KEY,
ef6243ac 15565 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15566 .doit = nl80211_del_key,
5617c6cd 15567 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15568 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
55682965 15569 },
ed1b6cc7
JB
15570 {
15571 .cmd = NL80211_CMD_SET_BEACON,
ef6243ac 15572 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15573 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15574 .doit = nl80211_set_beacon,
a05829a7 15575 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7
JB
15576 },
15577 {
8860020e 15578 .cmd = NL80211_CMD_START_AP,
ef6243ac 15579 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15580 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15581 .doit = nl80211_start_ap,
a05829a7 15582 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7
JB
15583 },
15584 {
8860020e 15585 .cmd = NL80211_CMD_STOP_AP,
ef6243ac 15586 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15587 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15588 .doit = nl80211_stop_ap,
a05829a7 15589 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7 15590 },
5727ef1b
JB
15591 {
15592 .cmd = NL80211_CMD_GET_STATION,
ef6243ac 15593 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15594 .doit = nl80211_get_station,
2ec600d6 15595 .dumpit = nl80211_dump_station,
a05829a7 15596 .internal_flags = NL80211_FLAG_NEED_NETDEV,
5727ef1b
JB
15597 },
15598 {
15599 .cmd = NL80211_CMD_SET_STATION,
ef6243ac 15600 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15601 .doit = nl80211_set_station,
5617c6cd 15602 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15603 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5727ef1b
JB
15604 },
15605 {
15606 .cmd = NL80211_CMD_NEW_STATION,
ef6243ac 15607 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15608 .doit = nl80211_new_station,
5617c6cd 15609 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15610 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5727ef1b
JB
15611 },
15612 {
15613 .cmd = NL80211_CMD_DEL_STATION,
ef6243ac 15614 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15615 .doit = nl80211_del_station,
5617c6cd 15616 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15617 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15618 },
15619 {
15620 .cmd = NL80211_CMD_GET_MPATH,
ef6243ac 15621 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6
LCC
15622 .doit = nl80211_get_mpath,
15623 .dumpit = nl80211_dump_mpath,
5617c6cd 15624 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15625 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6 15626 },
66be7d2b
HR
15627 {
15628 .cmd = NL80211_CMD_GET_MPP,
ef6243ac 15629 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
66be7d2b
HR
15630 .doit = nl80211_get_mpp,
15631 .dumpit = nl80211_dump_mpp,
5617c6cd 15632 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15633 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
66be7d2b 15634 },
2ec600d6
LCC
15635 {
15636 .cmd = NL80211_CMD_SET_MPATH,
ef6243ac 15637 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15638 .doit = nl80211_set_mpath,
5617c6cd 15639 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15640 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15641 },
15642 {
15643 .cmd = NL80211_CMD_NEW_MPATH,
ef6243ac 15644 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15645 .doit = nl80211_new_mpath,
5617c6cd 15646 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15647 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15648 },
15649 {
15650 .cmd = NL80211_CMD_DEL_MPATH,
ef6243ac 15651 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15652 .doit = nl80211_del_mpath,
5617c6cd 15653 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15654 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
9f1ba906
JM
15655 },
15656 {
15657 .cmd = NL80211_CMD_SET_BSS,
ef6243ac 15658 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9f1ba906 15659 .doit = nl80211_set_bss,
5617c6cd 15660 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15661 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
b2e1b302 15662 },
f130347c
LR
15663 {
15664 .cmd = NL80211_CMD_GET_REG,
ef6243ac 15665 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad30ca2c
AN
15666 .doit = nl80211_get_reg_do,
15667 .dumpit = nl80211_get_reg_dump,
a05829a7 15668 .internal_flags = 0,
f130347c
LR
15669 /* can be retrieved by unprivileged users */
15670 },
b6863036 15671#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
15672 {
15673 .cmd = NL80211_CMD_SET_REG,
ef6243ac 15674 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 15675 .doit = nl80211_set_reg,
b2e1b302 15676 .flags = GENL_ADMIN_PERM,
a05829a7 15677 .internal_flags = 0,
b2e1b302 15678 },
b6863036 15679#endif
b2e1b302
LR
15680 {
15681 .cmd = NL80211_CMD_REQ_SET_REG,
ef6243ac 15682 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 15683 .doit = nl80211_req_set_reg,
93da9cc1 15684 .flags = GENL_ADMIN_PERM,
15685 },
1ea4ff3e
JB
15686 {
15687 .cmd = NL80211_CMD_RELOAD_REGDB,
ef6243ac 15688 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1ea4ff3e 15689 .doit = nl80211_reload_regdb,
1ea4ff3e
JB
15690 .flags = GENL_ADMIN_PERM,
15691 },
93da9cc1 15692 {
24bdd9f4 15693 .cmd = NL80211_CMD_GET_MESH_CONFIG,
ef6243ac 15694 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 15695 .doit = nl80211_get_mesh_config,
93da9cc1 15696 /* can be retrieved by unprivileged users */
a05829a7 15697 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
93da9cc1 15698 },
15699 {
24bdd9f4 15700 .cmd = NL80211_CMD_SET_MESH_CONFIG,
ef6243ac 15701 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 15702 .doit = nl80211_update_mesh_config,
5617c6cd 15703 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15704 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
9aed3cc1 15705 },
2a519311
JB
15706 {
15707 .cmd = NL80211_CMD_TRIGGER_SCAN,
ef6243ac 15708 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311 15709 .doit = nl80211_trigger_scan,
5617c6cd 15710 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15711 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
2a519311 15712 },
91d3ab46
VK
15713 {
15714 .cmd = NL80211_CMD_ABORT_SCAN,
ef6243ac 15715 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
91d3ab46 15716 .doit = nl80211_abort_scan,
5617c6cd 15717 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15718 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
91d3ab46 15719 },
2a519311
JB
15720 {
15721 .cmd = NL80211_CMD_GET_SCAN,
ef6243ac 15722 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311
JB
15723 .dumpit = nl80211_dump_scan,
15724 },
807f8a8c
LC
15725 {
15726 .cmd = NL80211_CMD_START_SCHED_SCAN,
ef6243ac 15727 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 15728 .doit = nl80211_start_sched_scan,
5617c6cd 15729 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15730 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
807f8a8c
LC
15731 },
15732 {
15733 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
ef6243ac 15734 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 15735 .doit = nl80211_stop_sched_scan,
5617c6cd 15736 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15737 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
807f8a8c 15738 },
636a5d36
JM
15739 {
15740 .cmd = NL80211_CMD_AUTHENTICATE,
ef6243ac 15741 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15742 .doit = nl80211_authenticate,
5617c6cd 15743 .flags = GENL_UNS_ADMIN_PERM,
41265714 15744 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15745 0 |
5393b917 15746 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
15747 },
15748 {
15749 .cmd = NL80211_CMD_ASSOCIATE,
ef6243ac 15750 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15751 .doit = nl80211_associate,
5617c6cd 15752 .flags = GENL_UNS_ADMIN_PERM,
41265714 15753 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15754 0 |
d6db02a8 15755 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
15756 },
15757 {
15758 .cmd = NL80211_CMD_DEAUTHENTICATE,
ef6243ac 15759 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15760 .doit = nl80211_deauthenticate,
5617c6cd 15761 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15762 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
636a5d36
JM
15763 },
15764 {
15765 .cmd = NL80211_CMD_DISASSOCIATE,
ef6243ac 15766 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15767 .doit = nl80211_disassociate,
5617c6cd 15768 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15769 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
636a5d36 15770 },
04a773ad
JB
15771 {
15772 .cmd = NL80211_CMD_JOIN_IBSS,
ef6243ac 15773 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 15774 .doit = nl80211_join_ibss,
5617c6cd 15775 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15776 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04a773ad
JB
15777 },
15778 {
15779 .cmd = NL80211_CMD_LEAVE_IBSS,
ef6243ac 15780 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 15781 .doit = nl80211_leave_ibss,
5617c6cd 15782 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15783 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04a773ad 15784 },
aff89a9b
JB
15785#ifdef CONFIG_NL80211_TESTMODE
15786 {
15787 .cmd = NL80211_CMD_TESTMODE,
ef6243ac 15788 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
aff89a9b 15789 .doit = nl80211_testmode_do,
71063f0e 15790 .dumpit = nl80211_testmode_dump,
5617c6cd 15791 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15792 .internal_flags = NL80211_FLAG_NEED_WIPHY,
aff89a9b
JB
15793 },
15794#endif
b23aa676
SO
15795 {
15796 .cmd = NL80211_CMD_CONNECT,
ef6243ac 15797 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 15798 .doit = nl80211_connect,
5617c6cd 15799 .flags = GENL_UNS_ADMIN_PERM,
41265714 15800 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15801 0 |
d6db02a8 15802 NL80211_FLAG_CLEAR_SKB,
b23aa676 15803 },
088e8df8 15804 {
15805 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
ef6243ac 15806 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
088e8df8 15807 .doit = nl80211_update_connect_params,
088e8df8 15808 .flags = GENL_ADMIN_PERM,
15809 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15810 0 |
d6db02a8 15811 NL80211_FLAG_CLEAR_SKB,
088e8df8 15812 },
b23aa676
SO
15813 {
15814 .cmd = NL80211_CMD_DISCONNECT,
ef6243ac 15815 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 15816 .doit = nl80211_disconnect,
5617c6cd 15817 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15818 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
b23aa676 15819 },
463d0183
JB
15820 {
15821 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
ef6243ac 15822 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
463d0183 15823 .doit = nl80211_wiphy_netns,
5617c6cd 15824 .flags = GENL_UNS_ADMIN_PERM,
77cbf790
JB
15825 .internal_flags = NL80211_FLAG_NEED_WIPHY |
15826 NL80211_FLAG_NEED_RTNL |
15827 NL80211_FLAG_NO_WIPHY_MTX,
463d0183 15828 },
61fa713c
HS
15829 {
15830 .cmd = NL80211_CMD_GET_SURVEY,
ef6243ac 15831 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
61fa713c
HS
15832 .dumpit = nl80211_dump_survey,
15833 },
67fbb16b
SO
15834 {
15835 .cmd = NL80211_CMD_SET_PMKSA,
ef6243ac 15836 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15837 .doit = nl80211_setdel_pmksa,
5617c6cd 15838 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 15839 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15840 0 |
d6db02a8 15841 NL80211_FLAG_CLEAR_SKB,
67fbb16b
SO
15842 },
15843 {
15844 .cmd = NL80211_CMD_DEL_PMKSA,
ef6243ac 15845 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15846 .doit = nl80211_setdel_pmksa,
5617c6cd 15847 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15848 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
67fbb16b
SO
15849 },
15850 {
15851 .cmd = NL80211_CMD_FLUSH_PMKSA,
ef6243ac 15852 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15853 .doit = nl80211_flush_pmksa,
5617c6cd 15854 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15855 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
67fbb16b 15856 },
9588bbd5
JM
15857 {
15858 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
ef6243ac 15859 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 15860 .doit = nl80211_remain_on_channel,
5617c6cd 15861 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15862 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9588bbd5
JM
15863 },
15864 {
15865 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
ef6243ac 15866 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 15867 .doit = nl80211_cancel_remain_on_channel,
5617c6cd 15868 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15869 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9588bbd5 15870 },
13ae75b1
JM
15871 {
15872 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
ef6243ac 15873 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
13ae75b1 15874 .doit = nl80211_set_tx_bitrate_mask,
5617c6cd 15875 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15876 .internal_flags = NL80211_FLAG_NEED_NETDEV,
13ae75b1 15877 },
026331c4 15878 {
2e161f78 15879 .cmd = NL80211_CMD_REGISTER_FRAME,
ef6243ac 15880 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 15881 .doit = nl80211_register_mgmt,
5617c6cd 15882 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15883 .internal_flags = NL80211_FLAG_NEED_WDEV,
026331c4
JM
15884 },
15885 {
2e161f78 15886 .cmd = NL80211_CMD_FRAME,
ef6243ac 15887 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 15888 .doit = nl80211_tx_mgmt,
5617c6cd 15889 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15890 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
f7ca38df
JB
15891 },
15892 {
15893 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
ef6243ac 15894 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f7ca38df 15895 .doit = nl80211_tx_mgmt_cancel_wait,
5617c6cd 15896 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15897 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
026331c4 15898 },
ffb9eb3d
KV
15899 {
15900 .cmd = NL80211_CMD_SET_POWER_SAVE,
ef6243ac 15901 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 15902 .doit = nl80211_set_power_save,
5617c6cd 15903 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15904 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ffb9eb3d
KV
15905 },
15906 {
15907 .cmd = NL80211_CMD_GET_POWER_SAVE,
ef6243ac 15908 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 15909 .doit = nl80211_get_power_save,
ffb9eb3d 15910 /* can be retrieved by unprivileged users */
a05829a7 15911 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ffb9eb3d 15912 },
d6dc1a38
JO
15913 {
15914 .cmd = NL80211_CMD_SET_CQM,
ef6243ac 15915 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
d6dc1a38 15916 .doit = nl80211_set_cqm,
5617c6cd 15917 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15918 .internal_flags = NL80211_FLAG_NEED_NETDEV,
d6dc1a38 15919 },
f444de05
JB
15920 {
15921 .cmd = NL80211_CMD_SET_CHANNEL,
ef6243ac 15922 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f444de05 15923 .doit = nl80211_set_channel,
5617c6cd 15924 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15925 .internal_flags = NL80211_FLAG_NEED_NETDEV,
f444de05 15926 },
29cbe68c
JB
15927 {
15928 .cmd = NL80211_CMD_JOIN_MESH,
ef6243ac 15929 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 15930 .doit = nl80211_join_mesh,
5617c6cd 15931 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15932 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
29cbe68c
JB
15933 },
15934 {
15935 .cmd = NL80211_CMD_LEAVE_MESH,
ef6243ac 15936 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 15937 .doit = nl80211_leave_mesh,
5617c6cd 15938 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15939 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
29cbe68c 15940 },
6e0bd6c3
RL
15941 {
15942 .cmd = NL80211_CMD_JOIN_OCB,
ef6243ac 15943 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 15944 .doit = nl80211_join_ocb,
5617c6cd 15945 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15946 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
6e0bd6c3
RL
15947 },
15948 {
15949 .cmd = NL80211_CMD_LEAVE_OCB,
ef6243ac 15950 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 15951 .doit = nl80211_leave_ocb,
5617c6cd 15952 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15953 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
6e0bd6c3 15954 },
dfb89c56 15955#ifdef CONFIG_PM
ff1b6e69
JB
15956 {
15957 .cmd = NL80211_CMD_GET_WOWLAN,
ef6243ac 15958 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 15959 .doit = nl80211_get_wowlan,
ff1b6e69 15960 /* can be retrieved by unprivileged users */
a05829a7 15961 .internal_flags = NL80211_FLAG_NEED_WIPHY,
ff1b6e69
JB
15962 },
15963 {
15964 .cmd = NL80211_CMD_SET_WOWLAN,
ef6243ac 15965 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 15966 .doit = nl80211_set_wowlan,
5617c6cd 15967 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15968 .internal_flags = NL80211_FLAG_NEED_WIPHY,
ff1b6e69 15969 },
dfb89c56 15970#endif
e5497d76
JB
15971 {
15972 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
ef6243ac 15973 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
e5497d76 15974 .doit = nl80211_set_rekey_data,
5617c6cd 15975 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 15976 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15977 0 |
5393b917 15978 NL80211_FLAG_CLEAR_SKB,
e5497d76 15979 },
109086ce
AN
15980 {
15981 .cmd = NL80211_CMD_TDLS_MGMT,
ef6243ac 15982 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 15983 .doit = nl80211_tdls_mgmt,
5617c6cd 15984 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15985 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
109086ce
AN
15986 },
15987 {
15988 .cmd = NL80211_CMD_TDLS_OPER,
ef6243ac 15989 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 15990 .doit = nl80211_tdls_oper,
5617c6cd 15991 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15992 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
109086ce 15993 },
28946da7
JB
15994 {
15995 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
ef6243ac 15996 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
28946da7 15997 .doit = nl80211_register_unexpected_frame,
5617c6cd 15998 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15999 .internal_flags = NL80211_FLAG_NEED_NETDEV,
28946da7 16000 },
7f6cf311
JB
16001 {
16002 .cmd = NL80211_CMD_PROBE_CLIENT,
ef6243ac 16003 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7f6cf311 16004 .doit = nl80211_probe_client,
5617c6cd 16005 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16006 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
7f6cf311 16007 },
5e760230
JB
16008 {
16009 .cmd = NL80211_CMD_REGISTER_BEACONS,
ef6243ac 16010 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5e760230 16011 .doit = nl80211_register_beacons,
5617c6cd 16012 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16013 .internal_flags = NL80211_FLAG_NEED_WIPHY,
5e760230 16014 },
1d9d9213
SW
16015 {
16016 .cmd = NL80211_CMD_SET_NOACK_MAP,
ef6243ac 16017 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1d9d9213 16018 .doit = nl80211_set_noack_map,
5617c6cd 16019 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16020 .internal_flags = NL80211_FLAG_NEED_NETDEV,
1d9d9213 16021 },
98104fde
JB
16022 {
16023 .cmd = NL80211_CMD_START_P2P_DEVICE,
ef6243ac 16024 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 16025 .doit = nl80211_start_p2p_device,
5617c6cd 16026 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
16027 .internal_flags = NL80211_FLAG_NEED_WDEV |
16028 NL80211_FLAG_NEED_RTNL,
16029 },
16030 {
16031 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
ef6243ac 16032 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 16033 .doit = nl80211_stop_p2p_device,
5617c6cd 16034 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
16035 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
16036 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
16037 },
16038 {
16039 .cmd = NL80211_CMD_START_NAN,
ef6243ac 16040 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 16041 .doit = nl80211_start_nan,
cb3b7d87
AB
16042 .flags = GENL_ADMIN_PERM,
16043 .internal_flags = NL80211_FLAG_NEED_WDEV |
16044 NL80211_FLAG_NEED_RTNL,
16045 },
16046 {
16047 .cmd = NL80211_CMD_STOP_NAN,
ef6243ac 16048 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 16049 .doit = nl80211_stop_nan,
cb3b7d87
AB
16050 .flags = GENL_ADMIN_PERM,
16051 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
16052 NL80211_FLAG_NEED_RTNL,
a442b761
AB
16053 },
16054 {
16055 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
ef6243ac 16056 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 16057 .doit = nl80211_nan_add_func,
a442b761 16058 .flags = GENL_ADMIN_PERM,
a05829a7 16059 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
a442b761
AB
16060 },
16061 {
16062 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
ef6243ac 16063 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 16064 .doit = nl80211_nan_del_func,
a442b761 16065 .flags = GENL_ADMIN_PERM,
a05829a7 16066 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
a5a9dcf2
AB
16067 },
16068 {
16069 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
ef6243ac 16070 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a5a9dcf2 16071 .doit = nl80211_nan_change_config,
a5a9dcf2 16072 .flags = GENL_ADMIN_PERM,
a05829a7 16073 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
98104fde 16074 },
f4e583c8
AQ
16075 {
16076 .cmd = NL80211_CMD_SET_MCAST_RATE,
ef6243ac 16077 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f4e583c8 16078 .doit = nl80211_set_mcast_rate,
5617c6cd 16079 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16080 .internal_flags = NL80211_FLAG_NEED_NETDEV,
77765eaf
VT
16081 },
16082 {
16083 .cmd = NL80211_CMD_SET_MAC_ACL,
ef6243ac 16084 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
77765eaf 16085 .doit = nl80211_set_mac_acl,
5617c6cd 16086 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16087 .internal_flags = NL80211_FLAG_NEED_NETDEV,
f4e583c8 16088 },
04f39047
SW
16089 {
16090 .cmd = NL80211_CMD_RADAR_DETECT,
ef6243ac 16091 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04f39047 16092 .doit = nl80211_start_radar_detection,
5617c6cd 16093 .flags = GENL_UNS_ADMIN_PERM,
84158164
LB
16094 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
16095 NL80211_FLAG_NO_WIPHY_MTX,
04f39047 16096 },
3713b4e3
JB
16097 {
16098 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
ef6243ac 16099 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3713b4e3 16100 .doit = nl80211_get_protocol_features,
3713b4e3 16101 },
355199e0
JM
16102 {
16103 .cmd = NL80211_CMD_UPDATE_FT_IES,
ef6243ac 16104 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
355199e0 16105 .doit = nl80211_update_ft_ies,
5617c6cd 16106 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16107 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
355199e0 16108 },
5de17984
AS
16109 {
16110 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
ef6243ac 16111 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 16112 .doit = nl80211_crit_protocol_start,
5617c6cd 16113 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16114 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
5de17984
AS
16115 },
16116 {
16117 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
ef6243ac 16118 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 16119 .doit = nl80211_crit_protocol_stop,
5617c6cd 16120 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16121 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
be29b99a
AK
16122 },
16123 {
16124 .cmd = NL80211_CMD_GET_COALESCE,
ef6243ac 16125 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 16126 .doit = nl80211_get_coalesce,
a05829a7 16127 .internal_flags = NL80211_FLAG_NEED_WIPHY,
be29b99a
AK
16128 },
16129 {
16130 .cmd = NL80211_CMD_SET_COALESCE,
ef6243ac 16131 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 16132 .doit = nl80211_set_coalesce,
5617c6cd 16133 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16134 .internal_flags = NL80211_FLAG_NEED_WIPHY,
16ef1fe2
SW
16135 },
16136 {
16137 .cmd = NL80211_CMD_CHANNEL_SWITCH,
ef6243ac 16138 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16ef1fe2 16139 .doit = nl80211_channel_switch,
5617c6cd 16140 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16141 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
16ef1fe2 16142 },
ad7e718c
JB
16143 {
16144 .cmd = NL80211_CMD_VENDOR,
ef6243ac 16145 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad7e718c 16146 .doit = nl80211_vendor_cmd,
7bdbe400 16147 .dumpit = nl80211_vendor_cmd_dump,
5617c6cd 16148 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c 16149 .internal_flags = NL80211_FLAG_NEED_WIPHY |
a05829a7 16150 0 |
d6db02a8 16151 NL80211_FLAG_CLEAR_SKB,
ad7e718c 16152 },
fa9ffc74
KP
16153 {
16154 .cmd = NL80211_CMD_SET_QOS_MAP,
ef6243ac 16155 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
fa9ffc74 16156 .doit = nl80211_set_qos_map,
5617c6cd 16157 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16158 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
fa9ffc74 16159 },
960d01ac
JB
16160 {
16161 .cmd = NL80211_CMD_ADD_TX_TS,
ef6243ac 16162 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 16163 .doit = nl80211_add_tx_ts,
5617c6cd 16164 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16165 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
960d01ac
JB
16166 },
16167 {
16168 .cmd = NL80211_CMD_DEL_TX_TS,
ef6243ac 16169 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 16170 .doit = nl80211_del_tx_ts,
5617c6cd 16171 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16172 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
960d01ac 16173 },
1057d35e
AN
16174 {
16175 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
ef6243ac 16176 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 16177 .doit = nl80211_tdls_channel_switch,
5617c6cd 16178 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16179 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
1057d35e
AN
16180 },
16181 {
16182 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
ef6243ac 16183 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 16184 .doit = nl80211_tdls_cancel_channel_switch,
5617c6cd 16185 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16186 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
1057d35e 16187 },
ce0ce13a
MB
16188 {
16189 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
ef6243ac 16190 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ce0ce13a 16191 .doit = nl80211_set_multicast_to_unicast,
ce0ce13a 16192 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16193 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ce0ce13a 16194 },
3a00df57
AS
16195 {
16196 .cmd = NL80211_CMD_SET_PMK,
ef6243ac 16197 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 16198 .doit = nl80211_set_pmk,
3a00df57 16199 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 16200 0 |
d6db02a8 16201 NL80211_FLAG_CLEAR_SKB,
3a00df57
AS
16202 },
16203 {
16204 .cmd = NL80211_CMD_DEL_PMK,
ef6243ac 16205 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 16206 .doit = nl80211_del_pmk,
a05829a7 16207 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
3a00df57 16208 },
40cbfa90
SD
16209 {
16210 .cmd = NL80211_CMD_EXTERNAL_AUTH,
ef6243ac 16211 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
40cbfa90 16212 .doit = nl80211_external_auth,
40cbfa90 16213 .flags = GENL_ADMIN_PERM,
a05829a7 16214 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
40cbfa90 16215 },
2576a9ac
DK
16216 {
16217 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
ef6243ac 16218 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2576a9ac 16219 .doit = nl80211_tx_control_port,
2576a9ac 16220 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16221 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2576a9ac 16222 },
81e54d08
PKC
16223 {
16224 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
ef6243ac 16225 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
81e54d08 16226 .doit = nl80211_get_ftm_responder_stats,
a05829a7 16227 .internal_flags = NL80211_FLAG_NEED_NETDEV,
81e54d08 16228 },
9bb7e0f2
JB
16229 {
16230 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
ef6243ac 16231 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9bb7e0f2 16232 .doit = nl80211_pmsr_start,
9bb7e0f2 16233 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16234 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9bb7e0f2 16235 },
30c63115
S
16236 {
16237 .cmd = NL80211_CMD_NOTIFY_RADAR,
ef6243ac 16238 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
30c63115 16239 .doit = nl80211_notify_radar_detection,
30c63115 16240 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16241 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
30c63115 16242 },
cb74e977
SD
16243 {
16244 .cmd = NL80211_CMD_UPDATE_OWE_INFO,
16245 .doit = nl80211_update_owe_info,
16246 .flags = GENL_ADMIN_PERM,
a05829a7 16247 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5ab92e7f
RM
16248 },
16249 {
16250 .cmd = NL80211_CMD_PROBE_MESH_LINK,
16251 .doit = nl80211_probe_mesh_link,
16252 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16253 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
cb74e977 16254 },
77f576de
T
16255 {
16256 .cmd = NL80211_CMD_SET_TID_CONFIG,
16257 .doit = nl80211_set_tid_config,
16258 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 16259 .internal_flags = NL80211_FLAG_NEED_NETDEV,
77f576de 16260 },
6bdb68ce
CH
16261 {
16262 .cmd = NL80211_CMD_SET_SAR_SPECS,
16263 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16264 .doit = nl80211_set_sar_specs,
16265 .flags = GENL_UNS_ADMIN_PERM,
16266 .internal_flags = NL80211_FLAG_NEED_WIPHY |
16267 NL80211_FLAG_NEED_RTNL,
16268 },
0d2ab3ae
JC
16269 {
16270 .cmd = NL80211_CMD_COLOR_CHANGE_REQUEST,
16271 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16272 .doit = nl80211_color_change,
16273 .flags = GENL_UNS_ADMIN_PERM,
16274 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
16275 NL80211_FLAG_NEED_RTNL,
16276 },
e306784a
SM
16277 {
16278 .cmd = NL80211_CMD_SET_FILS_AAD,
16279 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16280 .doit = nl80211_set_fils_aad,
16281 .flags = GENL_UNS_ADMIN_PERM,
16282 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
16283 },
55682965 16284};
9588bbd5 16285
56989f6d 16286static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
16287 .name = NL80211_GENL_NAME, /* have users key off the name instead */
16288 .hdrsize = 0, /* no private header */
16289 .version = 1, /* no particular meaning now */
16290 .maxattr = NL80211_ATTR_MAX,
3b0f31f2 16291 .policy = nl80211_policy,
489111e5
JB
16292 .netnsok = true,
16293 .pre_doit = nl80211_pre_doit,
16294 .post_doit = nl80211_post_doit,
16295 .module = THIS_MODULE,
16296 .ops = nl80211_ops,
16297 .n_ops = ARRAY_SIZE(nl80211_ops),
66a9b928
JK
16298 .small_ops = nl80211_small_ops,
16299 .n_small_ops = ARRAY_SIZE(nl80211_small_ops),
489111e5
JB
16300 .mcgrps = nl80211_mcgrps,
16301 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
50508d94 16302 .parallel_ops = true,
489111e5
JB
16303};
16304
55682965
JB
16305/* notification functions */
16306
3bb20556
JB
16307void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
16308 enum nl80211_commands cmd)
55682965
JB
16309{
16310 struct sk_buff *msg;
86e8cf98 16311 struct nl80211_dump_wiphy_state state = {};
55682965 16312
3bb20556
JB
16313 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
16314 cmd != NL80211_CMD_DEL_WIPHY);
16315
fd2120ca 16316 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
16317 if (!msg)
16318 return;
16319
3bb20556 16320 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
16321 nlmsg_free(msg);
16322 return;
16323 }
16324
68eb5503 16325 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16326 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
16327}
16328
896ff063
DK
16329void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
16330 struct wireless_dev *wdev,
16331 enum nl80211_commands cmd)
16332{
16333 struct sk_buff *msg;
16334
896ff063
DK
16335 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16336 if (!msg)
16337 return;
16338
3d1a5bbf 16339 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
896ff063
DK
16340 nlmsg_free(msg);
16341 return;
16342 }
16343
16344 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16345 NL80211_MCGRP_CONFIG, GFP_KERNEL);
16346}
16347
362a415d
JB
16348static int nl80211_add_scan_req(struct sk_buff *msg,
16349 struct cfg80211_registered_device *rdev)
16350{
16351 struct cfg80211_scan_request *req = rdev->scan_req;
16352 struct nlattr *nest;
16353 int i;
c8cb5b85 16354 struct cfg80211_scan_info *info;
362a415d
JB
16355
16356 if (WARN_ON(!req))
16357 return 0;
16358
ae0be8de 16359 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_SSIDS);
362a415d
JB
16360 if (!nest)
16361 goto nla_put_failure;
9360ffd1
DM
16362 for (i = 0; i < req->n_ssids; i++) {
16363 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
16364 goto nla_put_failure;
16365 }
362a415d
JB
16366 nla_nest_end(msg, nest);
16367
2032f3b2
TP
16368 if (req->flags & NL80211_SCAN_FLAG_FREQ_KHZ) {
16369 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQ_KHZ);
16370 if (!nest)
16371 goto nla_put_failure;
16372 for (i = 0; i < req->n_channels; i++) {
16373 if (nla_put_u32(msg, i,
16374 ieee80211_channel_to_khz(req->channels[i])))
16375 goto nla_put_failure;
16376 }
16377 nla_nest_end(msg, nest);
16378 } else {
16379 nest = nla_nest_start_noflag(msg,
16380 NL80211_ATTR_SCAN_FREQUENCIES);
16381 if (!nest)
9360ffd1 16382 goto nla_put_failure;
2032f3b2
TP
16383 for (i = 0; i < req->n_channels; i++) {
16384 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
16385 goto nla_put_failure;
16386 }
16387 nla_nest_end(msg, nest);
9360ffd1 16388 }
362a415d 16389
9360ffd1
DM
16390 if (req->ie &&
16391 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
16392 goto nla_put_failure;
362a415d 16393
ae917c9f
JB
16394 if (req->flags &&
16395 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
16396 goto nla_put_failure;
ed473771 16397
c8cb5b85
TM
16398 info = rdev->int_scan_req ? &rdev->int_scan_req->info :
16399 &rdev->scan_req->info;
16400 if (info->scan_start_tsf &&
1d76250b 16401 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
c8cb5b85 16402 info->scan_start_tsf, NL80211_BSS_PAD) ||
1d76250b 16403 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
c8cb5b85 16404 info->tsf_bssid)))
1d76250b
AS
16405 goto nla_put_failure;
16406
362a415d
JB
16407 return 0;
16408 nla_put_failure:
16409 return -ENOBUFS;
16410}
16411
505a2e88 16412static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 16413 struct cfg80211_registered_device *rdev,
fd014284 16414 struct wireless_dev *wdev,
15e47304 16415 u32 portid, u32 seq, int flags,
a538e2d5 16416 u32 cmd)
2a519311
JB
16417{
16418 void *hdr;
16419
15e47304 16420 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
16421 if (!hdr)
16422 return -1;
16423
9360ffd1 16424 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
16425 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16426 wdev->netdev->ifindex)) ||
2dad624e
ND
16427 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16428 NL80211_ATTR_PAD))
9360ffd1 16429 goto nla_put_failure;
2a519311 16430
362a415d
JB
16431 /* ignore errors and send incomplete event anyway */
16432 nl80211_add_scan_req(msg, rdev);
2a519311 16433
053c095a
JB
16434 genlmsg_end(msg, hdr);
16435 return 0;
2a519311
JB
16436
16437 nla_put_failure:
16438 genlmsg_cancel(msg, hdr);
16439 return -EMSGSIZE;
16440}
16441
807f8a8c 16442static int
505a2e88 16443nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 16444 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
16445{
16446 void *hdr;
16447
96b08fd6 16448 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
16449 if (!hdr)
16450 return -1;
16451
96b08fd6
AVS
16452 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
16453 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
16454 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
16455 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
16456 NL80211_ATTR_PAD))
9360ffd1 16457 goto nla_put_failure;
807f8a8c 16458
053c095a
JB
16459 genlmsg_end(msg, hdr);
16460 return 0;
807f8a8c
LC
16461
16462 nla_put_failure:
16463 genlmsg_cancel(msg, hdr);
16464 return -EMSGSIZE;
16465}
16466
a538e2d5 16467void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 16468 struct wireless_dev *wdev)
a538e2d5
JB
16469{
16470 struct sk_buff *msg;
16471
58050fce 16472 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
16473 if (!msg)
16474 return;
16475
505a2e88 16476 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
16477 NL80211_CMD_TRIGGER_SCAN) < 0) {
16478 nlmsg_free(msg);
16479 return;
16480 }
16481
68eb5503 16482 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16483 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
16484}
16485
f9d15d16
JB
16486struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
16487 struct wireless_dev *wdev, bool aborted)
2a519311
JB
16488{
16489 struct sk_buff *msg;
16490
fd2120ca 16491 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 16492 if (!msg)
f9d15d16 16493 return NULL;
2a519311 16494
505a2e88 16495 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
16496 aborted ? NL80211_CMD_SCAN_ABORTED :
16497 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 16498 nlmsg_free(msg);
f9d15d16 16499 return NULL;
2a519311
JB
16500 }
16501
f9d15d16 16502 return msg;
2a519311
JB
16503}
16504
505a2e88
AVS
16505/* send message created by nl80211_build_scan_msg() */
16506void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
16507 struct sk_buff *msg)
807f8a8c 16508{
807f8a8c
LC
16509 if (!msg)
16510 return;
16511
68eb5503 16512 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16513 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
16514}
16515
96b08fd6 16516void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
16517{
16518 struct sk_buff *msg;
16519
58050fce 16520 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
16521 if (!msg)
16522 return;
16523
96b08fd6 16524 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
16525 nlmsg_free(msg);
16526 return;
16527 }
16528
96b08fd6 16529 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 16530 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
16531}
16532
b0d7aa59
JD
16533static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
16534 struct regulatory_request *request)
73d54c9e 16535{
73d54c9e 16536 /* Userspace can always count this one always being set */
9360ffd1
DM
16537 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
16538 goto nla_put_failure;
16539
16540 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
16541 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16542 NL80211_REGDOM_TYPE_WORLD))
16543 goto nla_put_failure;
16544 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
16545 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16546 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
16547 goto nla_put_failure;
16548 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
16549 request->intersect) {
16550 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16551 NL80211_REGDOM_TYPE_INTERSECTION))
16552 goto nla_put_failure;
16553 } else {
16554 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16555 NL80211_REGDOM_TYPE_COUNTRY) ||
16556 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
16557 request->alpha2))
16558 goto nla_put_failure;
16559 }
16560
ad30ca2c
AN
16561 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
16562 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
16563
16564 if (wiphy &&
16565 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
16566 goto nla_put_failure;
1bdd716c
AN
16567
16568 if (wiphy &&
16569 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
16570 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
16571 goto nla_put_failure;
ad30ca2c 16572 }
73d54c9e 16573
b0d7aa59
JD
16574 return true;
16575
16576nla_put_failure:
16577 return false;
16578}
16579
16580/*
16581 * This can happen on global regulatory changes or device specific settings
16582 * based on custom regulatory domains.
16583 */
16584void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
16585 struct regulatory_request *request)
16586{
16587 struct sk_buff *msg;
16588 void *hdr;
16589
16590 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16591 if (!msg)
16592 return;
16593
16594 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
24f6d765 16595 if (!hdr)
16596 goto nla_put_failure;
b0d7aa59 16597
24f6d765 16598 if (!nl80211_reg_change_event_fill(msg, request))
b0d7aa59
JD
16599 goto nla_put_failure;
16600
3b7b72ee 16601 genlmsg_end(msg, hdr);
73d54c9e 16602
bc43b28c 16603 rcu_read_lock();
68eb5503 16604 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 16605 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 16606 rcu_read_unlock();
73d54c9e
LR
16607
16608 return;
16609
16610nla_put_failure:
73d54c9e
LR
16611 nlmsg_free(msg);
16612}
16613
6039f6d2
JM
16614static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
16615 struct net_device *netdev,
16616 const u8 *buf, size_t len,
b0b6aa2c 16617 enum nl80211_commands cmd, gfp_t gfp,
4d9ec73d 16618 int uapsd_queues, const u8 *req_ies,
3bb02143 16619 size_t req_ies_len, bool reconnect)
6039f6d2
JM
16620{
16621 struct sk_buff *msg;
16622 void *hdr;
16623
4d9ec73d 16624 msg = nlmsg_new(100 + len + req_ies_len, gfp);
6039f6d2
JM
16625 if (!msg)
16626 return;
16627
16628 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16629 if (!hdr) {
16630 nlmsg_free(msg);
16631 return;
16632 }
16633
9360ffd1
DM
16634 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16635 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
4d9ec73d
JM
16636 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
16637 (req_ies &&
16638 nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
9360ffd1 16639 goto nla_put_failure;
6039f6d2 16640
3bb02143
JB
16641 if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
16642 goto nla_put_failure;
16643
b0b6aa2c
EP
16644 if (uapsd_queues >= 0) {
16645 struct nlattr *nla_wmm =
ae0be8de 16646 nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
b0b6aa2c
EP
16647 if (!nla_wmm)
16648 goto nla_put_failure;
16649
16650 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
16651 uapsd_queues))
16652 goto nla_put_failure;
16653
16654 nla_nest_end(msg, nla_wmm);
16655 }
16656
3b7b72ee 16657 genlmsg_end(msg, hdr);
6039f6d2 16658
68eb5503 16659 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16660 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
16661 return;
16662
16663 nla_put_failure:
6039f6d2
JM
16664 nlmsg_free(msg);
16665}
16666
16667void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16668 struct net_device *netdev, const u8 *buf,
16669 size_t len, gfp_t gfp)
6039f6d2
JM
16670{
16671 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16672 NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0,
16673 false);
6039f6d2
JM
16674}
16675
16676void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
16677 struct net_device *netdev, const u8 *buf,
4d9ec73d
JM
16678 size_t len, gfp_t gfp, int uapsd_queues,
16679 const u8 *req_ies, size_t req_ies_len)
6039f6d2 16680{
e6d6e342 16681 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 16682 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
3bb02143 16683 req_ies, req_ies_len, false);
6039f6d2
JM
16684}
16685
53b46b84 16686void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342 16687 struct net_device *netdev, const u8 *buf,
3bb02143 16688 size_t len, bool reconnect, gfp_t gfp)
6039f6d2
JM
16689{
16690 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16691 NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0,
16692 reconnect);
6039f6d2
JM
16693}
16694
53b46b84
JM
16695void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
16696 struct net_device *netdev, const u8 *buf,
3bb02143 16697 size_t len, bool reconnect, gfp_t gfp)
6039f6d2
JM
16698{
16699 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16700 NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0,
16701 reconnect);
6039f6d2
JM
16702}
16703
6ff57cf8
JB
16704void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
16705 size_t len)
cf4e594e 16706{
947add36
JB
16707 struct wireless_dev *wdev = dev->ieee80211_ptr;
16708 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16709 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
16710 const struct ieee80211_mgmt *mgmt = (void *)buf;
16711 u32 cmd;
947add36 16712
6ff57cf8
JB
16713 if (WARN_ON(len < 2))
16714 return;
cf4e594e 16715
4d797fce 16716 if (ieee80211_is_deauth(mgmt->frame_control)) {
6ff57cf8 16717 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
4d797fce 16718 } else if (ieee80211_is_disassoc(mgmt->frame_control)) {
6ff57cf8 16719 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
4d797fce
JM
16720 } else if (ieee80211_is_beacon(mgmt->frame_control)) {
16721 if (wdev->unprot_beacon_reported &&
16722 elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
16723 return;
16724 cmd = NL80211_CMD_UNPROT_BEACON;
16725 wdev->unprot_beacon_reported = jiffies;
16726 } else {
16727 return;
16728 }
947add36 16729
6ff57cf8 16730 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
4d9ec73d 16731 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
3bb02143 16732 NULL, 0, false);
cf4e594e 16733}
6ff57cf8 16734EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 16735
1b06bb40
LR
16736static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
16737 struct net_device *netdev, int cmd,
e6d6e342 16738 const u8 *addr, gfp_t gfp)
1965c853
JM
16739{
16740 struct sk_buff *msg;
16741 void *hdr;
16742
e6d6e342 16743 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
16744 if (!msg)
16745 return;
16746
16747 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16748 if (!hdr) {
16749 nlmsg_free(msg);
16750 return;
16751 }
16752
9360ffd1
DM
16753 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16754 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16755 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
16756 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
16757 goto nla_put_failure;
1965c853 16758
3b7b72ee 16759 genlmsg_end(msg, hdr);
1965c853 16760
68eb5503 16761 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16762 NL80211_MCGRP_MLME, gfp);
1965c853
JM
16763 return;
16764
16765 nla_put_failure:
1965c853
JM
16766 nlmsg_free(msg);
16767}
16768
16769void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16770 struct net_device *netdev, const u8 *addr,
16771 gfp_t gfp)
1965c853
JM
16772{
16773 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 16774 addr, gfp);
1965c853
JM
16775}
16776
16777void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16778 struct net_device *netdev, const u8 *addr,
16779 gfp_t gfp)
1965c853 16780{
e6d6e342
JB
16781 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
16782 addr, gfp);
1965c853
JM
16783}
16784
b23aa676 16785void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
16786 struct net_device *netdev,
16787 struct cfg80211_connect_resp_params *cr,
3093ebbe 16788 gfp_t gfp)
b23aa676
SO
16789{
16790 struct sk_buff *msg;
16791 void *hdr;
16792
a3caf744 16793 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
76804d28
AVS
16794 cr->fils.kek_len + cr->fils.pmk_len +
16795 (cr->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
16796 if (!msg)
16797 return;
16798
16799 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
16800 if (!hdr) {
16801 nlmsg_free(msg);
16802 return;
16803 }
16804
9360ffd1
DM
16805 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16806 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
16807 (cr->bssid &&
16808 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 16809 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
16810 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
16811 cr->status) ||
16812 (cr->status < 0 &&
3093ebbe 16813 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
16814 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
16815 cr->timeout_reason))) ||
16816 (cr->req_ie &&
16817 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
16818 (cr->resp_ie &&
16819 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744 16820 cr->resp_ie)) ||
76804d28 16821 (cr->fils.update_erp_next_seq_num &&
a3caf744 16822 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
76804d28 16823 cr->fils.erp_next_seq_num)) ||
a3caf744 16824 (cr->status == WLAN_STATUS_SUCCESS &&
76804d28
AVS
16825 ((cr->fils.kek &&
16826 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
16827 cr->fils.kek)) ||
16828 (cr->fils.pmk &&
16829 nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
16830 (cr->fils.pmkid &&
16831 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
9360ffd1 16832 goto nla_put_failure;
b23aa676 16833
3b7b72ee 16834 genlmsg_end(msg, hdr);
b23aa676 16835
68eb5503 16836 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16837 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
16838 return;
16839
16840 nla_put_failure:
b23aa676 16841 nlmsg_free(msg);
b23aa676
SO
16842}
16843
16844void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
16845 struct net_device *netdev,
16846 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
16847{
16848 struct sk_buff *msg;
16849 void *hdr;
29ce6ecb 16850 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 16851
e841b7b1
AVS
16852 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
16853 info->fils.kek_len + info->fils.pmk_len +
16854 (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
16855 if (!msg)
16856 return;
16857
16858 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
16859 if (!hdr) {
16860 nlmsg_free(msg);
16861 return;
16862 }
16863
9360ffd1
DM
16864 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16865 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16866 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
16867 (info->req_ie &&
16868 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
16869 info->req_ie)) ||
16870 (info->resp_ie &&
16871 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
e841b7b1
AVS
16872 info->resp_ie)) ||
16873 (info->fils.update_erp_next_seq_num &&
16874 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
16875 info->fils.erp_next_seq_num)) ||
16876 (info->fils.kek &&
16877 nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
16878 info->fils.kek)) ||
16879 (info->fils.pmk &&
16880 nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
16881 (info->fils.pmkid &&
16882 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
9360ffd1 16883 goto nla_put_failure;
b23aa676 16884
3b7b72ee 16885 genlmsg_end(msg, hdr);
b23aa676 16886
68eb5503 16887 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16888 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
16889 return;
16890
503c1fb9 16891 nla_put_failure:
503c1fb9
AS
16892 nlmsg_free(msg);
16893}
16894
16895void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
16896 struct net_device *netdev, const u8 *bssid)
16897{
16898 struct sk_buff *msg;
16899 void *hdr;
16900
16901 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16902 if (!msg)
16903 return;
16904
16905 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
16906 if (!hdr) {
16907 nlmsg_free(msg);
16908 return;
16909 }
16910
f4d75993
CHH
16911 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16912 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16913 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
503c1fb9
AS
16914 goto nla_put_failure;
16915
16916 genlmsg_end(msg, hdr);
16917
16918 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16919 NL80211_MCGRP_MLME, GFP_KERNEL);
16920 return;
16921
b23aa676 16922 nla_put_failure:
b23aa676 16923 nlmsg_free(msg);
b23aa676
SO
16924}
16925
16926void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
16927 struct net_device *netdev, u16 reason,
667503dd 16928 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
16929{
16930 struct sk_buff *msg;
16931 void *hdr;
16932
4ef8c1c9 16933 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
16934 if (!msg)
16935 return;
16936
16937 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
16938 if (!hdr) {
16939 nlmsg_free(msg);
16940 return;
16941 }
16942
9360ffd1
DM
16943 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16944 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
86b6c465 16945 (reason &&
9360ffd1
DM
16946 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
16947 (from_ap &&
16948 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
16949 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
16950 goto nla_put_failure;
b23aa676 16951
3b7b72ee 16952 genlmsg_end(msg, hdr);
b23aa676 16953
68eb5503 16954 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16955 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
16956 return;
16957
16958 nla_put_failure:
b23aa676 16959 nlmsg_free(msg);
b23aa676
SO
16960}
16961
04a773ad
JB
16962void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
16963 struct net_device *netdev, const u8 *bssid,
16964 gfp_t gfp)
16965{
16966 struct sk_buff *msg;
16967 void *hdr;
16968
fd2120ca 16969 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
16970 if (!msg)
16971 return;
16972
16973 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
16974 if (!hdr) {
16975 nlmsg_free(msg);
16976 return;
16977 }
16978
9360ffd1
DM
16979 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16980 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16981 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
16982 goto nla_put_failure;
04a773ad 16983
3b7b72ee 16984 genlmsg_end(msg, hdr);
04a773ad 16985
68eb5503 16986 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16987 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
16988 return;
16989
16990 nla_put_failure:
04a773ad
JB
16991 nlmsg_free(msg);
16992}
16993
947add36 16994void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
ecbc12ad
BC
16995 const u8 *ie, u8 ie_len,
16996 int sig_dbm, gfp_t gfp)
c93b5e71 16997{
947add36 16998 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16999 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
17000 struct sk_buff *msg;
17001 void *hdr;
17002
947add36
JB
17003 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
17004 return;
17005
17006 trace_cfg80211_notify_new_peer_candidate(dev, addr);
17007
4ef8c1c9 17008 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
17009 if (!msg)
17010 return;
17011
17012 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
17013 if (!hdr) {
17014 nlmsg_free(msg);
17015 return;
17016 }
17017
9360ffd1 17018 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
17019 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17020 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1 17021 (ie_len && ie &&
ecbc12ad
BC
17022 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
17023 (sig_dbm &&
17024 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
9360ffd1 17025 goto nla_put_failure;
c93b5e71 17026
3b7b72ee 17027 genlmsg_end(msg, hdr);
c93b5e71 17028
68eb5503 17029 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17030 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
17031 return;
17032
17033 nla_put_failure:
c93b5e71
JC
17034 nlmsg_free(msg);
17035}
947add36 17036EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 17037
a3b8b056
JM
17038void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
17039 struct net_device *netdev, const u8 *addr,
17040 enum nl80211_key_type key_type, int key_id,
e6d6e342 17041 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
17042{
17043 struct sk_buff *msg;
17044 void *hdr;
17045
e6d6e342 17046 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
17047 if (!msg)
17048 return;
17049
17050 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
17051 if (!hdr) {
17052 nlmsg_free(msg);
17053 return;
17054 }
17055
9360ffd1
DM
17056 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17057 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17058 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
17059 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
17060 (key_id != -1 &&
17061 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
17062 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
17063 goto nla_put_failure;
a3b8b056 17064
3b7b72ee 17065 genlmsg_end(msg, hdr);
a3b8b056 17066
68eb5503 17067 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17068 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
17069 return;
17070
17071 nla_put_failure:
a3b8b056
JM
17072 nlmsg_free(msg);
17073}
17074
6bad8766
LR
17075void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
17076 struct ieee80211_channel *channel_before,
17077 struct ieee80211_channel *channel_after)
17078{
17079 struct sk_buff *msg;
17080 void *hdr;
17081 struct nlattr *nl_freq;
17082
fd2120ca 17083 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
17084 if (!msg)
17085 return;
17086
17087 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
17088 if (!hdr) {
17089 nlmsg_free(msg);
17090 return;
17091 }
17092
17093 /*
17094 * Since we are applying the beacon hint to a wiphy we know its
17095 * wiphy_idx is valid
17096 */
9360ffd1
DM
17097 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
17098 goto nla_put_failure;
6bad8766
LR
17099
17100 /* Before */
ae0be8de 17101 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_BEFORE);
6bad8766
LR
17102 if (!nl_freq)
17103 goto nla_put_failure;
50f32718
HD
17104
17105 if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
6bad8766
LR
17106 goto nla_put_failure;
17107 nla_nest_end(msg, nl_freq);
17108
17109 /* After */
ae0be8de 17110 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_AFTER);
6bad8766
LR
17111 if (!nl_freq)
17112 goto nla_put_failure;
50f32718
HD
17113
17114 if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
6bad8766
LR
17115 goto nla_put_failure;
17116 nla_nest_end(msg, nl_freq);
17117
3b7b72ee 17118 genlmsg_end(msg, hdr);
6bad8766 17119
463d0183 17120 rcu_read_lock();
68eb5503 17121 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 17122 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 17123 rcu_read_unlock();
6bad8766
LR
17124
17125 return;
17126
17127nla_put_failure:
6bad8766
LR
17128 nlmsg_free(msg);
17129}
17130
9588bbd5
JM
17131static void nl80211_send_remain_on_chan_event(
17132 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 17133 struct wireless_dev *wdev, u64 cookie,
9588bbd5 17134 struct ieee80211_channel *chan,
9588bbd5
JM
17135 unsigned int duration, gfp_t gfp)
17136{
17137 struct sk_buff *msg;
17138 void *hdr;
17139
17140 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17141 if (!msg)
17142 return;
17143
17144 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
17145 if (!hdr) {
17146 nlmsg_free(msg);
17147 return;
17148 }
17149
9360ffd1 17150 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
17151 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
17152 wdev->netdev->ifindex)) ||
2dad624e
ND
17153 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17154 NL80211_ATTR_PAD) ||
9360ffd1 17155 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
17156 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
17157 NL80211_CHAN_NO_HT) ||
2dad624e
ND
17158 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
17159 NL80211_ATTR_PAD))
9360ffd1 17160 goto nla_put_failure;
9588bbd5 17161
9360ffd1
DM
17162 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
17163 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
17164 goto nla_put_failure;
9588bbd5 17165
3b7b72ee 17166 genlmsg_end(msg, hdr);
9588bbd5 17167
68eb5503 17168 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17169 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
17170 return;
17171
17172 nla_put_failure:
9588bbd5
JM
17173 nlmsg_free(msg);
17174}
17175
a083ee8a
IP
17176void cfg80211_assoc_comeback(struct net_device *netdev,
17177 struct cfg80211_bss *bss, u32 timeout)
17178{
17179 struct wireless_dev *wdev = netdev->ieee80211_ptr;
17180 struct wiphy *wiphy = wdev->wiphy;
17181 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
17182 struct sk_buff *msg;
17183 void *hdr;
17184
17185 trace_cfg80211_assoc_comeback(wdev, bss->bssid, timeout);
17186
17187 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17188 if (!msg)
17189 return;
17190
17191 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ASSOC_COMEBACK);
17192 if (!hdr) {
17193 nlmsg_free(msg);
17194 return;
17195 }
17196
17197 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17198 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17199 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bss->bssid) ||
17200 nla_put_u32(msg, NL80211_ATTR_TIMEOUT, timeout))
17201 goto nla_put_failure;
17202
17203 genlmsg_end(msg, hdr);
17204
17205 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17206 NL80211_MCGRP_MLME, GFP_KERNEL);
17207 return;
17208
17209 nla_put_failure:
17210 nlmsg_free(msg);
17211}
17212EXPORT_SYMBOL(cfg80211_assoc_comeback);
17213
947add36
JB
17214void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
17215 struct ieee80211_channel *chan,
17216 unsigned int duration, gfp_t gfp)
9588bbd5 17217{
947add36 17218 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17219 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17220
17221 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 17222 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 17223 rdev, wdev, cookie, chan,
42d97a59 17224 duration, gfp);
9588bbd5 17225}
947add36 17226EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 17227
947add36
JB
17228void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
17229 struct ieee80211_channel *chan,
17230 gfp_t gfp)
9588bbd5 17231{
947add36 17232 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17233 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17234
17235 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 17236 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 17237 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 17238}
947add36 17239EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 17240
1c38c7f2
JP
17241void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
17242 struct ieee80211_channel *chan,
17243 gfp_t gfp)
17244{
17245 struct wiphy *wiphy = wdev->wiphy;
17246 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
17247
17248 trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
17249 nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
17250 rdev, wdev, cookie, chan, 0, gfp);
17251}
17252EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
17253
947add36
JB
17254void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
17255 struct station_info *sinfo, gfp_t gfp)
98b62183 17256{
947add36 17257 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 17258 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
17259 struct sk_buff *msg;
17260
947add36
JB
17261 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
17262
58050fce 17263 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
17264 if (!msg)
17265 return;
17266
cf5ead82 17267 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 17268 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
17269 nlmsg_free(msg);
17270 return;
17271 }
17272
68eb5503 17273 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17274 NL80211_MCGRP_MLME, gfp);
98b62183 17275}
947add36 17276EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 17277
cf5ead82
JB
17278void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
17279 struct station_info *sinfo, gfp_t gfp)
ec15e68b 17280{
947add36 17281 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 17282 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 17283 struct sk_buff *msg;
73887fd9 17284 struct station_info empty_sinfo = {};
cf5ead82 17285
73887fd9
JB
17286 if (!sinfo)
17287 sinfo = &empty_sinfo;
ec15e68b 17288
947add36
JB
17289 trace_cfg80211_del_sta(dev, mac_addr);
17290
58050fce 17291 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7ea3e110
JB
17292 if (!msg) {
17293 cfg80211_sinfo_release_content(sinfo);
73887fd9 17294 return;
7ea3e110 17295 }
ec15e68b 17296
cf5ead82 17297 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 17298 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b 17299 nlmsg_free(msg);
73887fd9 17300 return;
ec15e68b
JM
17301 }
17302
68eb5503 17303 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17304 NL80211_MCGRP_MLME, gfp);
ec15e68b 17305}
cf5ead82 17306EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 17307
947add36
JB
17308void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
17309 enum nl80211_connect_failed_reason reason,
17310 gfp_t gfp)
ed44a951 17311{
947add36 17312 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 17313 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
17314 struct sk_buff *msg;
17315 void *hdr;
17316
17317 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
17318 if (!msg)
17319 return;
17320
17321 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
17322 if (!hdr) {
17323 nlmsg_free(msg);
17324 return;
17325 }
17326
17327 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17328 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
17329 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
17330 goto nla_put_failure;
17331
17332 genlmsg_end(msg, hdr);
17333
68eb5503 17334 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17335 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
17336 return;
17337
17338 nla_put_failure:
ed44a951
PP
17339 nlmsg_free(msg);
17340}
947add36 17341EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 17342
b92ab5d8
JB
17343static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
17344 const u8 *addr, gfp_t gfp)
28946da7
JB
17345{
17346 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 17347 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
17348 struct sk_buff *msg;
17349 void *hdr;
6aa7de05 17350 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 17351
15e47304 17352 if (!nlportid)
28946da7
JB
17353 return false;
17354
17355 msg = nlmsg_new(100, gfp);
17356 if (!msg)
17357 return true;
17358
b92ab5d8 17359 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
17360 if (!hdr) {
17361 nlmsg_free(msg);
17362 return true;
17363 }
17364
9360ffd1
DM
17365 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17366 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17367 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
17368 goto nla_put_failure;
28946da7 17369
9c90a9f6 17370 genlmsg_end(msg, hdr);
15e47304 17371 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
17372 return true;
17373
17374 nla_put_failure:
28946da7
JB
17375 nlmsg_free(msg);
17376 return true;
17377}
17378
947add36
JB
17379bool cfg80211_rx_spurious_frame(struct net_device *dev,
17380 const u8 *addr, gfp_t gfp)
b92ab5d8 17381{
947add36
JB
17382 struct wireless_dev *wdev = dev->ieee80211_ptr;
17383 bool ret;
17384
17385 trace_cfg80211_rx_spurious_frame(dev, addr);
17386
17387 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
17388 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
17389 trace_cfg80211_return_bool(false);
17390 return false;
17391 }
17392 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
17393 addr, gfp);
17394 trace_cfg80211_return_bool(ret);
17395 return ret;
b92ab5d8 17396}
947add36 17397EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 17398
947add36
JB
17399bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
17400 const u8 *addr, gfp_t gfp)
b92ab5d8 17401{
947add36
JB
17402 struct wireless_dev *wdev = dev->ieee80211_ptr;
17403 bool ret;
17404
17405 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
17406
17407 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
17408 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
17409 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
17410 trace_cfg80211_return_bool(false);
17411 return false;
17412 }
17413 ret = __nl80211_unexpected_frame(dev,
17414 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
17415 addr, gfp);
17416 trace_cfg80211_return_bool(ret);
17417 return ret;
b92ab5d8 17418}
947add36 17419EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 17420
2e161f78 17421int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 17422 struct wireless_dev *wdev, u32 nlportid,
804483e9 17423 int freq, int sig_dbm,
19504cf5 17424 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 17425{
71bbc994 17426 struct net_device *netdev = wdev->netdev;
026331c4
JM
17427 struct sk_buff *msg;
17428 void *hdr;
026331c4 17429
4ef8c1c9 17430 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
17431 if (!msg)
17432 return -ENOMEM;
17433
2e161f78 17434 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
17435 if (!hdr) {
17436 nlmsg_free(msg);
17437 return -ENOMEM;
17438 }
17439
9360ffd1 17440 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
17441 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
17442 netdev->ifindex)) ||
2dad624e
ND
17443 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17444 NL80211_ATTR_PAD) ||
e76fede8 17445 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(freq)) ||
942ba88b 17446 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq % 1000) ||
9360ffd1
DM
17447 (sig_dbm &&
17448 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
17449 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
17450 (flags &&
17451 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 17452 goto nla_put_failure;
026331c4 17453
3b7b72ee 17454 genlmsg_end(msg, hdr);
026331c4 17455
15e47304 17456 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
17457
17458 nla_put_failure:
026331c4
JM
17459 nlmsg_free(msg);
17460 return -ENOBUFS;
17461}
17462
dca9ca2d
MT
17463static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
17464 const u8 *buf, size_t len, bool ack,
17465 gfp_t gfp, enum nl80211_commands command)
026331c4 17466{
947add36 17467 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17468 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 17469 struct net_device *netdev = wdev->netdev;
026331c4
JM
17470 struct sk_buff *msg;
17471 void *hdr;
17472
dca9ca2d
MT
17473 if (command == NL80211_CMD_FRAME_TX_STATUS)
17474 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
17475 else
17476 trace_cfg80211_control_port_tx_status(wdev, cookie, ack);
947add36 17477
4ef8c1c9 17478 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
17479 if (!msg)
17480 return;
17481
dca9ca2d 17482 hdr = nl80211hdr_put(msg, 0, 0, 0, command);
026331c4
JM
17483 if (!hdr) {
17484 nlmsg_free(msg);
17485 return;
17486 }
17487
9360ffd1 17488 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
17489 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
17490 netdev->ifindex)) ||
2dad624e
ND
17491 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17492 NL80211_ATTR_PAD) ||
9360ffd1 17493 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
17494 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
17495 NL80211_ATTR_PAD) ||
9360ffd1
DM
17496 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
17497 goto nla_put_failure;
026331c4 17498
3b7b72ee 17499 genlmsg_end(msg, hdr);
026331c4 17500
68eb5503 17501 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17502 NL80211_MCGRP_MLME, gfp);
026331c4
JM
17503 return;
17504
dca9ca2d 17505nla_put_failure:
026331c4
JM
17506 nlmsg_free(msg);
17507}
dca9ca2d
MT
17508
17509void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
17510 const u8 *buf, size_t len, bool ack,
17511 gfp_t gfp)
17512{
17513 nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
17514 NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS);
17515}
17516EXPORT_SYMBOL(cfg80211_control_port_tx_status);
17517
17518void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
17519 const u8 *buf, size_t len, bool ack, gfp_t gfp)
17520{
17521 nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
17522 NL80211_CMD_FRAME_TX_STATUS);
17523}
947add36 17524EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 17525
6a671a50 17526static int __nl80211_rx_control_port(struct net_device *dev,
a948f713 17527 struct sk_buff *skb,
6a671a50
DK
17528 bool unencrypted, gfp_t gfp)
17529{
17530 struct wireless_dev *wdev = dev->ieee80211_ptr;
17531 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
a948f713 17532 struct ethhdr *ehdr = eth_hdr(skb);
8d74a623 17533 const u8 *addr = ehdr->h_source;
a948f713 17534 u16 proto = be16_to_cpu(skb->protocol);
6a671a50
DK
17535 struct sk_buff *msg;
17536 void *hdr;
a948f713
DK
17537 struct nlattr *frame;
17538
6a671a50
DK
17539 u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
17540
17541 if (!nlportid)
17542 return -ENOENT;
17543
a948f713 17544 msg = nlmsg_new(100 + skb->len, gfp);
6a671a50
DK
17545 if (!msg)
17546 return -ENOMEM;
17547
17548 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
17549 if (!hdr) {
17550 nlmsg_free(msg);
17551 return -ENOBUFS;
17552 }
17553
17554 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17555 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17556 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17557 NL80211_ATTR_PAD) ||
8d74a623 17558 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
6a671a50
DK
17559 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
17560 (unencrypted && nla_put_flag(msg,
17561 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
17562 goto nla_put_failure;
17563
a948f713
DK
17564 frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
17565 if (!frame)
17566 goto nla_put_failure;
17567
17568 skb_copy_bits(skb, 0, nla_data(frame), skb->len);
6a671a50
DK
17569 genlmsg_end(msg, hdr);
17570
17571 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
17572
17573 nla_put_failure:
17574 nlmsg_free(msg);
17575 return -ENOBUFS;
17576}
17577
17578bool cfg80211_rx_control_port(struct net_device *dev,
a948f713 17579 struct sk_buff *skb, bool unencrypted)
6a671a50
DK
17580{
17581 int ret;
17582
a948f713
DK
17583 trace_cfg80211_rx_control_port(dev, skb, unencrypted);
17584 ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC);
6a671a50
DK
17585 trace_cfg80211_return_bool(ret == 0);
17586 return ret == 0;
17587}
17588EXPORT_SYMBOL(cfg80211_rx_control_port);
17589
5b97f49d
JB
17590static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
17591 const char *mac, gfp_t gfp)
d6dc1a38 17592{
947add36 17593 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
17594 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
17595 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17596 void **cb;
947add36 17597
d6dc1a38 17598 if (!msg)
5b97f49d 17599 return NULL;
d6dc1a38 17600
5b97f49d
JB
17601 cb = (void **)msg->cb;
17602
17603 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
17604 if (!cb[0]) {
d6dc1a38 17605 nlmsg_free(msg);
5b97f49d 17606 return NULL;
d6dc1a38
JO
17607 }
17608
9360ffd1 17609 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 17610 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 17611 goto nla_put_failure;
d6dc1a38 17612
5b97f49d 17613 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
17614 goto nla_put_failure;
17615
ae0be8de 17616 cb[1] = nla_nest_start_noflag(msg, NL80211_ATTR_CQM);
5b97f49d 17617 if (!cb[1])
9360ffd1 17618 goto nla_put_failure;
d6dc1a38 17619
5b97f49d 17620 cb[2] = rdev;
d6dc1a38 17621
5b97f49d
JB
17622 return msg;
17623 nla_put_failure:
17624 nlmsg_free(msg);
17625 return NULL;
17626}
17627
17628static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
17629{
17630 void **cb = (void **)msg->cb;
17631 struct cfg80211_registered_device *rdev = cb[2];
17632
17633 nla_nest_end(msg, cb[1]);
17634 genlmsg_end(msg, cb[0]);
17635
17636 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 17637
68eb5503 17638 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17639 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
17640}
17641
17642void cfg80211_cqm_rssi_notify(struct net_device *dev,
17643 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 17644 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
17645{
17646 struct sk_buff *msg;
4a4b8169
AZ
17647 struct wireless_dev *wdev = dev->ieee80211_ptr;
17648 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 17649
bee427b8 17650 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 17651
98f03342
JB
17652 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
17653 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
17654 return;
17655
4a4b8169
AZ
17656 if (wdev->cqm_config) {
17657 wdev->cqm_config->last_rssi_event_value = rssi_level;
17658
17659 cfg80211_cqm_rssi_update(rdev, dev);
17660
17661 if (rssi_level == 0)
17662 rssi_level = wdev->cqm_config->last_rssi_event_value;
17663 }
17664
5b97f49d
JB
17665 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
17666 if (!msg)
17667 return;
17668
17669 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
17670 rssi_event))
17671 goto nla_put_failure;
17672
bee427b8
AZ
17673 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
17674 rssi_level))
17675 goto nla_put_failure;
17676
5b97f49d
JB
17677 cfg80211_send_cqm(msg, gfp);
17678
d6dc1a38
JO
17679 return;
17680
17681 nla_put_failure:
d6dc1a38
JO
17682 nlmsg_free(msg);
17683}
947add36 17684EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 17685
5b97f49d
JB
17686void cfg80211_cqm_txe_notify(struct net_device *dev,
17687 const u8 *peer, u32 num_packets,
17688 u32 rate, u32 intvl, gfp_t gfp)
17689{
17690 struct sk_buff *msg;
17691
17692 msg = cfg80211_prepare_cqm(dev, peer, gfp);
17693 if (!msg)
17694 return;
17695
17696 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
17697 goto nla_put_failure;
17698
17699 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
17700 goto nla_put_failure;
17701
17702 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
17703 goto nla_put_failure;
17704
17705 cfg80211_send_cqm(msg, gfp);
17706 return;
17707
17708 nla_put_failure:
17709 nlmsg_free(msg);
17710}
17711EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
17712
17713void cfg80211_cqm_pktloss_notify(struct net_device *dev,
17714 const u8 *peer, u32 num_packets, gfp_t gfp)
17715{
17716 struct sk_buff *msg;
17717
17718 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
17719
17720 msg = cfg80211_prepare_cqm(dev, peer, gfp);
17721 if (!msg)
17722 return;
17723
17724 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
17725 goto nla_put_failure;
17726
17727 cfg80211_send_cqm(msg, gfp);
17728 return;
17729
17730 nla_put_failure:
17731 nlmsg_free(msg);
17732}
17733EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
17734
98f03342
JB
17735void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
17736{
17737 struct sk_buff *msg;
17738
17739 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
17740 if (!msg)
17741 return;
17742
17743 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
17744 goto nla_put_failure;
17745
17746 cfg80211_send_cqm(msg, gfp);
17747 return;
17748
17749 nla_put_failure:
17750 nlmsg_free(msg);
17751}
17752EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
17753
947add36
JB
17754static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
17755 struct net_device *netdev, const u8 *bssid,
17756 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
17757{
17758 struct sk_buff *msg;
17759 struct nlattr *rekey_attr;
17760 void *hdr;
17761
58050fce 17762 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
17763 if (!msg)
17764 return;
17765
17766 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
17767 if (!hdr) {
17768 nlmsg_free(msg);
17769 return;
17770 }
17771
9360ffd1
DM
17772 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17773 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17774 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
17775 goto nla_put_failure;
e5497d76 17776
ae0be8de 17777 rekey_attr = nla_nest_start_noflag(msg, NL80211_ATTR_REKEY_DATA);
e5497d76
JB
17778 if (!rekey_attr)
17779 goto nla_put_failure;
17780
9360ffd1
DM
17781 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
17782 NL80211_REPLAY_CTR_LEN, replay_ctr))
17783 goto nla_put_failure;
e5497d76
JB
17784
17785 nla_nest_end(msg, rekey_attr);
17786
3b7b72ee 17787 genlmsg_end(msg, hdr);
e5497d76 17788
68eb5503 17789 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17790 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
17791 return;
17792
17793 nla_put_failure:
e5497d76
JB
17794 nlmsg_free(msg);
17795}
17796
947add36
JB
17797void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
17798 const u8 *replay_ctr, gfp_t gfp)
17799{
17800 struct wireless_dev *wdev = dev->ieee80211_ptr;
17801 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17802 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17803
17804 trace_cfg80211_gtk_rekey_notify(dev, bssid);
17805 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
17806}
17807EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
17808
17809static void
17810nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
17811 struct net_device *netdev, int index,
17812 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
17813{
17814 struct sk_buff *msg;
17815 struct nlattr *attr;
17816 void *hdr;
17817
58050fce 17818 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
17819 if (!msg)
17820 return;
17821
17822 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
17823 if (!hdr) {
17824 nlmsg_free(msg);
17825 return;
17826 }
17827
9360ffd1
DM
17828 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17829 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
17830 goto nla_put_failure;
c9df56b4 17831
ae0be8de 17832 attr = nla_nest_start_noflag(msg, NL80211_ATTR_PMKSA_CANDIDATE);
c9df56b4
JM
17833 if (!attr)
17834 goto nla_put_failure;
17835
9360ffd1
DM
17836 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
17837 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
17838 (preauth &&
17839 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
17840 goto nla_put_failure;
c9df56b4
JM
17841
17842 nla_nest_end(msg, attr);
17843
3b7b72ee 17844 genlmsg_end(msg, hdr);
c9df56b4 17845
68eb5503 17846 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17847 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
17848 return;
17849
17850 nla_put_failure:
c9df56b4
JM
17851 nlmsg_free(msg);
17852}
17853
947add36
JB
17854void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
17855 const u8 *bssid, bool preauth, gfp_t gfp)
17856{
17857 struct wireless_dev *wdev = dev->ieee80211_ptr;
17858 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17859 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17860
17861 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
17862 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
17863}
17864EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
17865
17866static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
17867 struct net_device *netdev,
17868 struct cfg80211_chan_def *chandef,
f8d7552e
LC
17869 gfp_t gfp,
17870 enum nl80211_commands notif,
669b8413 17871 u8 count, bool quiet)
5314526b
TP
17872{
17873 struct sk_buff *msg;
17874 void *hdr;
17875
58050fce 17876 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
17877 if (!msg)
17878 return;
17879
f8d7552e 17880 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
17881 if (!hdr) {
17882 nlmsg_free(msg);
17883 return;
17884 }
17885
683b6d3b
JB
17886 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
17887 goto nla_put_failure;
17888
17889 if (nl80211_send_chandef(msg, chandef))
7eab0f64 17890 goto nla_put_failure;
5314526b 17891
669b8413
JB
17892 if (notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) {
17893 if (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count))
f8d7552e 17894 goto nla_put_failure;
669b8413
JB
17895 if (quiet &&
17896 nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX))
f8d7552e 17897 goto nla_put_failure;
669b8413 17898 }
f8d7552e 17899
5314526b
TP
17900 genlmsg_end(msg, hdr);
17901
68eb5503 17902 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17903 NL80211_MCGRP_MLME, gfp);
5314526b
TP
17904 return;
17905
17906 nla_put_failure:
5314526b
TP
17907 nlmsg_free(msg);
17908}
17909
947add36
JB
17910void cfg80211_ch_switch_notify(struct net_device *dev,
17911 struct cfg80211_chan_def *chandef)
84f10708 17912{
947add36
JB
17913 struct wireless_dev *wdev = dev->ieee80211_ptr;
17914 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17915 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 17916
e487eaeb 17917 ASSERT_WDEV_LOCK(wdev);
947add36 17918
e487eaeb 17919 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 17920
9e0e2961 17921 wdev->chandef = *chandef;
96f55f12 17922 wdev->preset_chandef = *chandef;
5dc8cdce 17923
e50b88c4
SS
17924 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
17925 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
5dc8cdce 17926 !WARN_ON(!wdev->current_bss))
0afd425b 17927 cfg80211_update_assoc_bss_entry(wdev, chandef->chan);
5dc8cdce 17928
d34990bb
MV
17929 cfg80211_sched_dfs_chan_update(rdev);
17930
f8d7552e 17931 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
669b8413 17932 NL80211_CMD_CH_SWITCH_NOTIFY, 0, false);
947add36
JB
17933}
17934EXPORT_SYMBOL(cfg80211_ch_switch_notify);
17935
f8d7552e
LC
17936void cfg80211_ch_switch_started_notify(struct net_device *dev,
17937 struct cfg80211_chan_def *chandef,
669b8413 17938 u8 count, bool quiet)
f8d7552e
LC
17939{
17940 struct wireless_dev *wdev = dev->ieee80211_ptr;
17941 struct wiphy *wiphy = wdev->wiphy;
17942 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
17943
17944 trace_cfg80211_ch_switch_started_notify(dev, chandef);
17945
17946 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
669b8413
JB
17947 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
17948 count, quiet);
f8d7552e
LC
17949}
17950EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
17951
0d2ab3ae
JC
17952int cfg80211_bss_color_notify(struct net_device *dev, gfp_t gfp,
17953 enum nl80211_commands cmd, u8 count,
17954 u64 color_bitmap)
17955{
17956 struct wireless_dev *wdev = dev->ieee80211_ptr;
17957 struct wiphy *wiphy = wdev->wiphy;
17958 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
17959 struct sk_buff *msg;
17960 void *hdr;
17961
17962 ASSERT_WDEV_LOCK(wdev);
17963
17964 trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap);
17965
17966 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17967 if (!msg)
17968 return -ENOMEM;
17969
17970 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
17971 if (!hdr)
17972 goto nla_put_failure;
17973
17974 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
17975 goto nla_put_failure;
17976
17977 if (cmd == NL80211_CMD_COLOR_CHANGE_STARTED &&
17978 nla_put_u32(msg, NL80211_ATTR_COLOR_CHANGE_COUNT, count))
17979 goto nla_put_failure;
17980
17981 if (cmd == NL80211_CMD_OBSS_COLOR_COLLISION &&
17982 nla_put_u64_64bit(msg, NL80211_ATTR_OBSS_COLOR_BITMAP,
17983 color_bitmap, NL80211_ATTR_PAD))
17984 goto nla_put_failure;
17985
17986 genlmsg_end(msg, hdr);
17987
17988 return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
17989 msg, 0, NL80211_MCGRP_MLME, gfp);
17990
17991nla_put_failure:
17992 nlmsg_free(msg);
17993 return -EINVAL;
17994}
17995EXPORT_SYMBOL(cfg80211_bss_color_notify);
17996
04f39047
SW
17997void
17998nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 17999 const struct cfg80211_chan_def *chandef,
04f39047
SW
18000 enum nl80211_radar_event event,
18001 struct net_device *netdev, gfp_t gfp)
18002{
18003 struct sk_buff *msg;
18004 void *hdr;
18005
18006 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18007 if (!msg)
18008 return;
18009
18010 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
18011 if (!hdr) {
18012 nlmsg_free(msg);
18013 return;
18014 }
18015
18016 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
18017 goto nla_put_failure;
18018
18019 /* NOP and radar events don't need a netdev parameter */
18020 if (netdev) {
18021 struct wireless_dev *wdev = netdev->ieee80211_ptr;
18022
18023 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
18024 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
18025 NL80211_ATTR_PAD))
04f39047
SW
18026 goto nla_put_failure;
18027 }
18028
18029 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
18030 goto nla_put_failure;
18031
18032 if (nl80211_send_chandef(msg, chandef))
18033 goto nla_put_failure;
18034
9c90a9f6 18035 genlmsg_end(msg, hdr);
04f39047 18036
68eb5503 18037 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 18038 NL80211_MCGRP_MLME, gfp);
04f39047
SW
18039 return;
18040
18041 nla_put_failure:
04f39047
SW
18042 nlmsg_free(msg);
18043}
18044
466b9936 18045void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
18046 struct sta_opmode_info *sta_opmode,
18047 gfp_t gfp)
18048{
18049 struct sk_buff *msg;
18050 struct wireless_dev *wdev = dev->ieee80211_ptr;
18051 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
18052 void *hdr;
18053
18054 if (WARN_ON(!mac))
18055 return;
18056
18057 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18058 if (!msg)
18059 return;
18060
18061 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
18062 if (!hdr) {
18063 nlmsg_free(msg);
18064 return;
18065 }
18066
18067 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
18068 goto nla_put_failure;
18069
18070 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
18071 goto nla_put_failure;
18072
18073 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
18074 goto nla_put_failure;
18075
18076 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
18077 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
18078 goto nla_put_failure;
18079
18080 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
0016d320 18081 nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
466b9936 18082 goto nla_put_failure;
18083
18084 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
18085 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
18086 goto nla_put_failure;
18087
18088 genlmsg_end(msg, hdr);
18089
18090 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18091 NL80211_MCGRP_MLME, gfp);
18092
18093 return;
18094
18095nla_put_failure:
18096 nlmsg_free(msg);
18097}
18098EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
18099
7f6cf311 18100void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
c4b50cd3
VN
18101 u64 cookie, bool acked, s32 ack_signal,
18102 bool is_valid_ack_signal, gfp_t gfp)
7f6cf311
JB
18103{
18104 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 18105 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
18106 struct sk_buff *msg;
18107 void *hdr;
7f6cf311 18108
4ee3e063
BL
18109 trace_cfg80211_probe_status(dev, addr, cookie, acked);
18110
58050fce 18111 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 18112
7f6cf311
JB
18113 if (!msg)
18114 return;
18115
18116 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
18117 if (!hdr) {
18118 nlmsg_free(msg);
18119 return;
18120 }
18121
9360ffd1
DM
18122 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18123 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18124 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
18125 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
18126 NL80211_ATTR_PAD) ||
c4b50cd3
VN
18127 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
18128 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
18129 ack_signal)))
9360ffd1 18130 goto nla_put_failure;
7f6cf311 18131
9c90a9f6 18132 genlmsg_end(msg, hdr);
7f6cf311 18133
68eb5503 18134 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 18135 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
18136 return;
18137
18138 nla_put_failure:
7f6cf311
JB
18139 nlmsg_free(msg);
18140}
18141EXPORT_SYMBOL(cfg80211_probe_status);
18142
e76fede8
TP
18143void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame,
18144 size_t len, int freq, int sig_dbm)
5e760230 18145{
f26cbf40 18146 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
18147 struct sk_buff *msg;
18148 void *hdr;
37c73b5f 18149 struct cfg80211_beacon_registration *reg;
5e760230 18150
4ee3e063
BL
18151 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
18152
37c73b5f
BG
18153 spin_lock_bh(&rdev->beacon_registrations_lock);
18154 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
18155 msg = nlmsg_new(len + 100, GFP_ATOMIC);
18156 if (!msg) {
18157 spin_unlock_bh(&rdev->beacon_registrations_lock);
18158 return;
18159 }
5e760230 18160
37c73b5f
BG
18161 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
18162 if (!hdr)
18163 goto nla_put_failure;
5e760230 18164
37c73b5f
BG
18165 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18166 (freq &&
942ba88b
TP
18167 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
18168 KHZ_TO_MHZ(freq)) ||
18169 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
18170 freq % 1000))) ||
37c73b5f
BG
18171 (sig_dbm &&
18172 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
18173 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
18174 goto nla_put_failure;
5e760230 18175
37c73b5f 18176 genlmsg_end(msg, hdr);
5e760230 18177
37c73b5f
BG
18178 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
18179 }
18180 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
18181 return;
18182
18183 nla_put_failure:
37c73b5f 18184 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
18185 nlmsg_free(msg);
18186}
e76fede8 18187EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz);
5e760230 18188
cd8f7cb4 18189#ifdef CONFIG_PM
8cd4d456
LC
18190static int cfg80211_net_detect_results(struct sk_buff *msg,
18191 struct cfg80211_wowlan_wakeup *wakeup)
18192{
18193 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
18194 struct nlattr *nl_results, *nl_match, *nl_freqs;
18195 int i, j;
18196
ae0be8de
MK
18197 nl_results = nla_nest_start_noflag(msg,
18198 NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
8cd4d456
LC
18199 if (!nl_results)
18200 return -EMSGSIZE;
18201
18202 for (i = 0; i < nd->n_matches; i++) {
18203 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
18204
ae0be8de 18205 nl_match = nla_nest_start_noflag(msg, i);
8cd4d456
LC
18206 if (!nl_match)
18207 break;
18208
18209 /* The SSID attribute is optional in nl80211, but for
18210 * simplicity reasons it's always present in the
18211 * cfg80211 structure. If a driver can't pass the
18212 * SSID, that needs to be changed. A zero length SSID
18213 * is still a valid SSID (wildcard), so it cannot be
18214 * used for this purpose.
18215 */
18216 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
18217 match->ssid.ssid)) {
18218 nla_nest_cancel(msg, nl_match);
18219 goto out;
18220 }
18221
18222 if (match->n_channels) {
ae0be8de
MK
18223 nl_freqs = nla_nest_start_noflag(msg,
18224 NL80211_ATTR_SCAN_FREQUENCIES);
8cd4d456
LC
18225 if (!nl_freqs) {
18226 nla_nest_cancel(msg, nl_match);
18227 goto out;
18228 }
18229
18230 for (j = 0; j < match->n_channels; j++) {
5528fae8 18231 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
18232 nla_nest_cancel(msg, nl_freqs);
18233 nla_nest_cancel(msg, nl_match);
18234 goto out;
18235 }
18236 }
18237
18238 nla_nest_end(msg, nl_freqs);
18239 }
18240
18241 nla_nest_end(msg, nl_match);
18242 }
18243
18244out:
18245 nla_nest_end(msg, nl_results);
18246 return 0;
18247}
18248
cd8f7cb4
JB
18249void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
18250 struct cfg80211_wowlan_wakeup *wakeup,
18251 gfp_t gfp)
18252{
f26cbf40 18253 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
18254 struct sk_buff *msg;
18255 void *hdr;
9c90a9f6 18256 int size = 200;
cd8f7cb4
JB
18257
18258 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
18259
18260 if (wakeup)
18261 size += wakeup->packet_present_len;
18262
18263 msg = nlmsg_new(size, gfp);
18264 if (!msg)
18265 return;
18266
18267 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
18268 if (!hdr)
18269 goto free_msg;
18270
18271 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
18272 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
18273 NL80211_ATTR_PAD))
cd8f7cb4
JB
18274 goto free_msg;
18275
18276 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
18277 wdev->netdev->ifindex))
18278 goto free_msg;
18279
18280 if (wakeup) {
18281 struct nlattr *reasons;
18282
ae0be8de
MK
18283 reasons = nla_nest_start_noflag(msg,
18284 NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
18285 if (!reasons)
18286 goto free_msg;
cd8f7cb4
JB
18287
18288 if (wakeup->disconnect &&
18289 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
18290 goto free_msg;
18291 if (wakeup->magic_pkt &&
18292 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
18293 goto free_msg;
18294 if (wakeup->gtk_rekey_failure &&
18295 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
18296 goto free_msg;
18297 if (wakeup->eap_identity_req &&
18298 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
18299 goto free_msg;
18300 if (wakeup->four_way_handshake &&
18301 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
18302 goto free_msg;
18303 if (wakeup->rfkill_release &&
18304 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
18305 goto free_msg;
18306
18307 if (wakeup->pattern_idx >= 0 &&
18308 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
18309 wakeup->pattern_idx))
18310 goto free_msg;
18311
ae917c9f
JB
18312 if (wakeup->tcp_match &&
18313 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
18314 goto free_msg;
2a0e047e 18315
ae917c9f
JB
18316 if (wakeup->tcp_connlost &&
18317 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
18318 goto free_msg;
2a0e047e 18319
ae917c9f
JB
18320 if (wakeup->tcp_nomoretokens &&
18321 nla_put_flag(msg,
18322 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
18323 goto free_msg;
2a0e047e 18324
cd8f7cb4
JB
18325 if (wakeup->packet) {
18326 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
18327 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
18328
18329 if (!wakeup->packet_80211) {
18330 pkt_attr =
18331 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
18332 len_attr =
18333 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
18334 }
18335
18336 if (wakeup->packet_len &&
18337 nla_put_u32(msg, len_attr, wakeup->packet_len))
18338 goto free_msg;
18339
18340 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
18341 wakeup->packet))
18342 goto free_msg;
18343 }
18344
8cd4d456
LC
18345 if (wakeup->net_detect &&
18346 cfg80211_net_detect_results(msg, wakeup))
18347 goto free_msg;
18348
cd8f7cb4
JB
18349 nla_nest_end(msg, reasons);
18350 }
18351
9c90a9f6 18352 genlmsg_end(msg, hdr);
cd8f7cb4 18353
68eb5503 18354 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 18355 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
18356 return;
18357
18358 free_msg:
18359 nlmsg_free(msg);
18360}
18361EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
18362#endif
18363
3475b094
JM
18364void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
18365 enum nl80211_tdls_operation oper,
18366 u16 reason_code, gfp_t gfp)
18367{
18368 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 18369 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
18370 struct sk_buff *msg;
18371 void *hdr;
3475b094
JM
18372
18373 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
18374 reason_code);
18375
18376 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18377 if (!msg)
18378 return;
18379
18380 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
18381 if (!hdr) {
18382 nlmsg_free(msg);
18383 return;
18384 }
18385
18386 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18387 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18388 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
18389 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
18390 (reason_code > 0 &&
18391 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
18392 goto nla_put_failure;
18393
9c90a9f6 18394 genlmsg_end(msg, hdr);
3475b094 18395
68eb5503 18396 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 18397 NL80211_MCGRP_MLME, gfp);
3475b094
JM
18398 return;
18399
18400 nla_put_failure:
3475b094
JM
18401 nlmsg_free(msg);
18402}
18403EXPORT_SYMBOL(cfg80211_tdls_oper_request);
18404
026331c4
JM
18405static int nl80211_netlink_notify(struct notifier_block * nb,
18406 unsigned long state,
18407 void *_notify)
18408{
18409 struct netlink_notify *notify = _notify;
18410 struct cfg80211_registered_device *rdev;
18411 struct wireless_dev *wdev;
37c73b5f 18412 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 18413
8f815cdd 18414 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
18415 return NOTIFY_DONE;
18416
18417 rcu_read_lock();
18418
5e760230 18419 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 18420 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 18421
ca986ad9
AVS
18422 list_for_each_entry_rcu(sched_scan_req,
18423 &rdev->sched_scan_req_list,
18424 list) {
18425 if (sched_scan_req->owner_nlportid == notify->portid) {
18426 sched_scan_req->nl_owner_dead = true;
753aacfd 18427 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 18428 }
753aacfd 18429 }
78f22b6a 18430
53873f13 18431 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 18432 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 18433
ab81007a
JB
18434 if (wdev->owner_nlportid == notify->portid) {
18435 wdev->nl_owner_dead = true;
18436 schedule_work(&rdev->destroy_work);
18437 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 18438 schedule_work(&wdev->disconnect_wk);
ab81007a 18439 }
9bb7e0f2
JB
18440
18441 cfg80211_release_pmsr(wdev, notify->portid);
78f22b6a
JB
18442 }
18443
37c73b5f
BG
18444 spin_lock_bh(&rdev->beacon_registrations_lock);
18445 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
18446 list) {
18447 if (reg->nlportid == notify->portid) {
18448 list_del(&reg->list);
18449 kfree(reg);
18450 break;
18451 }
18452 }
18453 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 18454 }
026331c4
JM
18455
18456 rcu_read_unlock();
18457
05050753
I
18458 /*
18459 * It is possible that the user space process that is controlling the
18460 * indoor setting disappeared, so notify the regulatory core.
18461 */
18462 regulatory_netlink_notify(notify->portid);
6784c7db 18463 return NOTIFY_OK;
026331c4
JM
18464}
18465
18466static struct notifier_block nl80211_netlink_notifier = {
18467 .notifier_call = nl80211_netlink_notify,
18468};
18469
355199e0
JM
18470void cfg80211_ft_event(struct net_device *netdev,
18471 struct cfg80211_ft_event_params *ft_event)
18472{
18473 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 18474 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
18475 struct sk_buff *msg;
18476 void *hdr;
355199e0
JM
18477
18478 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
18479
18480 if (!ft_event->target_ap)
18481 return;
18482
1039d081
DL
18483 msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
18484 GFP_KERNEL);
355199e0
JM
18485 if (!msg)
18486 return;
18487
18488 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
18489 if (!hdr)
18490 goto out;
355199e0 18491
ae917c9f
JB
18492 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18493 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18494 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
18495 goto out;
355199e0 18496
ae917c9f
JB
18497 if (ft_event->ies &&
18498 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
18499 goto out;
18500 if (ft_event->ric_ies &&
18501 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
18502 ft_event->ric_ies))
18503 goto out;
355199e0 18504
9c90a9f6 18505 genlmsg_end(msg, hdr);
355199e0 18506
68eb5503 18507 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 18508 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
18509 return;
18510 out:
18511 nlmsg_free(msg);
355199e0
JM
18512}
18513EXPORT_SYMBOL(cfg80211_ft_event);
18514
5de17984
AS
18515void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
18516{
18517 struct cfg80211_registered_device *rdev;
18518 struct sk_buff *msg;
18519 void *hdr;
18520 u32 nlportid;
18521
f26cbf40 18522 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
18523 if (!rdev->crit_proto_nlportid)
18524 return;
18525
18526 nlportid = rdev->crit_proto_nlportid;
18527 rdev->crit_proto_nlportid = 0;
18528
18529 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18530 if (!msg)
18531 return;
18532
18533 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
18534 if (!hdr)
18535 goto nla_put_failure;
18536
18537 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
18538 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
18539 NL80211_ATTR_PAD))
5de17984
AS
18540 goto nla_put_failure;
18541
18542 genlmsg_end(msg, hdr);
18543
18544 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
18545 return;
18546
18547 nla_put_failure:
5de17984 18548 nlmsg_free(msg);
5de17984
AS
18549}
18550EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
18551
348baf0e
JB
18552void nl80211_send_ap_stopped(struct wireless_dev *wdev)
18553{
18554 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 18555 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
18556 struct sk_buff *msg;
18557 void *hdr;
18558
18559 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
18560 if (!msg)
18561 return;
18562
18563 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
18564 if (!hdr)
18565 goto out;
18566
18567 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18568 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
18569 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
18570 NL80211_ATTR_PAD))
348baf0e
JB
18571 goto out;
18572
18573 genlmsg_end(msg, hdr);
18574
18575 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
18576 NL80211_MCGRP_MLME, GFP_KERNEL);
18577 return;
18578 out:
18579 nlmsg_free(msg);
18580}
18581
40cbfa90
SD
18582int cfg80211_external_auth_request(struct net_device *dev,
18583 struct cfg80211_external_auth_params *params,
18584 gfp_t gfp)
18585{
18586 struct wireless_dev *wdev = dev->ieee80211_ptr;
18587 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
18588 struct sk_buff *msg;
18589 void *hdr;
18590
18591 if (!wdev->conn_owner_nlportid)
18592 return -EINVAL;
18593
18594 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18595 if (!msg)
18596 return -ENOMEM;
18597
18598 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
18599 if (!hdr)
18600 goto nla_put_failure;
18601
18602 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18603 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18604 nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
18605 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
18606 params->action) ||
18607 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
18608 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
18609 params->ssid.ssid))
18610 goto nla_put_failure;
18611
18612 genlmsg_end(msg, hdr);
18613 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
18614 wdev->conn_owner_nlportid);
18615 return 0;
18616
18617 nla_put_failure:
18618 nlmsg_free(msg);
18619 return -ENOBUFS;
18620}
18621EXPORT_SYMBOL(cfg80211_external_auth_request);
18622
cb74e977
SD
18623void cfg80211_update_owe_info_event(struct net_device *netdev,
18624 struct cfg80211_update_owe_info *owe_info,
18625 gfp_t gfp)
18626{
18627 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
18628 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18629 struct sk_buff *msg;
18630 void *hdr;
18631
18632 trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
18633
18634 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18635 if (!msg)
18636 return;
18637
18638 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
18639 if (!hdr)
18640 goto nla_put_failure;
18641
18642 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18643 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18644 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
18645 goto nla_put_failure;
18646
18647 if (!owe_info->ie_len ||
18648 nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
18649 goto nla_put_failure;
18650
18651 genlmsg_end(msg, hdr);
18652
18653 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18654 NL80211_MCGRP_MLME, gfp);
18655 return;
18656
18657nla_put_failure:
18658 genlmsg_cancel(msg, hdr);
18659 nlmsg_free(msg);
18660}
18661EXPORT_SYMBOL(cfg80211_update_owe_info_event);
18662
55682965
JB
18663/* initialisation/exit functions */
18664
56989f6d 18665int __init nl80211_init(void)
55682965 18666{
0d63cbb5 18667 int err;
55682965 18668
489111e5 18669 err = genl_register_family(&nl80211_fam);
55682965
JB
18670 if (err)
18671 return err;
18672
026331c4
JM
18673 err = netlink_register_notifier(&nl80211_netlink_notifier);
18674 if (err)
18675 goto err_out;
18676
55682965
JB
18677 return 0;
18678 err_out:
18679 genl_unregister_family(&nl80211_fam);
18680 return err;
18681}
18682
18683void nl80211_exit(void)
18684{
026331c4 18685 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
18686 genl_unregister_family(&nl80211_fam);
18687}