cfg80211: set custom regdomain after wiphy registration
[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
abaf94ec 8 * Copyright (C) 2018-2021 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
55682965 288/* policy for the attributes */
d15da2a2
JB
289static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
290
81e54d08
PKC
291static const struct nla_policy
292nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
293 [NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
294 [NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
295 .len = U8_MAX },
296 [NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
297 .len = U8_MAX },
298};
299
9bb7e0f2
JB
300static const struct nla_policy
301nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
302 [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
303 [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
304 [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
305 NLA_POLICY_MAX(NLA_U8, 15),
306 [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
307 [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
308 NLA_POLICY_MAX(NLA_U8, 15),
309 [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
ea18709a 310 NLA_POLICY_MAX(NLA_U8, 31),
9bb7e0f2
JB
311 [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
312 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
313 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
efb5520d
AS
314 [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG },
315 [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG },
73807523 316 [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG },
9bb7e0f2
JB
317};
318
319static const struct nla_policy
320nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
321 [NL80211_PMSR_TYPE_FTM] =
23323289 322 NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
9bb7e0f2
JB
323};
324
325static const struct nla_policy
326nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
327 [NL80211_PMSR_REQ_ATTR_DATA] =
23323289 328 NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
9bb7e0f2
JB
329 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
330};
331
332static const struct nla_policy
aeddc05f 333nl80211_pmsr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
9bb7e0f2 334 [NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
d15da2a2 335 [NL80211_PMSR_PEER_ATTR_CHAN] = NLA_POLICY_NESTED(nl80211_policy),
9bb7e0f2 336 [NL80211_PMSR_PEER_ATTR_REQ] =
23323289 337 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
9bb7e0f2
JB
338 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
339};
340
341static const struct nla_policy
342nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
343 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
344 [NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
345 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
346 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
347 [NL80211_PMSR_ATTR_PEERS] =
aeddc05f 348 NLA_POLICY_NESTED_ARRAY(nl80211_pmsr_peer_attr_policy),
9bb7e0f2
JB
349};
350
796e90f4
JC
351static const struct nla_policy
352he_obss_pd_policy[NL80211_HE_OBSS_PD_ATTR_MAX + 1] = {
353 [NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] =
354 NLA_POLICY_RANGE(NLA_U8, 1, 20),
355 [NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET] =
356 NLA_POLICY_RANGE(NLA_U8, 1, 20),
f5bec330
RM
357 [NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET] =
358 NLA_POLICY_RANGE(NLA_U8, 1, 20),
359 [NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP] =
360 NLA_POLICY_EXACT_LEN(8),
361 [NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP] =
362 NLA_POLICY_EXACT_LEN(8),
363 [NL80211_HE_OBSS_PD_ATTR_SR_CTRL] = { .type = NLA_U8 },
796e90f4
JC
364};
365
5c5e52d1
JC
366static const struct nla_policy
367he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
368 [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63),
369 [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG },
370 [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
371};
372
9a5f6488
TC
373static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
374 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
375 .len = NL80211_MAX_SUPP_RATES },
376 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
377 .len = NL80211_MAX_SUPP_HT_RATES },
378 [NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)),
379 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
eb89a6a6
MH
380 [NL80211_TXRATE_HE] = NLA_POLICY_EXACT_LEN(sizeof(struct nl80211_txrate_he)),
381 [NL80211_TXRATE_HE_GI] = NLA_POLICY_RANGE(NLA_U8,
382 NL80211_RATE_INFO_HE_GI_0_8,
383 NL80211_RATE_INFO_HE_GI_3_2),
384 [NL80211_TXRATE_HE_LTF] = NLA_POLICY_RANGE(NLA_U8,
385 NL80211_RATE_INFO_HE_1XLTF,
386 NL80211_RATE_INFO_HE_4XLTF),
9a5f6488
TC
387};
388
77f576de
T
389static const struct nla_policy
390nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
3710a8a6
JB
391 [NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
392 [NL80211_TID_CONFIG_ATTR_PEER_SUPP] = { .type = NLA_U64 },
77f576de 393 [NL80211_TID_CONFIG_ATTR_OVERRIDE] = { .type = NLA_FLAG },
3710a8a6 394 [NL80211_TID_CONFIG_ATTR_TIDS] = NLA_POLICY_RANGE(NLA_U16, 1, 0xff),
77f576de
T
395 [NL80211_TID_CONFIG_ATTR_NOACK] =
396 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
6a21d16c
T
397 [NL80211_TID_CONFIG_ATTR_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
398 [NL80211_TID_CONFIG_ATTR_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
ade274b2
T
399 [NL80211_TID_CONFIG_ATTR_AMPDU_CTRL] =
400 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
04f7d142
T
401 [NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] =
402 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
33462e68
SM
403 [NL80211_TID_CONFIG_ATTR_AMSDU_CTRL] =
404 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
9a5f6488
TC
405 [NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE] =
406 NLA_POLICY_MAX(NLA_U8, NL80211_TX_RATE_FIXED),
407 [NL80211_TID_CONFIG_ATTR_TX_RATE] =
408 NLA_POLICY_NESTED(nl80211_txattr_policy),
77f576de
T
409};
410
291c49de
AD
411static const struct nla_policy
412nl80211_fils_discovery_policy[NL80211_FILS_DISCOVERY_ATTR_MAX + 1] = {
413 [NL80211_FILS_DISCOVERY_ATTR_INT_MIN] = NLA_POLICY_MAX(NLA_U32, 10000),
414 [NL80211_FILS_DISCOVERY_ATTR_INT_MAX] = NLA_POLICY_MAX(NLA_U32, 10000),
272cd0e8
AD
415 [NL80211_FILS_DISCOVERY_ATTR_TMPL] =
416 NLA_POLICY_RANGE(NLA_BINARY,
417 NL80211_FILS_DISCOVERY_TMPL_MIN_LEN,
418 IEEE80211_MAX_DATA_LEN),
291c49de
AD
419};
420
7443dcd1
AD
421static const struct nla_policy
422nl80211_unsol_bcast_probe_resp_policy[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1] = {
423 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] = NLA_POLICY_MAX(NLA_U32, 20),
424 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL] = { .type = NLA_BINARY,
425 .len = IEEE80211_MAX_DATA_LEN }
426};
427
6bdb68ce
CH
428static const struct nla_policy
429sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
430 [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
431 [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
432};
433
434static const struct nla_policy
435sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
436 [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
437 [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
438};
439
d15da2a2 440static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
6d4dd4ef 441 [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
55682965
JB
442 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
443 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 444 .len = 20-1 },
31888487 445 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 446
72bdcf34 447 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 448 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
2a38075c
AAL
449 [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
450 NL80211_EDMG_CHANNELS_MIN,
451 NL80211_EDMG_CHANNELS_MAX),
452 [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
453 NL80211_EDMG_BW_CONFIG_MIN,
454 NL80211_EDMG_BW_CONFIG_MAX),
455
3d9d1d66
JB
456 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
457 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
942ba88b 458 [NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
3d9d1d66
JB
459 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
460
ab0d76f6
JB
461 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
462 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
b9a5f8ca
JM
463 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
464 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 465 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 466 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965 467
ab0d76f6 468 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
55682965
JB
469 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
470 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 471
c7721c05
JB
472 [NL80211_ATTR_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
473 [NL80211_ATTR_PREV_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
41ade00f 474
b9454e83 475 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
476 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
477 .len = WLAN_MAX_KEY_LEN },
56be393f 478 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
41ade00f
JB
479 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
480 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 481 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
ab0d76f6
JB
482 [NL80211_ATTR_KEY_TYPE] =
483 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
ed1b6cc7
JB
484
485 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
486 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
f88eb7c0
JB
487 [NL80211_ATTR_BEACON_HEAD] =
488 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
489 IEEE80211_MAX_DATA_LEN),
3d7af878
JB
490 [NL80211_ATTR_BEACON_TAIL] =
491 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
492 IEEE80211_MAX_DATA_LEN),
ab0d76f6
JB
493 [NL80211_ATTR_STA_AID] =
494 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
5727ef1b
JB
495 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
496 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
497 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
498 .len = NL80211_MAX_SUPP_RATES },
ab0d76f6
JB
499 [NL80211_ATTR_STA_PLINK_ACTION] =
500 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
e96d1cd2
ARN
501 [NL80211_ATTR_STA_TX_POWER_SETTING] =
502 NLA_POLICY_RANGE(NLA_U8,
503 NL80211_TX_POWER_AUTOMATIC,
504 NL80211_TX_POWER_FIXED),
505 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
5727ef1b 506 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 507 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 508 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 509 .len = IEEE80211_MAX_MESH_ID_LEN },
1fab1b89 510 [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
9f1ba906 511
b2e1b302
LR
512 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
513 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
514
9f1ba906
JM
515 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
516 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
517 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
518 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
519 .len = NL80211_MAX_SUPP_RATES },
50b12f59 520 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 521
24bdd9f4 522 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 523 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 524
c7721c05 525 [NL80211_ATTR_HT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_HT_CAPABILITY_LEN),
9aed3cc1
JM
526
527 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
3d7af878
JB
528 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
529 validate_ie_attr,
530 IEEE80211_MAX_DATA_LEN),
2a519311
JB
531 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
532 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
533
534 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
535 .len = IEEE80211_MAX_SSID_LEN },
536 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
537 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 538 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 539 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
ab0d76f6
JB
540 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
541 NL80211_MFP_NO,
542 NL80211_MFP_OPTIONAL),
eccb8e8f
JB
543 [NL80211_ATTR_STA_FLAGS2] = {
544 .len = sizeof(struct nl80211_sta_flag_update),
545 },
3f77316c 546 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
547 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
548 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
64bf3d4b 549 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
b23aa676 550 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
ea750801 551 [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
b23aa676
SO
552 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
553 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 554 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 555 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
c7721c05 556 [NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
9588bbd5
JM
557 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
558 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 559 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
560 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
561 .len = IEEE80211_MAX_DATA_LEN },
562 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ab0d76f6
JB
563 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
564 NL80211_PS_DISABLED,
565 NL80211_PS_ENABLED),
d6dc1a38 566 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 567 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 568 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
569 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
570 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 571 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
572 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
573 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 574 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 575 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 576 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 577 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
ab0d76f6
JB
578 [NL80211_ATTR_STA_PLINK_STATE] =
579 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
056e9375
JK
580 [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
581 [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
ab0d76f6
JB
582 [NL80211_ATTR_MESH_PEER_AID] =
583 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
bbe6ad6d 584 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 585 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 586 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
ab0d76f6
JB
587 [NL80211_ATTR_HIDDEN_SSID] =
588 NLA_POLICY_RANGE(NLA_U32,
589 NL80211_HIDDEN_SSID_NOT_IN_USE,
590 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
3d7af878
JB
591 [NL80211_ATTR_IE_PROBE_RESP] =
592 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
593 IEEE80211_MAX_DATA_LEN),
594 [NL80211_ATTR_IE_ASSOC_RESP] =
595 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
596 IEEE80211_MAX_DATA_LEN),
f4b34b55 597 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 598 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 599 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
600 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
601 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
602 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
603 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
604 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 605 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 606 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
607 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
608 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 609 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
610 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
611 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
612 .len = NL80211_HT_CAPABILITY_LEN
613 },
1d9d9213 614 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 615 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 616 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 617 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 618 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
cb9abd48
JB
619
620 /* need to include at least Auth Transaction and Status Code */
621 [NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
622
c7721c05 623 [NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
ed473771 624 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
ab0d76f6
JB
625 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
626 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
627 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
628 NLA_POLICY_RANGE(NLA_U32,
629 NL80211_MESH_POWER_UNKNOWN + 1,
630 NL80211_MESH_POWER_MAX),
77765eaf
VT
631 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
632 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
633 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
634 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 635 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
636 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
637 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
638 .len = NL80211_VHT_CAPABILITY_LEN,
639 },
355199e0
JM
640 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
641 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
642 .len = IEEE80211_MAX_DATA_LEN },
0e1a1d85 643 [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
cb9abd48
JB
644 [NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
645 NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
ab0d76f6
JB
646 [NL80211_ATTR_PEER_AID] =
647 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
16ef1fe2
SW
648 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
649 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
650 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
00c207ed
JC
651 [NL80211_ATTR_CNTDWN_OFFS_BEACON] = { .type = NLA_BINARY },
652 [NL80211_ATTR_CNTDWN_OFFS_PRESP] = { .type = NLA_BINARY },
cb9abd48 653 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
c8b82802
JB
654 /*
655 * The value of the Length field of the Supported Operating
656 * Classes element is between 2 and 253.
657 */
658 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] =
659 NLA_POLICY_RANGE(NLA_BINARY, 2, 253),
5336fa88 660 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 661 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
662 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
663 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
664 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
c8b82802
JB
665 [NL80211_ATTR_QOS_MAP] = NLA_POLICY_RANGE(NLA_BINARY,
666 IEEE80211_QOS_MAP_LEN_MIN,
667 IEEE80211_QOS_MAP_LEN_MAX),
c7721c05 668 [NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
1df4a510 669 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 670 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 671 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 672 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 673 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
ab0d76f6
JB
674 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
675 [NL80211_ATTR_USER_PRIO] =
676 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
960d01ac 677 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 678 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
5cde05c6 679 [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
c7721c05 680 [NL80211_ATTR_MAC_MASK] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
1bdd716c 681 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 682 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 683 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 684 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 685 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 686 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
ab0d76f6
JB
687 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
688 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
c6e6a0c8
AE
689 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
690 .len = VHT_MUMIMO_GROUPS_DATA_LEN
691 },
c7721c05 692 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
ab0d76f6 693 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
8585989d 694 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
a442b761 695 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
348bd456
JM
696 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
697 .len = FILS_MAX_KEK_LEN },
c7721c05 698 [NL80211_ATTR_FILS_NONCES] = NLA_POLICY_EXACT_LEN_WARN(2 * FILS_NONCE_LEN),
ce0ce13a 699 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
c7721c05 700 [NL80211_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
bf95ecdb 701 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
702 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
703 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
704 },
3093ebbe 705 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
a3caf744
VK
706 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
707 .len = FILS_ERP_MAX_USERNAME_LEN },
708 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
709 .len = FILS_ERP_MAX_REALM_LEN },
710 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
711 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
712 .len = FILS_ERP_MAX_RRK_LEN },
c7721c05 713 [NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
a3caf744 714 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
cb9abd48 715 [NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
ca986ad9 716 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
40cbfa90 717 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
52539ca8
THJ
718
719 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
720 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
721 [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
c8b82802
JB
722 [NL80211_ATTR_HE_CAPABILITY] =
723 NLA_POLICY_RANGE(NLA_BINARY,
724 NL80211_HE_MIN_CAPABILITY_LEN,
725 NL80211_HE_MAX_CAPABILITY_LEN),
0e012b4e
JB
726 [NL80211_ATTR_FTM_RESPONDER] =
727 NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
9bb7e0f2
JB
728 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
729 [NL80211_ATTR_PEER_MEASUREMENTS] =
23323289 730 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
36647055 731 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
26f7044e
CHH
732 [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
733 .len = SAE_PASSWORD_MAX_LEN },
a0de1ca3 734 [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
796e90f4 735 [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
14f34e36 736 [NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
5c5e52d1 737 [NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
77f576de
T
738 [NL80211_ATTR_TID_CONFIG] =
739 NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
5631d96a 740 [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
7fc82af8
VJ
741 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
742 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
9dba48a6 743 [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
942ba88b 744 [NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
2032f3b2 745 [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
8140860c
JB
746 [NL80211_ATTR_HE_6GHZ_CAPABILITY] =
747 NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
291c49de
AD
748 [NL80211_ATTR_FILS_DISCOVERY] =
749 NLA_POLICY_NESTED(nl80211_fils_discovery_policy),
7443dcd1
AD
750 [NL80211_ATTR_UNSOL_BCAST_PROBE_RESP] =
751 NLA_POLICY_NESTED(nl80211_unsol_bcast_probe_resp_policy),
d2b7588a
TP
752 [NL80211_ATTR_S1G_CAPABILITY] =
753 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
754 [NL80211_ATTR_S1G_CAPABILITY_MASK] =
755 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
9f0ffa41
RD
756 [NL80211_ATTR_SAE_PWE] =
757 NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
758 NL80211_SAE_PWE_BOTH),
3bb02143 759 [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
6bdb68ce 760 [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
b6db0f89 761 [NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
55682965
JB
762};
763
e31b8213 764/* policy for the key attributes */
b54452b0 765static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 766 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
767 [NL80211_KEY_IDX] = { .type = NLA_U8 },
768 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 769 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
770 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
771 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
ab0d76f6 772 [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
dbd2fd65 773 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
6cdd3979 774 [NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
dbd2fd65
JB
775};
776
777/* policy for the key default flags */
778static const struct nla_policy
779nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
780 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
781 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
782};
783
f83ace3b 784#ifdef CONFIG_PM
ff1b6e69
JB
785/* policy for WoWLAN attributes */
786static const struct nla_policy
787nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
788 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
789 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
790 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
791 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
792 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
793 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
794 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
795 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 796 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 797 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
798};
799
800static const struct nla_policy
801nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
802 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
803 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
c7721c05 804 [NL80211_WOWLAN_TCP_DST_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
2a0e047e
JB
805 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
806 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
bc043585 807 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
2a0e047e
JB
808 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
809 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
810 },
811 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
812 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
813 },
814 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
bc043585
JB
815 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
816 [NL80211_WOWLAN_TCP_WAKE_MASK] = NLA_POLICY_MIN_LEN(1),
ff1b6e69 817};
f83ace3b 818#endif /* CONFIG_PM */
ff1b6e69 819
be29b99a
AK
820/* policy for coalesce rule attributes */
821static const struct nla_policy
822nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
823 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
ab0d76f6
JB
824 [NL80211_ATTR_COALESCE_RULE_CONDITION] =
825 NLA_POLICY_RANGE(NLA_U32,
826 NL80211_COALESCE_CONDITION_MATCH,
827 NL80211_COALESCE_CONDITION_NO_MATCH),
be29b99a
AK
828 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
829};
830
e5497d76
JB
831/* policy for GTK rekey offload attributes */
832static const struct nla_policy
833nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
093a48d2
NE
834 [NL80211_REKEY_DATA_KEK] = {
835 .type = NLA_BINARY,
836 .len = NL80211_KEK_EXT_LEN
837 },
838 [NL80211_REKEY_DATA_KCK] = {
839 .type = NLA_BINARY,
840 .len = NL80211_KCK_EXT_LEN
841 },
cb9abd48 842 [NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN(NL80211_REPLAY_CTR_LEN),
093a48d2 843 [NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
e5497d76
JB
844};
845
1e1b11b6 846static const struct nla_policy
847nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
848 [NL80211_BAND_2GHZ] = { .type = NLA_S32 },
849 [NL80211_BAND_5GHZ] = { .type = NLA_S32 },
e548a1c3 850 [NL80211_BAND_6GHZ] = { .type = NLA_S32 },
1e1b11b6 851 [NL80211_BAND_60GHZ] = { .type = NLA_S32 },
852};
853
a1f1c21c
LC
854static const struct nla_policy
855nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 856 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 857 .len = IEEE80211_MAX_SSID_LEN },
c7721c05 858 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
88e920b4 859 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
1e1b11b6 860 [NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
861 NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
a1f1c21c
LC
862};
863
3b06d277
AS
864static const struct nla_policy
865nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
866 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
867 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
868};
869
38de03d2
AS
870static const struct nla_policy
871nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
872 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
873 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
874 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
875 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
876 },
877};
878
a442b761
AB
879/* policy for NAN function attributes */
880static const struct nla_policy
881nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
cb9abd48
JB
882 [NL80211_NAN_FUNC_TYPE] =
883 NLA_POLICY_MAX(NLA_U8, NL80211_NAN_FUNC_MAX_TYPE),
0a27844c 884 [NL80211_NAN_FUNC_SERVICE_ID] = {
a442b761
AB
885 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
886 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
887 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
888 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
889 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
890 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
c7721c05 891 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
a442b761
AB
892 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
893 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
894 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
895 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
896 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
897 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
898 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
899 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
900 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
901};
902
903/* policy for Service Response Filter attributes */
904static const struct nla_policy
905nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
906 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
907 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
908 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
909 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
910 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
911};
912
ad670233
PX
913/* policy for packet pattern attributes */
914static const struct nla_policy
915nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
916 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
917 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
918 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
919};
920
9bb7e0f2
JB
921int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
922 struct cfg80211_registered_device **rdev,
923 struct wireless_dev **wdev)
a043897a 924{
97990a06 925 int err;
a043897a 926
97990a06 927 if (!cb->args[0]) {
50508d94
JB
928 struct nlattr **attrbuf;
929
930 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
931 GFP_KERNEL);
932 if (!attrbuf)
933 return -ENOMEM;
934
8cb08174
JB
935 err = nlmsg_parse_deprecated(cb->nlh,
936 GENL_HDRLEN + nl80211_fam.hdrsize,
50508d94 937 attrbuf, nl80211_fam.maxattr,
8cb08174 938 nl80211_policy, NULL);
50508d94
JB
939 if (err) {
940 kfree(attrbuf);
ea90e0dc 941 return err;
50508d94 942 }
67748893 943
a05829a7
JB
944 rtnl_lock();
945 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(cb->skb->sk),
50508d94
JB
946 attrbuf);
947 kfree(attrbuf);
a05829a7
JB
948 if (IS_ERR(*wdev)) {
949 rtnl_unlock();
ea90e0dc 950 return PTR_ERR(*wdev);
a05829a7 951 }
f26cbf40 952 *rdev = wiphy_to_rdev((*wdev)->wiphy);
a05829a7
JB
953 mutex_lock(&(*rdev)->wiphy.mtx);
954 rtnl_unlock();
c319d50b
JB
955 /* 0 is the first index - add 1 to parse only once */
956 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
957 cb->args[1] = (*wdev)->identifier;
958 } else {
c319d50b 959 /* subtract the 1 again here */
a05829a7 960 struct wiphy *wiphy;
97990a06 961 struct wireless_dev *tmp;
67748893 962
a05829a7
JB
963 rtnl_lock();
964 wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
965 if (!wiphy) {
966 rtnl_unlock();
ea90e0dc 967 return -ENODEV;
a05829a7 968 }
f26cbf40 969 *rdev = wiphy_to_rdev(wiphy);
97990a06 970 *wdev = NULL;
67748893 971
53873f13 972 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
973 if (tmp->identifier == cb->args[1]) {
974 *wdev = tmp;
975 break;
976 }
977 }
67748893 978
a05829a7
JB
979 if (!*wdev) {
980 rtnl_unlock();
ea90e0dc 981 return -ENODEV;
a05829a7
JB
982 }
983 mutex_lock(&(*rdev)->wiphy.mtx);
984 rtnl_unlock();
67748893
JB
985 }
986
67748893 987 return 0;
67748893
JB
988}
989
55682965 990/* message building helper */
9bb7e0f2
JB
991void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
992 int flags, u8 cmd)
55682965
JB
993{
994 /* since there is no private header just add the generic one */
15e47304 995 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
996}
997
50f32718
HD
998static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
999 const struct ieee80211_reg_rule *rule)
1000{
1001 int j;
1002 struct nlattr *nl_wmm_rules =
ae0be8de 1003 nla_nest_start_noflag(msg, NL80211_FREQUENCY_ATTR_WMM);
50f32718
HD
1004
1005 if (!nl_wmm_rules)
1006 goto nla_put_failure;
1007
1008 for (j = 0; j < IEEE80211_NUM_ACS; j++) {
ae0be8de 1009 struct nlattr *nl_wmm_rule = nla_nest_start_noflag(msg, j);
50f32718
HD
1010
1011 if (!nl_wmm_rule)
1012 goto nla_put_failure;
1013
1014 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
38cb87ee 1015 rule->wmm_rule.client[j].cw_min) ||
50f32718 1016 nla_put_u16(msg, NL80211_WMMR_CW_MAX,
38cb87ee 1017 rule->wmm_rule.client[j].cw_max) ||
50f32718 1018 nla_put_u8(msg, NL80211_WMMR_AIFSN,
38cb87ee 1019 rule->wmm_rule.client[j].aifsn) ||
d3c89bbc
HD
1020 nla_put_u16(msg, NL80211_WMMR_TXOP,
1021 rule->wmm_rule.client[j].cot))
50f32718
HD
1022 goto nla_put_failure;
1023
1024 nla_nest_end(msg, nl_wmm_rule);
1025 }
1026 nla_nest_end(msg, nl_wmm_rules);
1027
1028 return 0;
1029
1030nla_put_failure:
1031 return -ENOBUFS;
1032}
1033
1034static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
cdc89b97
JB
1035 struct ieee80211_channel *chan,
1036 bool large)
5dab3b8a 1037{
ea077c1c
RL
1038 /* Some channels must be completely excluded from the
1039 * list to protect old user-space tools from breaking
1040 */
1041 if (!large && chan->flags &
1042 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
1043 return 0;
f8d504ca
JB
1044 if (!large && chan->freq_offset)
1045 return 0;
ea077c1c 1046
9360ffd1
DM
1047 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
1048 chan->center_freq))
1049 goto nla_put_failure;
5dab3b8a 1050
942ba88b
TP
1051 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset))
1052 goto nla_put_failure;
1053
9360ffd1
DM
1054 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
1055 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
1056 goto nla_put_failure;
8fe02e16
LR
1057 if (chan->flags & IEEE80211_CHAN_NO_IR) {
1058 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
1059 goto nla_put_failure;
1060 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
1061 goto nla_put_failure;
1062 }
cdc89b97
JB
1063 if (chan->flags & IEEE80211_CHAN_RADAR) {
1064 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
1065 goto nla_put_failure;
1066 if (large) {
1067 u32 time;
1068
1069 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
1070
1071 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
1072 chan->dfs_state))
1073 goto nla_put_failure;
1074 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
1075 time))
1076 goto nla_put_failure;
089027e5
JD
1077 if (nla_put_u32(msg,
1078 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
1079 chan->dfs_cac_ms))
1080 goto nla_put_failure;
cdc89b97
JB
1081 }
1082 }
5dab3b8a 1083
fe1abafd
JB
1084 if (large) {
1085 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
1086 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
1087 goto nla_put_failure;
1088 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
1089 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
1090 goto nla_put_failure;
1091 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
1092 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
1093 goto nla_put_failure;
1094 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
1095 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
1096 goto nla_put_failure;
570dbde1
DS
1097 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
1098 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
1099 goto nla_put_failure;
06f207fc
AN
1100 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
1101 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 1102 goto nla_put_failure;
ea077c1c
RL
1103 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
1104 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
1105 goto nla_put_failure;
1106 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
1107 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
1108 goto nla_put_failure;
1e61d82c
HD
1109 if ((chan->flags & IEEE80211_CHAN_NO_HE) &&
1110 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE))
1111 goto nla_put_failure;
d65a9770
TP
1112 if ((chan->flags & IEEE80211_CHAN_1MHZ) &&
1113 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_1MHZ))
1114 goto nla_put_failure;
1115 if ((chan->flags & IEEE80211_CHAN_2MHZ) &&
1116 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_2MHZ))
1117 goto nla_put_failure;
1118 if ((chan->flags & IEEE80211_CHAN_4MHZ) &&
1119 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_4MHZ))
1120 goto nla_put_failure;
1121 if ((chan->flags & IEEE80211_CHAN_8MHZ) &&
1122 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_8MHZ))
1123 goto nla_put_failure;
1124 if ((chan->flags & IEEE80211_CHAN_16MHZ) &&
1125 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_16MHZ))
1126 goto nla_put_failure;
fe1abafd
JB
1127 }
1128
9360ffd1
DM
1129 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
1130 DBM_TO_MBM(chan->max_power)))
1131 goto nla_put_failure;
5dab3b8a 1132
50f32718
HD
1133 if (large) {
1134 const struct ieee80211_reg_rule *rule =
b88d26d9 1135 freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
50f32718 1136
38cb87ee 1137 if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
50f32718
HD
1138 if (nl80211_msg_put_wmm_rules(msg, rule))
1139 goto nla_put_failure;
1140 }
1141 }
1142
5dab3b8a
LR
1143 return 0;
1144
1145 nla_put_failure:
1146 return -ENOBUFS;
1147}
1148
52539ca8
THJ
1149static bool nl80211_put_txq_stats(struct sk_buff *msg,
1150 struct cfg80211_txq_stats *txqstats,
1151 int attrtype)
1152{
1153 struct nlattr *txqattr;
1154
1155#define PUT_TXQVAL_U32(attr, memb) do { \
1156 if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) && \
1157 nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
1158 return false; \
1159 } while (0)
1160
ae0be8de 1161 txqattr = nla_nest_start_noflag(msg, attrtype);
52539ca8
THJ
1162 if (!txqattr)
1163 return false;
1164
1165 PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
1166 PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
1167 PUT_TXQVAL_U32(FLOWS, flows);
1168 PUT_TXQVAL_U32(DROPS, drops);
1169 PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
1170 PUT_TXQVAL_U32(OVERLIMIT, overlimit);
1171 PUT_TXQVAL_U32(OVERMEMORY, overmemory);
1172 PUT_TXQVAL_U32(COLLISIONS, collisions);
1173 PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
1174 PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
1175 PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
1176 nla_nest_end(msg, txqattr);
1177
1178#undef PUT_TXQVAL_U32
1179 return true;
1180}
1181
55682965
JB
1182/* netlink command implementations */
1183
b9454e83
JB
1184struct key_parse {
1185 struct key_params p;
1186 int idx;
e31b8213 1187 int type;
56be393f 1188 bool def, defmgmt, defbeacon;
dbd2fd65 1189 bool def_uni, def_multi;
b9454e83
JB
1190};
1191
768075eb
JB
1192static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
1193 struct key_parse *k)
b9454e83
JB
1194{
1195 struct nlattr *tb[NL80211_KEY_MAX + 1];
8cb08174
JB
1196 int err = nla_parse_nested_deprecated(tb, NL80211_KEY_MAX, key,
1197 nl80211_key_policy,
1198 info->extack);
b9454e83
JB
1199 if (err)
1200 return err;
1201
1202 k->def = !!tb[NL80211_KEY_DEFAULT];
1203 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
56be393f 1204 k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
b9454e83 1205
dbd2fd65
JB
1206 if (k->def) {
1207 k->def_uni = true;
1208 k->def_multi = true;
1209 }
56be393f 1210 if (k->defmgmt || k->defbeacon)
dbd2fd65
JB
1211 k->def_multi = true;
1212
b9454e83
JB
1213 if (tb[NL80211_KEY_IDX])
1214 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
1215
1216 if (tb[NL80211_KEY_DATA]) {
1217 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
1218 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
1219 }
1220
1221 if (tb[NL80211_KEY_SEQ]) {
1222 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
1223 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
1224 }
1225
1226 if (tb[NL80211_KEY_CIPHER])
1227 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
1228
ab0d76f6 1229 if (tb[NL80211_KEY_TYPE])
e31b8213 1230 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
e31b8213 1231
dbd2fd65
JB
1232 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
1233 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 1234
8cb08174
JB
1235 err = nla_parse_nested_deprecated(kdt,
1236 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1237 tb[NL80211_KEY_DEFAULT_TYPES],
1238 nl80211_key_default_policy,
1239 info->extack);
dbd2fd65
JB
1240 if (err)
1241 return err;
1242
1243 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1244 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1245 }
1246
6cdd3979
AW
1247 if (tb[NL80211_KEY_MODE])
1248 k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
1249
b9454e83
JB
1250 return 0;
1251}
1252
1253static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
1254{
1255 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
1256 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
1257 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1258 }
1259
1260 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1261 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1262 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1263 }
1264
1265 if (info->attrs[NL80211_ATTR_KEY_IDX])
1266 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1267
1268 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
1269 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1270
1271 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
1272 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
1273
dbd2fd65
JB
1274 if (k->def) {
1275 k->def_uni = true;
1276 k->def_multi = true;
1277 }
1278 if (k->defmgmt)
1279 k->def_multi = true;
1280
ab0d76f6 1281 if (info->attrs[NL80211_ATTR_KEY_TYPE])
e31b8213 1282 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
e31b8213 1283
dbd2fd65
JB
1284 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
1285 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
8cb08174
JB
1286 int err = nla_parse_nested_deprecated(kdt,
1287 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1288 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
1289 nl80211_key_default_policy,
1290 info->extack);
dbd2fd65
JB
1291 if (err)
1292 return err;
1293
1294 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1295 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1296 }
1297
b9454e83
JB
1298 return 0;
1299}
1300
1301static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
1302{
1303 int err;
1304
1305 memset(k, 0, sizeof(*k));
1306 k->idx = -1;
e31b8213 1307 k->type = -1;
b9454e83
JB
1308
1309 if (info->attrs[NL80211_ATTR_KEY])
768075eb 1310 err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
b9454e83
JB
1311 else
1312 err = nl80211_parse_key_old(info, k);
1313
1314 if (err)
1315 return err;
1316
56be393f
JM
1317 if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
1318 (k->defbeacon ? 1 : 0) > 1) {
1319 GENL_SET_ERR_MSG(info,
1320 "key with multiple default flags is invalid");
b9454e83 1321 return -EINVAL;
768075eb 1322 }
b9454e83 1323
56be393f 1324 if (k->defmgmt || k->defbeacon) {
768075eb 1325 if (k->def_uni || !k->def_multi) {
56be393f
JM
1326 GENL_SET_ERR_MSG(info,
1327 "defmgmt/defbeacon key must be mcast");
dbd2fd65 1328 return -EINVAL;
768075eb 1329 }
dbd2fd65
JB
1330 }
1331
b9454e83
JB
1332 if (k->idx != -1) {
1333 if (k->defmgmt) {
768075eb
JB
1334 if (k->idx < 4 || k->idx > 5) {
1335 GENL_SET_ERR_MSG(info,
1336 "defmgmt key idx not 4 or 5");
b9454e83 1337 return -EINVAL;
768075eb 1338 }
56be393f
JM
1339 } else if (k->defbeacon) {
1340 if (k->idx < 6 || k->idx > 7) {
1341 GENL_SET_ERR_MSG(info,
1342 "defbeacon key idx not 6 or 7");
1343 return -EINVAL;
1344 }
b9454e83 1345 } else if (k->def) {
768075eb
JB
1346 if (k->idx < 0 || k->idx > 3) {
1347 GENL_SET_ERR_MSG(info, "def key idx not 0-3");
b9454e83 1348 return -EINVAL;
768075eb 1349 }
b9454e83 1350 } else {
56be393f
JM
1351 if (k->idx < 0 || k->idx > 7) {
1352 GENL_SET_ERR_MSG(info, "key idx not 0-7");
b9454e83 1353 return -EINVAL;
768075eb 1354 }
b9454e83
JB
1355 }
1356 }
1357
1358 return 0;
1359}
1360
fffd0934
JB
1361static struct cfg80211_cached_keys *
1362nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
768075eb 1363 struct genl_info *info, bool *no_ht)
fffd0934 1364{
768075eb 1365 struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
fffd0934
JB
1366 struct key_parse parse;
1367 struct nlattr *key;
1368 struct cfg80211_cached_keys *result;
1369 int rem, err, def = 0;
f1c1f17a
JB
1370 bool have_key = false;
1371
1372 nla_for_each_nested(key, keys, rem) {
1373 have_key = true;
1374 break;
1375 }
1376
1377 if (!have_key)
1378 return NULL;
fffd0934
JB
1379
1380 result = kzalloc(sizeof(*result), GFP_KERNEL);
1381 if (!result)
1382 return ERR_PTR(-ENOMEM);
1383
1384 result->def = -1;
fffd0934
JB
1385
1386 nla_for_each_nested(key, keys, rem) {
1387 memset(&parse, 0, sizeof(parse));
1388 parse.idx = -1;
1389
768075eb 1390 err = nl80211_parse_key_new(info, key, &parse);
fffd0934
JB
1391 if (err)
1392 goto error;
1393 err = -EINVAL;
1394 if (!parse.p.key)
1395 goto error;
768075eb
JB
1396 if (parse.idx < 0 || parse.idx > 3) {
1397 GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
fffd0934 1398 goto error;
768075eb 1399 }
fffd0934 1400 if (parse.def) {
768075eb
JB
1401 if (def) {
1402 GENL_SET_ERR_MSG(info,
1403 "only one key can be default");
fffd0934 1404 goto error;
768075eb 1405 }
fffd0934
JB
1406 def = 1;
1407 result->def = parse.idx;
dbd2fd65
JB
1408 if (!parse.def_uni || !parse.def_multi)
1409 goto error;
fffd0934
JB
1410 } else if (parse.defmgmt)
1411 goto error;
1412 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 1413 parse.idx, false, NULL);
fffd0934
JB
1414 if (err)
1415 goto error;
386b1f27
JB
1416 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1417 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
768075eb 1418 GENL_SET_ERR_MSG(info, "connect key must be WEP");
386b1f27
JB
1419 err = -EINVAL;
1420 goto error;
1421 }
fffd0934
JB
1422 result->params[parse.idx].cipher = parse.p.cipher;
1423 result->params[parse.idx].key_len = parse.p.key_len;
1424 result->params[parse.idx].key = result->data[parse.idx];
1425 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 1426
386b1f27
JB
1427 /* must be WEP key if we got here */
1428 if (no_ht)
1429 *no_ht = true;
fffd0934
JB
1430 }
1431
f1c1f17a
JB
1432 if (result->def < 0) {
1433 err = -EINVAL;
768075eb 1434 GENL_SET_ERR_MSG(info, "need a default/TX key");
f1c1f17a
JB
1435 goto error;
1436 }
1437
fffd0934
JB
1438 return result;
1439 error:
1440 kfree(result);
1441 return ERR_PTR(err);
1442}
1443
1444static int nl80211_key_allowed(struct wireless_dev *wdev)
1445{
1446 ASSERT_WDEV_LOCK(wdev);
1447
fffd0934
JB
1448 switch (wdev->iftype) {
1449 case NL80211_IFTYPE_AP:
1450 case NL80211_IFTYPE_AP_VLAN:
074ac8df 1451 case NL80211_IFTYPE_P2P_GO:
ff973af7 1452 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
1453 break;
1454 case NL80211_IFTYPE_ADHOC:
fffd0934 1455 case NL80211_IFTYPE_STATION:
074ac8df 1456 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 1457 if (!wdev->current_bss)
fffd0934
JB
1458 return -ENOLINK;
1459 break;
de4fcbad 1460 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 1461 case NL80211_IFTYPE_OCB:
de4fcbad 1462 case NL80211_IFTYPE_MONITOR:
cb3b7d87 1463 case NL80211_IFTYPE_NAN:
de4fcbad
JB
1464 case NL80211_IFTYPE_P2P_DEVICE:
1465 case NL80211_IFTYPE_WDS:
1466 case NUM_NL80211_IFTYPES:
fffd0934
JB
1467 return -EINVAL;
1468 }
1469
1470 return 0;
1471}
1472
664834de 1473static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
942ba88b 1474 u32 freq)
664834de
JM
1475{
1476 struct ieee80211_channel *chan;
1477
942ba88b 1478 chan = ieee80211_get_channel_khz(wiphy, freq);
664834de
JM
1479 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1480 return NULL;
1481 return chan;
1482}
1483
7527a782
JB
1484static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1485{
ae0be8de 1486 struct nlattr *nl_modes = nla_nest_start_noflag(msg, attr);
7527a782
JB
1487 int i;
1488
1489 if (!nl_modes)
1490 goto nla_put_failure;
1491
1492 i = 0;
1493 while (ifmodes) {
9360ffd1
DM
1494 if ((ifmodes & 1) && nla_put_flag(msg, i))
1495 goto nla_put_failure;
7527a782
JB
1496 ifmodes >>= 1;
1497 i++;
1498 }
1499
1500 nla_nest_end(msg, nl_modes);
1501 return 0;
1502
1503nla_put_failure:
1504 return -ENOBUFS;
1505}
1506
1507static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1508 struct sk_buff *msg,
1509 bool large)
7527a782
JB
1510{
1511 struct nlattr *nl_combis;
1512 int i, j;
1513
ae0be8de
MK
1514 nl_combis = nla_nest_start_noflag(msg,
1515 NL80211_ATTR_INTERFACE_COMBINATIONS);
7527a782
JB
1516 if (!nl_combis)
1517 goto nla_put_failure;
1518
1519 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1520 const struct ieee80211_iface_combination *c;
1521 struct nlattr *nl_combi, *nl_limits;
1522
1523 c = &wiphy->iface_combinations[i];
1524
ae0be8de 1525 nl_combi = nla_nest_start_noflag(msg, i + 1);
7527a782
JB
1526 if (!nl_combi)
1527 goto nla_put_failure;
1528
ae0be8de
MK
1529 nl_limits = nla_nest_start_noflag(msg,
1530 NL80211_IFACE_COMB_LIMITS);
7527a782
JB
1531 if (!nl_limits)
1532 goto nla_put_failure;
1533
1534 for (j = 0; j < c->n_limits; j++) {
1535 struct nlattr *nl_limit;
1536
ae0be8de 1537 nl_limit = nla_nest_start_noflag(msg, j + 1);
7527a782
JB
1538 if (!nl_limit)
1539 goto nla_put_failure;
9360ffd1
DM
1540 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1541 c->limits[j].max))
1542 goto nla_put_failure;
7527a782
JB
1543 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1544 c->limits[j].types))
1545 goto nla_put_failure;
1546 nla_nest_end(msg, nl_limit);
1547 }
1548
1549 nla_nest_end(msg, nl_limits);
1550
9360ffd1
DM
1551 if (c->beacon_int_infra_match &&
1552 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1553 goto nla_put_failure;
1554 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1555 c->num_different_channels) ||
1556 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1557 c->max_interfaces))
1558 goto nla_put_failure;
cdc89b97 1559 if (large &&
8c48b50a
FF
1560 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1561 c->radar_detect_widths) ||
1562 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1563 c->radar_detect_regions)))
cdc89b97 1564 goto nla_put_failure;
0c317a02
PK
1565 if (c->beacon_int_min_gcd &&
1566 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1567 c->beacon_int_min_gcd))
1568 goto nla_put_failure;
7527a782
JB
1569
1570 nla_nest_end(msg, nl_combi);
1571 }
1572
1573 nla_nest_end(msg, nl_combis);
1574
1575 return 0;
1576nla_put_failure:
1577 return -ENOBUFS;
1578}
1579
3713b4e3 1580#ifdef CONFIG_PM
b56cf720
JB
1581static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1582 struct sk_buff *msg)
1583{
964dc9e2 1584 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1585 struct nlattr *nl_tcp;
1586
1587 if (!tcp)
1588 return 0;
1589
ae0be8de
MK
1590 nl_tcp = nla_nest_start_noflag(msg,
1591 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
b56cf720
JB
1592 if (!nl_tcp)
1593 return -ENOBUFS;
1594
1595 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1596 tcp->data_payload_max))
1597 return -ENOBUFS;
1598
1599 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1600 tcp->data_payload_max))
1601 return -ENOBUFS;
1602
1603 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1604 return -ENOBUFS;
1605
1606 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1607 sizeof(*tcp->tok), tcp->tok))
1608 return -ENOBUFS;
1609
1610 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1611 tcp->data_interval_max))
1612 return -ENOBUFS;
1613
1614 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1615 tcp->wake_payload_max))
1616 return -ENOBUFS;
1617
1618 nla_nest_end(msg, nl_tcp);
1619 return 0;
1620}
1621
3713b4e3 1622static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1623 struct cfg80211_registered_device *rdev,
b56cf720 1624 bool large)
55682965 1625{
3713b4e3 1626 struct nlattr *nl_wowlan;
55682965 1627
1b8ec87a 1628 if (!rdev->wiphy.wowlan)
3713b4e3 1629 return 0;
55682965 1630
ae0be8de
MK
1631 nl_wowlan = nla_nest_start_noflag(msg,
1632 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
3713b4e3
JB
1633 if (!nl_wowlan)
1634 return -ENOBUFS;
9360ffd1 1635
1b8ec87a 1636 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1637 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1638 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1639 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1640 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1641 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1642 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1643 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1644 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1645 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1646 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1647 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1648 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1649 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1650 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1651 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1652 return -ENOBUFS;
9360ffd1 1653
1b8ec87a 1654 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1655 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1656 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1657 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1658 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1659 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1660 };
9360ffd1 1661
3713b4e3
JB
1662 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1663 sizeof(pat), &pat))
1664 return -ENOBUFS;
1665 }
9360ffd1 1666
75453ccb
LC
1667 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1668 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1669 rdev->wiphy.wowlan->max_nd_match_sets))
1670 return -ENOBUFS;
1671
1b8ec87a 1672 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1673 return -ENOBUFS;
1674
3713b4e3 1675 nla_nest_end(msg, nl_wowlan);
9360ffd1 1676
3713b4e3
JB
1677 return 0;
1678}
1679#endif
9360ffd1 1680
be29b99a 1681static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1682 struct cfg80211_registered_device *rdev)
be29b99a
AK
1683{
1684 struct nl80211_coalesce_rule_support rule;
1685
1b8ec87a 1686 if (!rdev->wiphy.coalesce)
be29b99a
AK
1687 return 0;
1688
1b8ec87a
ZG
1689 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1690 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1691 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1692 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1693 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1694 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1695
1696 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1697 return -ENOBUFS;
1698
1699 return 0;
1700}
1701
c4cbaf79
LC
1702static int
1703nl80211_send_iftype_data(struct sk_buff *msg,
22395217 1704 const struct ieee80211_supported_band *sband,
c4cbaf79
LC
1705 const struct ieee80211_sband_iftype_data *iftdata)
1706{
1707 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
1708
1709 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
1710 iftdata->types_mask))
1711 return -ENOBUFS;
1712
1713 if (he_cap->has_he) {
1714 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
1715 sizeof(he_cap->he_cap_elem.mac_cap_info),
1716 he_cap->he_cap_elem.mac_cap_info) ||
1717 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
1718 sizeof(he_cap->he_cap_elem.phy_cap_info),
1719 he_cap->he_cap_elem.phy_cap_info) ||
1720 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
1721 sizeof(he_cap->he_mcs_nss_supp),
1722 &he_cap->he_mcs_nss_supp) ||
1723 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
1724 sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
1725 return -ENOBUFS;
1726 }
1727
22395217
JB
1728 if (sband->band == NL80211_BAND_6GHZ &&
1729 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
1730 sizeof(iftdata->he_6ghz_capa),
1731 &iftdata->he_6ghz_capa))
1732 return -ENOBUFS;
1733
c4cbaf79
LC
1734 return 0;
1735}
1736
3713b4e3 1737static int nl80211_send_band_rateinfo(struct sk_buff *msg,
f8d504ca
JB
1738 struct ieee80211_supported_band *sband,
1739 bool large)
3713b4e3
JB
1740{
1741 struct nlattr *nl_rates, *nl_rate;
1742 struct ieee80211_rate *rate;
1743 int i;
87bbbe22 1744
3713b4e3
JB
1745 /* add HT info */
1746 if (sband->ht_cap.ht_supported &&
1747 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1748 sizeof(sband->ht_cap.mcs),
1749 &sband->ht_cap.mcs) ||
1750 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1751 sband->ht_cap.cap) ||
1752 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1753 sband->ht_cap.ampdu_factor) ||
1754 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1755 sband->ht_cap.ampdu_density)))
1756 return -ENOBUFS;
afe0cbf8 1757
3713b4e3
JB
1758 /* add VHT info */
1759 if (sband->vht_cap.vht_supported &&
1760 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1761 sizeof(sband->vht_cap.vht_mcs),
1762 &sband->vht_cap.vht_mcs) ||
1763 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1764 sband->vht_cap.cap)))
1765 return -ENOBUFS;
f59ac048 1766
f8d504ca 1767 if (large && sband->n_iftype_data) {
c4cbaf79 1768 struct nlattr *nl_iftype_data =
ae0be8de
MK
1769 nla_nest_start_noflag(msg,
1770 NL80211_BAND_ATTR_IFTYPE_DATA);
c4cbaf79
LC
1771 int err;
1772
1773 if (!nl_iftype_data)
1774 return -ENOBUFS;
1775
1776 for (i = 0; i < sband->n_iftype_data; i++) {
1777 struct nlattr *iftdata;
1778
ae0be8de 1779 iftdata = nla_nest_start_noflag(msg, i + 1);
c4cbaf79
LC
1780 if (!iftdata)
1781 return -ENOBUFS;
1782
22395217 1783 err = nl80211_send_iftype_data(msg, sband,
c4cbaf79
LC
1784 &sband->iftype_data[i]);
1785 if (err)
1786 return err;
1787
1788 nla_nest_end(msg, iftdata);
1789 }
1790
1791 nla_nest_end(msg, nl_iftype_data);
1792 }
1793
2a38075c 1794 /* add EDMG info */
f8d504ca 1795 if (large && sband->edmg_cap.channels &&
2a38075c
AAL
1796 (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
1797 sband->edmg_cap.channels) ||
1798 nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
1799 sband->edmg_cap.bw_config)))
1800
1801 return -ENOBUFS;
1802
3713b4e3 1803 /* add bitrates */
ae0be8de 1804 nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
3713b4e3
JB
1805 if (!nl_rates)
1806 return -ENOBUFS;
ee688b00 1807
3713b4e3 1808 for (i = 0; i < sband->n_bitrates; i++) {
ae0be8de 1809 nl_rate = nla_nest_start_noflag(msg, i);
3713b4e3
JB
1810 if (!nl_rate)
1811 return -ENOBUFS;
ee688b00 1812
3713b4e3
JB
1813 rate = &sband->bitrates[i];
1814 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1815 rate->bitrate))
1816 return -ENOBUFS;
1817 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1818 nla_put_flag(msg,
1819 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1820 return -ENOBUFS;
ee688b00 1821
3713b4e3
JB
1822 nla_nest_end(msg, nl_rate);
1823 }
d51626df 1824
3713b4e3 1825 nla_nest_end(msg, nl_rates);
bf0c111e 1826
3713b4e3
JB
1827 return 0;
1828}
ee688b00 1829
3713b4e3
JB
1830static int
1831nl80211_send_mgmt_stypes(struct sk_buff *msg,
1832 const struct ieee80211_txrx_stypes *mgmt_stypes)
1833{
1834 u16 stypes;
1835 struct nlattr *nl_ftypes, *nl_ifs;
1836 enum nl80211_iftype ift;
1837 int i;
ee688b00 1838
3713b4e3
JB
1839 if (!mgmt_stypes)
1840 return 0;
5dab3b8a 1841
ae0be8de 1842 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_TX_FRAME_TYPES);
3713b4e3
JB
1843 if (!nl_ifs)
1844 return -ENOBUFS;
e2f367f2 1845
3713b4e3 1846 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1847 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1848 if (!nl_ftypes)
1849 return -ENOBUFS;
1850 i = 0;
1851 stypes = mgmt_stypes[ift].tx;
1852 while (stypes) {
1853 if ((stypes & 1) &&
1854 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1855 (i << 4) | IEEE80211_FTYPE_MGMT))
1856 return -ENOBUFS;
1857 stypes >>= 1;
1858 i++;
ee688b00 1859 }
3713b4e3
JB
1860 nla_nest_end(msg, nl_ftypes);
1861 }
ee688b00 1862
3713b4e3 1863 nla_nest_end(msg, nl_ifs);
ee688b00 1864
ae0be8de 1865 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_RX_FRAME_TYPES);
3713b4e3
JB
1866 if (!nl_ifs)
1867 return -ENOBUFS;
ee688b00 1868
3713b4e3 1869 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1870 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1871 if (!nl_ftypes)
1872 return -ENOBUFS;
1873 i = 0;
1874 stypes = mgmt_stypes[ift].rx;
1875 while (stypes) {
1876 if ((stypes & 1) &&
1877 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1878 (i << 4) | IEEE80211_FTYPE_MGMT))
1879 return -ENOBUFS;
1880 stypes >>= 1;
1881 i++;
1882 }
1883 nla_nest_end(msg, nl_ftypes);
1884 }
1885 nla_nest_end(msg, nl_ifs);
ee688b00 1886
3713b4e3
JB
1887 return 0;
1888}
ee688b00 1889
1794899e
JB
1890#define CMD(op, n) \
1891 do { \
1892 if (rdev->ops->op) { \
1893 i++; \
1894 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1895 goto nla_put_failure; \
1896 } \
1897 } while (0)
1898
1899static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1900 struct sk_buff *msg)
1901{
1902 int i = 0;
1903
1904 /*
1905 * do *NOT* add anything into this function, new things need to be
1906 * advertised only to new versions of userspace that can deal with
1907 * the split (and they can't possibly care about new features...
1908 */
1909 CMD(add_virtual_intf, NEW_INTERFACE);
1910 CMD(change_virtual_intf, SET_INTERFACE);
1911 CMD(add_key, NEW_KEY);
1912 CMD(start_ap, START_AP);
1913 CMD(add_station, NEW_STATION);
1914 CMD(add_mpath, NEW_MPATH);
1915 CMD(update_mesh_config, SET_MESH_CONFIG);
1916 CMD(change_bss, SET_BSS);
1917 CMD(auth, AUTHENTICATE);
1918 CMD(assoc, ASSOCIATE);
1919 CMD(deauth, DEAUTHENTICATE);
1920 CMD(disassoc, DISASSOCIATE);
1921 CMD(join_ibss, JOIN_IBSS);
1922 CMD(join_mesh, JOIN_MESH);
1923 CMD(set_pmksa, SET_PMKSA);
1924 CMD(del_pmksa, DEL_PMKSA);
1925 CMD(flush_pmksa, FLUSH_PMKSA);
1926 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1927 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1928 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1929 CMD(mgmt_tx, FRAME);
1930 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1931 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1932 i++;
1933 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1934 goto nla_put_failure;
1935 }
1936 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1937 rdev->ops->join_mesh) {
1938 i++;
1939 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1940 goto nla_put_failure;
1941 }
1794899e
JB
1942 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1943 CMD(tdls_mgmt, TDLS_MGMT);
1944 CMD(tdls_oper, TDLS_OPER);
1945 }
ca986ad9 1946 if (rdev->wiphy.max_sched_scan_reqs)
1794899e
JB
1947 CMD(sched_scan_start, START_SCHED_SCAN);
1948 CMD(probe_client, PROBE_CLIENT);
1949 CMD(set_noack_map, SET_NOACK_MAP);
1950 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1951 i++;
1952 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1953 goto nla_put_failure;
1954 }
1955 CMD(start_p2p_device, START_P2P_DEVICE);
1956 CMD(set_mcast_rate, SET_MCAST_RATE);
1957#ifdef CONFIG_NL80211_TESTMODE
1958 CMD(testmode_cmd, TESTMODE);
1959#endif
1960
1961 if (rdev->ops->connect || rdev->ops->auth) {
1962 i++;
1963 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1964 goto nla_put_failure;
1965 }
1966
1967 if (rdev->ops->disconnect || rdev->ops->deauth) {
1968 i++;
1969 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1970 goto nla_put_failure;
1971 }
1972
1973 return i;
1974 nla_put_failure:
1975 return -ENOBUFS;
1976}
1977
9bb7e0f2
JB
1978static int
1979nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
1980 struct sk_buff *msg)
1981{
1982 struct nlattr *ftm;
1983
1984 if (!cap->ftm.supported)
1985 return 0;
1986
ae0be8de 1987 ftm = nla_nest_start_noflag(msg, NL80211_PMSR_TYPE_FTM);
9bb7e0f2
JB
1988 if (!ftm)
1989 return -ENOBUFS;
1990
1991 if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
1992 return -ENOBUFS;
1993 if (cap->ftm.non_asap &&
1994 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
1995 return -ENOBUFS;
1996 if (cap->ftm.request_lci &&
1997 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
1998 return -ENOBUFS;
1999 if (cap->ftm.request_civicloc &&
2000 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
2001 return -ENOBUFS;
2002 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
2003 cap->ftm.preambles))
2004 return -ENOBUFS;
2005 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
2006 cap->ftm.bandwidths))
2007 return -ENOBUFS;
2008 if (cap->ftm.max_bursts_exponent >= 0 &&
2009 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
2010 cap->ftm.max_bursts_exponent))
2011 return -ENOBUFS;
2012 if (cap->ftm.max_ftms_per_burst &&
2013 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
2014 cap->ftm.max_ftms_per_burst))
2015 return -ENOBUFS;
efb5520d
AS
2016 if (cap->ftm.trigger_based &&
2017 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED))
2018 return -ENOBUFS;
2019 if (cap->ftm.non_trigger_based &&
2020 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED))
2021 return -ENOBUFS;
9bb7e0f2
JB
2022
2023 nla_nest_end(msg, ftm);
2024 return 0;
2025}
2026
2027static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
2028 struct sk_buff *msg)
2029{
2030 const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
2031 struct nlattr *pmsr, *caps;
2032
2033 if (!cap)
2034 return 0;
2035
2036 /*
2037 * we don't need to clean up anything here since the caller
2038 * will genlmsg_cancel() if we fail
2039 */
2040
ae0be8de 2041 pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
9bb7e0f2
JB
2042 if (!pmsr)
2043 return -ENOBUFS;
2044
2045 if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
2046 return -ENOBUFS;
2047
2048 if (cap->report_ap_tsf &&
2049 nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
2050 return -ENOBUFS;
2051
2052 if (cap->randomize_mac_addr &&
2053 nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
2054 return -ENOBUFS;
2055
ae0be8de 2056 caps = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
9bb7e0f2
JB
2057 if (!caps)
2058 return -ENOBUFS;
2059
2060 if (nl80211_send_pmsr_ftm_capa(cap, msg))
2061 return -ENOBUFS;
2062
2063 nla_nest_end(msg, caps);
2064 nla_nest_end(msg, pmsr);
2065
2066 return 0;
2067}
2068
d6039a34
VJ
2069static int
2070nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
2071 struct sk_buff *msg)
2072{
2073 int i;
2074 struct nlattr *nested, *nested_akms;
2075 const struct wiphy_iftype_akm_suites *iftype_akms;
2076
2077 if (!rdev->wiphy.num_iftype_akm_suites ||
2078 !rdev->wiphy.iftype_akm_suites)
2079 return 0;
2080
2081 nested = nla_nest_start(msg, NL80211_ATTR_IFTYPE_AKM_SUITES);
2082 if (!nested)
2083 return -ENOBUFS;
2084
2085 for (i = 0; i < rdev->wiphy.num_iftype_akm_suites; i++) {
2086 nested_akms = nla_nest_start(msg, i + 1);
2087 if (!nested_akms)
2088 return -ENOBUFS;
2089
2090 iftype_akms = &rdev->wiphy.iftype_akm_suites[i];
2091
2092 if (nl80211_put_iftypes(msg, NL80211_IFTYPE_AKM_ATTR_IFTYPES,
2093 iftype_akms->iftypes_mask))
2094 return -ENOBUFS;
2095
2096 if (nla_put(msg, NL80211_IFTYPE_AKM_ATTR_SUITES,
2097 sizeof(u32) * iftype_akms->n_akm_suites,
2098 iftype_akms->akm_suites)) {
2099 return -ENOBUFS;
2100 }
2101 nla_nest_end(msg, nested_akms);
2102 }
2103
2104 nla_nest_end(msg, nested);
2105
2106 return 0;
2107}
2108
3710a8a6
JB
2109static int
2110nl80211_put_tid_config_support(struct cfg80211_registered_device *rdev,
2111 struct sk_buff *msg)
2112{
2113 struct nlattr *supp;
2114
2115 if (!rdev->wiphy.tid_config_support.vif &&
2116 !rdev->wiphy.tid_config_support.peer)
2117 return 0;
2118
2119 supp = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
2120 if (!supp)
2121 return -ENOSPC;
2122
2123 if (rdev->wiphy.tid_config_support.vif &&
2124 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_VIF_SUPP,
2125 rdev->wiphy.tid_config_support.vif,
2126 NL80211_TID_CONFIG_ATTR_PAD))
2127 goto fail;
2128
2129 if (rdev->wiphy.tid_config_support.peer &&
2130 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_PEER_SUPP,
2131 rdev->wiphy.tid_config_support.peer,
2132 NL80211_TID_CONFIG_ATTR_PAD))
2133 goto fail;
2134
6a21d16c
T
2135 /* for now we just use the same value ... makes more sense */
2136 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
2137 rdev->wiphy.tid_config_support.max_retry))
2138 goto fail;
2139 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG,
2140 rdev->wiphy.tid_config_support.max_retry))
2141 goto fail;
2142
3710a8a6
JB
2143 nla_nest_end(msg, supp);
2144
2145 return 0;
2146fail:
2147 nla_nest_cancel(msg, supp);
2148 return -ENOBUFS;
2149}
2150
6bdb68ce
CH
2151static int
2152nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
2153 struct sk_buff *msg)
2154{
2155 struct nlattr *sar_capa, *specs, *sub_freq_range;
2156 u8 num_freq_ranges;
2157 int i;
2158
2159 if (!rdev->wiphy.sar_capa)
2160 return 0;
2161
2162 num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
2163
2164 sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
2165 if (!sar_capa)
2166 return -ENOSPC;
2167
2168 if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
2169 goto fail;
2170
2171 specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
2172 if (!specs)
2173 goto fail;
2174
2175 /* report supported freq_ranges */
2176 for (i = 0; i < num_freq_ranges; i++) {
2177 sub_freq_range = nla_nest_start(msg, i + 1);
2178 if (!sub_freq_range)
2179 goto fail;
2180
2181 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
2182 rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
2183 goto fail;
2184
2185 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
2186 rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
2187 goto fail;
2188
2189 nla_nest_end(msg, sub_freq_range);
2190 }
2191
2192 nla_nest_end(msg, specs);
2193 nla_nest_end(msg, sar_capa);
2194
2195 return 0;
2196fail:
2197 nla_nest_cancel(msg, sar_capa);
2198 return -ENOBUFS;
2199}
2200
86e8cf98
JB
2201struct nl80211_dump_wiphy_state {
2202 s64 filter_wiphy;
2203 long start;
019ae3a9 2204 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
2205 bool split;
2206};
2207
1b8ec87a 2208static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 2209 enum nl80211_commands cmd,
3713b4e3 2210 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 2211 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
2212{
2213 void *hdr;
2214 struct nlattr *nl_bands, *nl_band;
2215 struct nlattr *nl_freqs, *nl_freq;
2216 struct nlattr *nl_cmds;
57fbcce3 2217 enum nl80211_band band;
3713b4e3
JB
2218 struct ieee80211_channel *chan;
2219 int i;
2220 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 2221 rdev->wiphy.mgmt_stypes;
fe1abafd 2222 u32 features;
ee688b00 2223
3bb20556 2224 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
2225 if (!hdr)
2226 return -ENOBUFS;
ee688b00 2227
86e8cf98
JB
2228 if (WARN_ON(!state))
2229 return -EINVAL;
ee688b00 2230
1b8ec87a 2231 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 2232 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 2233 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
2234 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2235 cfg80211_rdev_list_generation))
8fdc621d
JB
2236 goto nla_put_failure;
2237
3bb20556
JB
2238 if (cmd != NL80211_CMD_NEW_WIPHY)
2239 goto finish;
2240
86e8cf98 2241 switch (state->split_start) {
3713b4e3
JB
2242 case 0:
2243 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 2244 rdev->wiphy.retry_short) ||
3713b4e3 2245 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 2246 rdev->wiphy.retry_long) ||
3713b4e3 2247 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 2248 rdev->wiphy.frag_threshold) ||
3713b4e3 2249 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 2250 rdev->wiphy.rts_threshold) ||
3713b4e3 2251 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 2252 rdev->wiphy.coverage_class) ||
3713b4e3 2253 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 2254 rdev->wiphy.max_scan_ssids) ||
3713b4e3 2255 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 2256 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 2257 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 2258 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 2259 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 2260 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 2261 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
f8d504ca 2262 rdev->wiphy.max_match_sets))
9360ffd1 2263 goto nla_put_failure;
3713b4e3 2264
1b8ec87a 2265 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 2266 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 2267 goto nla_put_failure;
1b8ec87a 2268 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
2269 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
2270 goto nla_put_failure;
1b8ec87a 2271 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
2272 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
2273 goto nla_put_failure;
1b8ec87a 2274 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
2275 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
2276 goto nla_put_failure;
1b8ec87a 2277 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
2278 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
2279 goto nla_put_failure;
1b8ec87a 2280 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 2281 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 2282 goto nla_put_failure;
86e8cf98
JB
2283 state->split_start++;
2284 if (state->split)
3713b4e3 2285 break;
7b506ff6 2286 fallthrough;
3713b4e3
JB
2287 case 1:
2288 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
2289 sizeof(u32) * rdev->wiphy.n_cipher_suites,
2290 rdev->wiphy.cipher_suites))
3713b4e3 2291 goto nla_put_failure;
4745fc09 2292
3713b4e3 2293 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 2294 rdev->wiphy.max_num_pmkids))
3713b4e3 2295 goto nla_put_failure;
b23aa676 2296
1b8ec87a 2297 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 2298 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 2299 goto nla_put_failure;
b23aa676 2300
3713b4e3 2301 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 2302 rdev->wiphy.available_antennas_tx) ||
3713b4e3 2303 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 2304 rdev->wiphy.available_antennas_rx))
9360ffd1 2305 goto nla_put_failure;
b23aa676 2306
1b8ec87a 2307 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 2308 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 2309 rdev->wiphy.probe_resp_offload))
3713b4e3 2310 goto nla_put_failure;
8fdc621d 2311
1b8ec87a
ZG
2312 if ((rdev->wiphy.available_antennas_tx ||
2313 rdev->wiphy.available_antennas_rx) &&
2314 rdev->ops->get_antenna) {
3713b4e3
JB
2315 u32 tx_ant = 0, rx_ant = 0;
2316 int res;
7a087e74 2317
1b8ec87a 2318 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
2319 if (!res) {
2320 if (nla_put_u32(msg,
2321 NL80211_ATTR_WIPHY_ANTENNA_TX,
2322 tx_ant) ||
2323 nla_put_u32(msg,
2324 NL80211_ATTR_WIPHY_ANTENNA_RX,
2325 rx_ant))
2326 goto nla_put_failure;
2327 }
2328 }
a293911d 2329
86e8cf98
JB
2330 state->split_start++;
2331 if (state->split)
3713b4e3 2332 break;
7b506ff6 2333 fallthrough;
3713b4e3
JB
2334 case 2:
2335 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 2336 rdev->wiphy.interface_modes))
3713b4e3 2337 goto nla_put_failure;
86e8cf98
JB
2338 state->split_start++;
2339 if (state->split)
3713b4e3 2340 break;
7b506ff6 2341 fallthrough;
3713b4e3 2342 case 3:
ae0be8de
MK
2343 nl_bands = nla_nest_start_noflag(msg,
2344 NL80211_ATTR_WIPHY_BANDS);
3713b4e3
JB
2345 if (!nl_bands)
2346 goto nla_put_failure;
f7ca38df 2347
86e8cf98 2348 for (band = state->band_start;
57fbcce3 2349 band < NUM_NL80211_BANDS; band++) {
3713b4e3 2350 struct ieee80211_supported_band *sband;
2e161f78 2351
f8d504ca
JB
2352 /* omit higher bands for ancient software */
2353 if (band > NL80211_BAND_5GHZ && !state->split)
2354 break;
2355
1b8ec87a 2356 sband = rdev->wiphy.bands[band];
2e161f78 2357
3713b4e3
JB
2358 if (!sband)
2359 continue;
2360
ae0be8de 2361 nl_band = nla_nest_start_noflag(msg, band);
3713b4e3 2362 if (!nl_band)
2e161f78 2363 goto nla_put_failure;
3713b4e3 2364
86e8cf98 2365 switch (state->chan_start) {
3713b4e3 2366 case 0:
f8d504ca
JB
2367 if (nl80211_send_band_rateinfo(msg, sband,
2368 state->split))
9360ffd1 2369 goto nla_put_failure;
86e8cf98
JB
2370 state->chan_start++;
2371 if (state->split)
3713b4e3 2372 break;
7b506ff6 2373 fallthrough;
3713b4e3
JB
2374 default:
2375 /* add frequencies */
ae0be8de
MK
2376 nl_freqs = nla_nest_start_noflag(msg,
2377 NL80211_BAND_ATTR_FREQS);
3713b4e3
JB
2378 if (!nl_freqs)
2379 goto nla_put_failure;
2380
86e8cf98 2381 for (i = state->chan_start - 1;
3713b4e3
JB
2382 i < sband->n_channels;
2383 i++) {
ae0be8de
MK
2384 nl_freq = nla_nest_start_noflag(msg,
2385 i);
3713b4e3
JB
2386 if (!nl_freq)
2387 goto nla_put_failure;
2388
2389 chan = &sband->channels[i];
2390
86e8cf98 2391 if (nl80211_msg_put_channel(
50f32718 2392 msg, &rdev->wiphy, chan,
86e8cf98 2393 state->split))
3713b4e3
JB
2394 goto nla_put_failure;
2395
2396 nla_nest_end(msg, nl_freq);
86e8cf98 2397 if (state->split)
3713b4e3
JB
2398 break;
2399 }
2400 if (i < sband->n_channels)
86e8cf98 2401 state->chan_start = i + 2;
3713b4e3 2402 else
86e8cf98 2403 state->chan_start = 0;
3713b4e3
JB
2404 nla_nest_end(msg, nl_freqs);
2405 }
2406
2407 nla_nest_end(msg, nl_band);
2408
86e8cf98 2409 if (state->split) {
3713b4e3 2410 /* start again here */
86e8cf98 2411 if (state->chan_start)
3713b4e3
JB
2412 band--;
2413 break;
2e161f78 2414 }
2e161f78 2415 }
3713b4e3 2416 nla_nest_end(msg, nl_bands);
2e161f78 2417
57fbcce3 2418 if (band < NUM_NL80211_BANDS)
86e8cf98 2419 state->band_start = band + 1;
3713b4e3 2420 else
86e8cf98 2421 state->band_start = 0;
74b70a4e 2422
3713b4e3 2423 /* if bands & channels are done, continue outside */
86e8cf98
JB
2424 if (state->band_start == 0 && state->chan_start == 0)
2425 state->split_start++;
2426 if (state->split)
3713b4e3 2427 break;
7b506ff6 2428 fallthrough;
3713b4e3 2429 case 4:
ae0be8de
MK
2430 nl_cmds = nla_nest_start_noflag(msg,
2431 NL80211_ATTR_SUPPORTED_COMMANDS);
3713b4e3 2432 if (!nl_cmds)
2e161f78
JB
2433 goto nla_put_failure;
2434
1794899e
JB
2435 i = nl80211_add_commands_unsplit(rdev, msg);
2436 if (i < 0)
2437 goto nla_put_failure;
86e8cf98 2438 if (state->split) {
5de17984
AS
2439 CMD(crit_proto_start, CRIT_PROTOCOL_START);
2440 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 2441 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 2442 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 2443 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
2444 if (rdev->wiphy.features &
2445 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 2446 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 2447 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 2448 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
7010998c 2449 CMD(update_ft_ies, UPDATE_FT_IES);
6bdb68ce
CH
2450 if (rdev->wiphy.sar_capa)
2451 CMD(set_sar_specs, SET_SAR_SPECS);
5de17984 2452 }
3713b4e3 2453#undef CMD
ff1b6e69 2454
3713b4e3 2455 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
2456 state->split_start++;
2457 if (state->split)
3713b4e3 2458 break;
7b506ff6 2459 fallthrough;
3713b4e3 2460 case 5:
1b8ec87a
ZG
2461 if (rdev->ops->remain_on_channel &&
2462 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
2463 nla_put_u32(msg,
2464 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 2465 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
2466 goto nla_put_failure;
2467
1b8ec87a 2468 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
2469 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
2470 goto nla_put_failure;
2471
86e8cf98
JB
2472 state->split_start++;
2473 if (state->split)
3713b4e3 2474 break;
7b506ff6 2475 fallthrough;
3713b4e3
JB
2476 case 6:
2477#ifdef CONFIG_PM
1b8ec87a 2478 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 2479 goto nla_put_failure;
86e8cf98
JB
2480 state->split_start++;
2481 if (state->split)
3713b4e3
JB
2482 break;
2483#else
86e8cf98 2484 state->split_start++;
dfb89c56 2485#endif
7b506ff6 2486 fallthrough;
3713b4e3
JB
2487 case 7:
2488 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 2489 rdev->wiphy.software_iftypes))
3713b4e3 2490 goto nla_put_failure;
ff1b6e69 2491
1b8ec87a 2492 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 2493 state->split))
3713b4e3 2494 goto nla_put_failure;
7527a782 2495
86e8cf98
JB
2496 state->split_start++;
2497 if (state->split)
3713b4e3 2498 break;
7b506ff6 2499 fallthrough;
3713b4e3 2500 case 8:
1b8ec87a 2501 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 2502 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 2503 rdev->wiphy.ap_sme_capa))
3713b4e3 2504 goto nla_put_failure;
7527a782 2505
1b8ec87a 2506 features = rdev->wiphy.features;
fe1abafd
JB
2507 /*
2508 * We can only add the per-channel limit information if the
2509 * dump is split, otherwise it makes it too big. Therefore
2510 * only advertise it in that case.
2511 */
86e8cf98 2512 if (state->split)
fe1abafd
JB
2513 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
2514 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 2515 goto nla_put_failure;
562a7480 2516
1b8ec87a 2517 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 2518 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
2519 sizeof(*rdev->wiphy.ht_capa_mod_mask),
2520 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 2521 goto nla_put_failure;
1f074bd8 2522
1b8ec87a
ZG
2523 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
2524 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 2525 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 2526 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 2527 goto nla_put_failure;
7e7c8926 2528
3713b4e3
JB
2529 /*
2530 * Any information below this point is only available to
2531 * applications that can deal with it being split. This
2532 * helps ensure that newly added capabilities don't break
2533 * older tools by overrunning their buffers.
2534 *
2535 * We still increment split_start so that in the split
2536 * case we'll continue with more data in the next round,
2537 * but break unconditionally so unsplit data stops here.
2538 */
ab10c22b
JB
2539 if (state->split)
2540 state->split_start++;
2541 else
2542 state->split_start = 0;
3713b4e3
JB
2543 break;
2544 case 9:
f8d504ca
JB
2545 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
2546 goto nla_put_failure;
2547
2548 if (nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
2549 rdev->wiphy.max_sched_scan_plans) ||
2550 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
2551 rdev->wiphy.max_sched_scan_plan_interval) ||
2552 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
2553 rdev->wiphy.max_sched_scan_plan_iterations))
2554 goto nla_put_failure;
2555
1b8ec87a 2556 if (rdev->wiphy.extended_capabilities &&
fe1abafd 2557 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
2558 rdev->wiphy.extended_capabilities_len,
2559 rdev->wiphy.extended_capabilities) ||
fe1abafd 2560 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
2561 rdev->wiphy.extended_capabilities_len,
2562 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 2563 goto nla_put_failure;
a50df0c4 2564
1b8ec87a 2565 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 2566 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
2567 sizeof(*rdev->wiphy.vht_capa_mod_mask),
2568 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
2569 goto nla_put_failure;
2570
ae6fa4d5
DK
2571 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
2572 rdev->wiphy.perm_addr))
2573 goto nla_put_failure;
2574
2575 if (!is_zero_ether_addr(rdev->wiphy.addr_mask) &&
2576 nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
2577 rdev->wiphy.addr_mask))
2578 goto nla_put_failure;
2579
2580 if (rdev->wiphy.n_addresses > 1) {
2581 void *attr;
2582
2583 attr = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
2584 if (!attr)
2585 goto nla_put_failure;
2586
2587 for (i = 0; i < rdev->wiphy.n_addresses; i++)
2588 if (nla_put(msg, i + 1, ETH_ALEN,
2589 rdev->wiphy.addresses[i].addr))
2590 goto nla_put_failure;
2591
2592 nla_nest_end(msg, attr);
2593 }
2594
be29b99a
AK
2595 state->split_start++;
2596 break;
2597 case 10:
1b8ec87a 2598 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
2599 goto nla_put_failure;
2600
1b8ec87a 2601 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
2602 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
2603 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
2604 goto nla_put_failure;
b43504cf 2605
1b8ec87a 2606 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 2607 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 2608 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
2609 goto nla_put_failure;
2610
ad7e718c
JB
2611 state->split_start++;
2612 break;
2613 case 11:
1b8ec87a 2614 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
2615 const struct nl80211_vendor_cmd_info *info;
2616 struct nlattr *nested;
2617
ae0be8de
MK
2618 nested = nla_nest_start_noflag(msg,
2619 NL80211_ATTR_VENDOR_DATA);
567ffc35
JB
2620 if (!nested)
2621 goto nla_put_failure;
2622
1b8ec87a
ZG
2623 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
2624 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
2625 if (nla_put(msg, i + 1, sizeof(*info), info))
2626 goto nla_put_failure;
2627 }
2628 nla_nest_end(msg, nested);
2629 }
2630
1b8ec87a 2631 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
2632 const struct nl80211_vendor_cmd_info *info;
2633 struct nlattr *nested;
ad7e718c 2634
ae0be8de
MK
2635 nested = nla_nest_start_noflag(msg,
2636 NL80211_ATTR_VENDOR_EVENTS);
567ffc35 2637 if (!nested)
ad7e718c 2638 goto nla_put_failure;
567ffc35 2639
1b8ec87a
ZG
2640 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
2641 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
2642 if (nla_put(msg, i + 1, sizeof(*info), info))
2643 goto nla_put_failure;
2644 }
2645 nla_nest_end(msg, nested);
2646 }
9a774c78
AO
2647 state->split_start++;
2648 break;
2649 case 12:
2650 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
2651 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
2652 rdev->wiphy.max_num_csa_counters))
2653 goto nla_put_failure;
01e0daa4 2654
1bdd716c
AN
2655 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2656 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
2657 goto nla_put_failure;
2658
ca986ad9
AVS
2659 if (rdev->wiphy.max_sched_scan_reqs &&
2660 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
2661 rdev->wiphy.max_sched_scan_reqs))
2662 goto nla_put_failure;
2663
d75bb06b
GKS
2664 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
2665 sizeof(rdev->wiphy.ext_features),
2666 rdev->wiphy.ext_features))
2667 goto nla_put_failure;
2668
38de03d2
AS
2669 if (rdev->wiphy.bss_select_support) {
2670 struct nlattr *nested;
2671 u32 bss_select_support = rdev->wiphy.bss_select_support;
2672
ae0be8de
MK
2673 nested = nla_nest_start_noflag(msg,
2674 NL80211_ATTR_BSS_SELECT);
38de03d2
AS
2675 if (!nested)
2676 goto nla_put_failure;
2677
2678 i = 0;
2679 while (bss_select_support) {
2680 if ((bss_select_support & 1) &&
2681 nla_put_flag(msg, i))
2682 goto nla_put_failure;
2683 i++;
2684 bss_select_support >>= 1;
2685 }
2686 nla_nest_end(msg, nested);
2687 }
2688
019ae3a9
KV
2689 state->split_start++;
2690 break;
2691 case 13:
2692 if (rdev->wiphy.num_iftype_ext_capab &&
2693 rdev->wiphy.iftype_ext_capab) {
2694 struct nlattr *nested_ext_capab, *nested;
2695
ae0be8de
MK
2696 nested = nla_nest_start_noflag(msg,
2697 NL80211_ATTR_IFTYPE_EXT_CAPA);
019ae3a9
KV
2698 if (!nested)
2699 goto nla_put_failure;
2700
2701 for (i = state->capa_start;
2702 i < rdev->wiphy.num_iftype_ext_capab; i++) {
2703 const struct wiphy_iftype_ext_capab *capab;
2704
2705 capab = &rdev->wiphy.iftype_ext_capab[i];
2706
ae0be8de
MK
2707 nested_ext_capab = nla_nest_start_noflag(msg,
2708 i);
019ae3a9
KV
2709 if (!nested_ext_capab ||
2710 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
2711 capab->iftype) ||
2712 nla_put(msg, NL80211_ATTR_EXT_CAPA,
2713 capab->extended_capabilities_len,
2714 capab->extended_capabilities) ||
2715 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
2716 capab->extended_capabilities_len,
2717 capab->extended_capabilities_mask))
2718 goto nla_put_failure;
2719
2720 nla_nest_end(msg, nested_ext_capab);
2721 if (state->split)
2722 break;
2723 }
2724 nla_nest_end(msg, nested);
2725 if (i < rdev->wiphy.num_iftype_ext_capab) {
2726 state->capa_start = i + 1;
2727 break;
2728 }
2729 }
2730
8585989d
LC
2731 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
2732 rdev->wiphy.nan_supported_bands))
2733 goto nla_put_failure;
2734
52539ca8
THJ
2735 if (wiphy_ext_feature_isset(&rdev->wiphy,
2736 NL80211_EXT_FEATURE_TXQS)) {
2737 struct cfg80211_txq_stats txqstats = {};
2738 int res;
2739
2740 res = rdev_get_txq_stats(rdev, NULL, &txqstats);
2741 if (!res &&
2742 !nl80211_put_txq_stats(msg, &txqstats,
2743 NL80211_ATTR_TXQ_STATS))
2744 goto nla_put_failure;
2745
2746 if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
2747 rdev->wiphy.txq_limit))
2748 goto nla_put_failure;
2749 if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
2750 rdev->wiphy.txq_memory_limit))
2751 goto nla_put_failure;
2752 if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
2753 rdev->wiphy.txq_quantum))
2754 goto nla_put_failure;
2755 }
2756
9bb7e0f2
JB
2757 state->split_start++;
2758 break;
2759 case 14:
2760 if (nl80211_send_pmsr_capa(rdev, msg))
2761 goto nla_put_failure;
2762
ab4dfa20
VJ
2763 state->split_start++;
2764 break;
2765 case 15:
2766 if (rdev->wiphy.akm_suites &&
2767 nla_put(msg, NL80211_ATTR_AKM_SUITES,
2768 sizeof(u32) * rdev->wiphy.n_akm_suites,
2769 rdev->wiphy.akm_suites))
2770 goto nla_put_failure;
2771
d6039a34
VJ
2772 if (nl80211_put_iftype_akm_suites(rdev, msg))
2773 goto nla_put_failure;
2774
3710a8a6
JB
2775 if (nl80211_put_tid_config_support(rdev, msg))
2776 goto nla_put_failure;
6bdb68ce
CH
2777 state->split_start++;
2778 break;
2779 case 16:
2780 if (nl80211_put_sar_specs(rdev, msg))
2781 goto nla_put_failure;
3710a8a6 2782
3713b4e3 2783 /* done */
86e8cf98 2784 state->split_start = 0;
3713b4e3
JB
2785 break;
2786 }
3bb20556 2787 finish:
053c095a
JB
2788 genlmsg_end(msg, hdr);
2789 return 0;
55682965
JB
2790
2791 nla_put_failure:
bc3ed28c
TG
2792 genlmsg_cancel(msg, hdr);
2793 return -EMSGSIZE;
55682965
JB
2794}
2795
86e8cf98
JB
2796static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
2797 struct netlink_callback *cb,
2798 struct nl80211_dump_wiphy_state *state)
2799{
50508d94
JB
2800 struct nlattr **tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
2801 int ret;
2802
2803 if (!tb)
2804 return -ENOMEM;
2805
2806 ret = nlmsg_parse_deprecated(cb->nlh,
2807 GENL_HDRLEN + nl80211_fam.hdrsize,
2808 tb, nl80211_fam.maxattr,
2809 nl80211_policy, NULL);
86e8cf98 2810 /* ignore parse errors for backward compatibility */
50508d94
JB
2811 if (ret) {
2812 ret = 0;
2813 goto out;
2814 }
86e8cf98
JB
2815
2816 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
2817 if (tb[NL80211_ATTR_WIPHY])
2818 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2819 if (tb[NL80211_ATTR_WDEV])
2820 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
2821 if (tb[NL80211_ATTR_IFINDEX]) {
2822 struct net_device *netdev;
2823 struct cfg80211_registered_device *rdev;
2824 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2825
7f2b8562 2826 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
50508d94
JB
2827 if (!netdev) {
2828 ret = -ENODEV;
2829 goto out;
2830 }
86e8cf98 2831 if (netdev->ieee80211_ptr) {
f26cbf40 2832 rdev = wiphy_to_rdev(
86e8cf98
JB
2833 netdev->ieee80211_ptr->wiphy);
2834 state->filter_wiphy = rdev->wiphy_idx;
2835 }
86e8cf98
JB
2836 }
2837
50508d94
JB
2838 ret = 0;
2839out:
2840 kfree(tb);
2841 return ret;
86e8cf98
JB
2842}
2843
55682965
JB
2844static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
2845{
645e77de 2846 int idx = 0, ret;
86e8cf98 2847 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 2848 struct cfg80211_registered_device *rdev;
3a5a423b 2849
5fe231e8 2850 rtnl_lock();
86e8cf98
JB
2851 if (!state) {
2852 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
2853 if (!state) {
2854 rtnl_unlock();
86e8cf98 2855 return -ENOMEM;
3713b4e3 2856 }
86e8cf98
JB
2857 state->filter_wiphy = -1;
2858 ret = nl80211_dump_wiphy_parse(skb, cb, state);
2859 if (ret) {
2860 kfree(state);
2861 rtnl_unlock();
2862 return ret;
3713b4e3 2863 }
86e8cf98 2864 cb->args[0] = (long)state;
3713b4e3
JB
2865 }
2866
1b8ec87a
ZG
2867 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2868 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2869 continue;
86e8cf98 2870 if (++idx <= state->start)
55682965 2871 continue;
86e8cf98 2872 if (state->filter_wiphy != -1 &&
1b8ec87a 2873 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
2874 continue;
2875 /* attempt to fit multiple wiphy data chunks into the skb */
2876 do {
3bb20556
JB
2877 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
2878 skb,
3713b4e3
JB
2879 NETLINK_CB(cb->skb).portid,
2880 cb->nlh->nlmsg_seq,
86e8cf98 2881 NLM_F_MULTI, state);
3713b4e3
JB
2882 if (ret < 0) {
2883 /*
2884 * If sending the wiphy data didn't fit (ENOBUFS
2885 * or EMSGSIZE returned), this SKB is still
2886 * empty (so it's not too big because another
2887 * wiphy dataset is already in the skb) and
2888 * we've not tried to adjust the dump allocation
2889 * yet ... then adjust the alloc size to be
2890 * bigger, and return 1 but with the empty skb.
2891 * This results in an empty message being RX'ed
2892 * in userspace, but that is ignored.
2893 *
2894 * We can then retry with the larger buffer.
2895 */
2896 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 2897 !skb->len && !state->split &&
3713b4e3
JB
2898 cb->min_dump_alloc < 4096) {
2899 cb->min_dump_alloc = 4096;
f12cb289 2900 state->split_start = 0;
d98cae64 2901 rtnl_unlock();
3713b4e3
JB
2902 return 1;
2903 }
2904 idx--;
2905 break;
645e77de 2906 }
86e8cf98 2907 } while (state->split_start > 0);
3713b4e3 2908 break;
55682965 2909 }
5fe231e8 2910 rtnl_unlock();
55682965 2911
86e8cf98 2912 state->start = idx;
55682965
JB
2913
2914 return skb->len;
2915}
2916
86e8cf98
JB
2917static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
2918{
2919 kfree((void *)cb->args[0]);
2920 return 0;
2921}
2922
55682965
JB
2923static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
2924{
2925 struct sk_buff *msg;
1b8ec87a 2926 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2927 struct nl80211_dump_wiphy_state state = {};
55682965 2928
645e77de 2929 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2930 if (!msg)
4c476991 2931 return -ENOMEM;
55682965 2932
3bb20556
JB
2933 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2934 info->snd_portid, info->snd_seq, 0,
86e8cf98 2935 &state) < 0) {
4c476991
JB
2936 nlmsg_free(msg);
2937 return -ENOBUFS;
2938 }
55682965 2939
134e6375 2940 return genlmsg_reply(msg, info);
55682965
JB
2941}
2942
31888487
JM
2943static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2944 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2945 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2946 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2947 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2948 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2949};
2950
2951static int parse_txq_params(struct nlattr *tb[],
2952 struct ieee80211_txq_params *txq_params)
2953{
259d8c1e
DW
2954 u8 ac;
2955
a3304b0a 2956 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2957 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2958 !tb[NL80211_TXQ_ATTR_AIFS])
2959 return -EINVAL;
2960
259d8c1e 2961 ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2962 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2963 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2964 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2965 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2966
259d8c1e 2967 if (ac >= NL80211_NUM_ACS)
a3304b0a 2968 return -EINVAL;
259d8c1e 2969 txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
31888487
JM
2970 return 0;
2971}
2972
f444de05
JB
2973static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2974{
2975 /*
e7e0517c
JB
2976 * You can only set the channel explicitly for some interfaces,
2977 * most have their channel managed via their respective
cc1d2806
JB
2978 * "establish a connection" command (connect, join, ...)
2979 *
2980 * For AP/GO and mesh mode, the channel can be set with the
2981 * channel userspace API, but is only stored and passed to the
2982 * low-level driver when the AP starts or the mesh is joined.
2983 * This is for backward compatibility, userspace can also give
2984 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2985 *
2986 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2987 * whatever else is going on, so they have their own special
2988 * operation to set the monitor channel if possible.
f444de05
JB
2989 */
2990 return !wdev ||
2991 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2992 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2993 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2994 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2995}
2996
9bb7e0f2
JB
2997int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2998 struct genl_info *info,
2999 struct cfg80211_chan_def *chandef)
683b6d3b 3000{
49f9cf0e
JB
3001 struct netlink_ext_ack *extack = info->extack;
3002 struct nlattr **attrs = info->attrs;
dbeca2ea 3003 u32 control_freq;
683b6d3b 3004
49f9cf0e 3005 if (!attrs[NL80211_ATTR_WIPHY_FREQ])
683b6d3b
JB
3006 return -EINVAL;
3007
942ba88b
TP
3008 control_freq = MHZ_TO_KHZ(
3009 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3010 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
3011 control_freq +=
3012 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
683b6d3b 3013
f43e5210 3014 memset(chandef, 0, sizeof(*chandef));
942ba88b 3015 chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
3d9d1d66 3016 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
942ba88b
TP
3017 chandef->center_freq1 = KHZ_TO_MHZ(control_freq);
3018 chandef->freq1_offset = control_freq % 1000;
3d9d1d66 3019 chandef->center_freq2 = 0;
683b6d3b
JB
3020
3021 /* Primary channel not allowed */
49f9cf0e
JB
3022 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) {
3023 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
3024 "Channel is disabled");
683b6d3b 3025 return -EINVAL;
49f9cf0e 3026 }
683b6d3b 3027
49f9cf0e 3028 if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
3d9d1d66
JB
3029 enum nl80211_channel_type chantype;
3030
49f9cf0e 3031 chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
3d9d1d66
JB
3032
3033 switch (chantype) {
3034 case NL80211_CHAN_NO_HT:
3035 case NL80211_CHAN_HT20:
3036 case NL80211_CHAN_HT40PLUS:
3037 case NL80211_CHAN_HT40MINUS:
3038 cfg80211_chandef_create(chandef, chandef->chan,
3039 chantype);
ffa4629e 3040 /* user input for center_freq is incorrect */
49f9cf0e
JB
3041 if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
3042 chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
3043 NL_SET_ERR_MSG_ATTR(extack,
3044 attrs[NL80211_ATTR_CENTER_FREQ1],
3045 "bad center frequency 1");
ffa4629e 3046 return -EINVAL;
49f9cf0e 3047 }
ffa4629e 3048 /* center_freq2 must be zero */
49f9cf0e
JB
3049 if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
3050 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
3051 NL_SET_ERR_MSG_ATTR(extack,
3052 attrs[NL80211_ATTR_CENTER_FREQ2],
3053 "center frequency 2 can't be used");
ffa4629e 3054 return -EINVAL;
49f9cf0e 3055 }
3d9d1d66
JB
3056 break;
3057 default:
49f9cf0e
JB
3058 NL_SET_ERR_MSG_ATTR(extack,
3059 attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3060 "invalid channel type");
3d9d1d66
JB
3061 return -EINVAL;
3062 }
49f9cf0e 3063 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
3d9d1d66 3064 chandef->width =
49f9cf0e 3065 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
942ba88b 3066 if (attrs[NL80211_ATTR_CENTER_FREQ1]) {
3d9d1d66 3067 chandef->center_freq1 =
49f9cf0e 3068 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
942ba88b
TP
3069 if (attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET])
3070 chandef->freq1_offset = nla_get_u32(
3071 attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET]);
3072 else
3073 chandef->freq1_offset = 0;
3074 }
49f9cf0e 3075 if (attrs[NL80211_ATTR_CENTER_FREQ2])
3d9d1d66 3076 chandef->center_freq2 =
49f9cf0e 3077 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
3d9d1d66
JB
3078 }
3079
2a38075c
AAL
3080 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
3081 chandef->edmg.channels =
3082 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
3083
3084 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
3085 chandef->edmg.bw_config =
3086 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
3087 } else {
3088 chandef->edmg.bw_config = 0;
3089 chandef->edmg.channels = 0;
3090 }
3091
49f9cf0e
JB
3092 if (!cfg80211_chandef_valid(chandef)) {
3093 NL_SET_ERR_MSG(extack, "invalid channel definition");
3d9d1d66 3094 return -EINVAL;
49f9cf0e 3095 }
3d9d1d66 3096
9f5e8f6e 3097 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
49f9cf0e
JB
3098 IEEE80211_CHAN_DISABLED)) {
3099 NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
3d9d1d66 3100 return -EINVAL;
49f9cf0e 3101 }
3d9d1d66 3102
2f301ab2
SW
3103 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
3104 chandef->width == NL80211_CHAN_WIDTH_10) &&
49f9cf0e
JB
3105 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
3106 NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
2f301ab2 3107 return -EINVAL;
49f9cf0e 3108 }
2f301ab2 3109
683b6d3b
JB
3110 return 0;
3111}
3112
f444de05 3113static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 3114 struct net_device *dev,
f444de05
JB
3115 struct genl_info *info)
3116{
683b6d3b 3117 struct cfg80211_chan_def chandef;
f444de05 3118 int result;
e8c9bd5b 3119 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 3120 struct wireless_dev *wdev = NULL;
e8c9bd5b 3121
e16821bc
JM
3122 if (dev)
3123 wdev = dev->ieee80211_ptr;
f444de05
JB
3124 if (!nl80211_can_set_dev_channel(wdev))
3125 return -EOPNOTSUPP;
e16821bc
JM
3126 if (wdev)
3127 iftype = wdev->iftype;
f444de05 3128
683b6d3b
JB
3129 result = nl80211_parse_chandef(rdev, info, &chandef);
3130 if (result)
3131 return result;
f444de05 3132
e8c9bd5b 3133 switch (iftype) {
aa430da4
JB
3134 case NL80211_IFTYPE_AP:
3135 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
3136 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
3137 iftype)) {
aa430da4
JB
3138 result = -EINVAL;
3139 break;
3140 }
e16821bc
JM
3141 if (wdev->beacon_interval) {
3142 if (!dev || !rdev->ops->set_ap_chanwidth ||
3143 !(rdev->wiphy.features &
3144 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
3145 result = -EBUSY;
3146 break;
3147 }
3148
3149 /* Only allow dynamic channel width changes */
3150 if (chandef.chan != wdev->preset_chandef.chan) {
3151 result = -EBUSY;
3152 break;
3153 }
3154 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
3155 if (result)
3156 break;
3157 }
683b6d3b 3158 wdev->preset_chandef = chandef;
aa430da4
JB
3159 result = 0;
3160 break;
cc1d2806 3161 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 3162 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 3163 break;
e8c9bd5b 3164 case NL80211_IFTYPE_MONITOR:
683b6d3b 3165 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 3166 break;
aa430da4 3167 default:
e8c9bd5b 3168 result = -EINVAL;
f444de05 3169 }
f444de05
JB
3170
3171 return result;
3172}
3173
3174static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
3175{
4c476991
JB
3176 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3177 struct net_device *netdev = info->user_ptr[1];
f444de05 3178
e16821bc 3179 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
3180}
3181
55682965
JB
3182static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
3183{
a05829a7 3184 struct cfg80211_registered_device *rdev = NULL;
f444de05
JB
3185 struct net_device *netdev = NULL;
3186 struct wireless_dev *wdev;
a1e567c8 3187 int result = 0, rem_txq_params = 0;
31888487 3188 struct nlattr *nl_txq_params;
b9a5f8ca
JM
3189 u32 changed;
3190 u8 retry_short = 0, retry_long = 0;
3191 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 3192 u8 coverage_class = 0;
52539ca8 3193 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
55682965 3194
a05829a7 3195 rtnl_lock();
f444de05
JB
3196 /*
3197 * Try to find the wiphy and netdev. Normally this
3198 * function shouldn't need the netdev, but this is
3199 * done for backward compatibility -- previously
3200 * setting the channel was done per wiphy, but now
3201 * it is per netdev. Previous userland like hostapd
3202 * also passed a netdev to set_wiphy, so that it is
3203 * possible to let that go to the right netdev!
3204 */
4bbf4d56 3205
f444de05
JB
3206 if (info->attrs[NL80211_ATTR_IFINDEX]) {
3207 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
3208
7f2b8562 3209 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 3210 if (netdev && netdev->ieee80211_ptr)
f26cbf40 3211 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 3212 else
f444de05 3213 netdev = NULL;
4bbf4d56
JB
3214 }
3215
f444de05 3216 if (!netdev) {
878d9ec7
JB
3217 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
3218 info->attrs);
a05829a7
JB
3219 if (IS_ERR(rdev)) {
3220 rtnl_unlock();
4c476991 3221 return PTR_ERR(rdev);
a05829a7 3222 }
f444de05
JB
3223 wdev = NULL;
3224 netdev = NULL;
3225 result = 0;
71fe96bf 3226 } else
f444de05 3227 wdev = netdev->ieee80211_ptr;
f444de05 3228
a05829a7 3229 wiphy_lock(&rdev->wiphy);
a05829a7 3230
f444de05
JB
3231 /*
3232 * end workaround code, by now the rdev is available
3233 * and locked, and wdev may or may not be NULL.
3234 */
4bbf4d56
JB
3235
3236 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
3237 result = cfg80211_dev_rename(
3238 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
0391a45c 3239 rtnl_unlock();
4bbf4d56 3240
4bbf4d56 3241 if (result)
a05829a7 3242 goto out;
31888487
JM
3243
3244 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
3245 struct ieee80211_txq_params txq_params;
3246 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
3247
a05829a7
JB
3248 if (!rdev->ops->set_txq_params) {
3249 result = -EOPNOTSUPP;
3250 goto out;
3251 }
31888487 3252
a05829a7
JB
3253 if (!netdev) {
3254 result = -EINVAL;
3255 goto out;
3256 }
f70f01c2 3257
133a3ff2 3258 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
a05829a7
JB
3259 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
3260 result = -EINVAL;
3261 goto out;
3262 }
133a3ff2 3263
a05829a7
JB
3264 if (!netif_running(netdev)) {
3265 result = -ENETDOWN;
3266 goto out;
3267 }
2b5f8b0b 3268
31888487
JM
3269 nla_for_each_nested(nl_txq_params,
3270 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
3271 rem_txq_params) {
8cb08174
JB
3272 result = nla_parse_nested_deprecated(tb,
3273 NL80211_TXQ_ATTR_MAX,
3274 nl_txq_params,
3275 txq_params_policy,
3276 info->extack);
ae811e21 3277 if (result)
a05829a7 3278 goto out;
31888487
JM
3279 result = parse_txq_params(tb, &txq_params);
3280 if (result)
a05829a7 3281 goto out;
31888487 3282
e35e4d28
HG
3283 result = rdev_set_txq_params(rdev, netdev,
3284 &txq_params);
31888487 3285 if (result)
a05829a7 3286 goto out;
31888487
JM
3287 }
3288 }
55682965 3289
72bdcf34 3290 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
3291 result = __nl80211_set_channel(
3292 rdev,
3293 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
3294 info);
72bdcf34 3295 if (result)
a05829a7 3296 goto out;
72bdcf34
JM
3297 }
3298
98d2ff8b 3299 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 3300 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
3301 enum nl80211_tx_power_setting type;
3302 int idx, mbm = 0;
3303
c8442118
JB
3304 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
3305 txp_wdev = NULL;
3306
a05829a7
JB
3307 if (!rdev->ops->set_tx_power) {
3308 result = -EOPNOTSUPP;
3309 goto out;
3310 }
98d2ff8b
JO
3311
3312 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
3313 type = nla_get_u32(info->attrs[idx]);
3314
3315 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
a05829a7
JB
3316 (type != NL80211_TX_POWER_AUTOMATIC)) {
3317 result = -EINVAL;
3318 goto out;
3319 }
98d2ff8b
JO
3320
3321 if (type != NL80211_TX_POWER_AUTOMATIC) {
3322 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
3323 mbm = nla_get_u32(info->attrs[idx]);
3324 }
3325
c8442118 3326 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 3327 if (result)
a05829a7 3328 goto out;
98d2ff8b
JO
3329 }
3330
afe0cbf8
BR
3331 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
3332 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
3333 u32 tx_ant, rx_ant;
7a087e74 3334
7f531e03
BR
3335 if ((!rdev->wiphy.available_antennas_tx &&
3336 !rdev->wiphy.available_antennas_rx) ||
a05829a7
JB
3337 !rdev->ops->set_antenna) {
3338 result = -EOPNOTSUPP;
3339 goto out;
3340 }
afe0cbf8
BR
3341
3342 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
3343 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
3344
a7ffac95 3345 /* reject antenna configurations which don't match the
7f531e03
BR
3346 * available antenna masks, except for the "all" mask */
3347 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
a05829a7
JB
3348 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
3349 result = -EINVAL;
3350 goto out;
3351 }
a7ffac95 3352
7f531e03
BR
3353 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
3354 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 3355
e35e4d28 3356 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 3357 if (result)
a05829a7 3358 goto out;
afe0cbf8
BR
3359 }
3360
b9a5f8ca
JM
3361 changed = 0;
3362
3363 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
3364 retry_short = nla_get_u8(
3365 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562 3366
b9a5f8ca
JM
3367 changed |= WIPHY_PARAM_RETRY_SHORT;
3368 }
3369
3370 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
3371 retry_long = nla_get_u8(
3372 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562 3373
b9a5f8ca
JM
3374 changed |= WIPHY_PARAM_RETRY_LONG;
3375 }
3376
3377 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
3378 frag_threshold = nla_get_u32(
3379 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
a05829a7
JB
3380 if (frag_threshold < 256) {
3381 result = -EINVAL;
3382 goto out;
3383 }
7f2b8562 3384
b9a5f8ca
JM
3385 if (frag_threshold != (u32) -1) {
3386 /*
3387 * Fragments (apart from the last one) are required to
3388 * have even length. Make the fragmentation code
3389 * simpler by stripping LSB should someone try to use
3390 * odd threshold value.
3391 */
3392 frag_threshold &= ~0x1;
3393 }
3394 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
3395 }
3396
3397 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
3398 rts_threshold = nla_get_u32(
3399 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
3400 changed |= WIPHY_PARAM_RTS_THRESHOLD;
3401 }
3402
81077e82 3403 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
a05829a7
JB
3404 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
3405 result = -EINVAL;
3406 goto out;
3407 }
3057dbfd 3408
81077e82
LT
3409 coverage_class = nla_get_u8(
3410 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
3411 changed |= WIPHY_PARAM_COVERAGE_CLASS;
3412 }
3413
3057dbfd 3414 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
a05829a7
JB
3415 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION)) {
3416 result = -EOPNOTSUPP;
3417 goto out;
3418 }
3057dbfd
LB
3419
3420 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
3421 }
3422
52539ca8
THJ
3423 if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
3424 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3425 NL80211_EXT_FEATURE_TXQS)) {
3426 result = -EOPNOTSUPP;
3427 goto out;
3428 }
52539ca8
THJ
3429 txq_limit = nla_get_u32(
3430 info->attrs[NL80211_ATTR_TXQ_LIMIT]);
3431 changed |= WIPHY_PARAM_TXQ_LIMIT;
3432 }
3433
3434 if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
3435 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3436 NL80211_EXT_FEATURE_TXQS)) {
3437 result = -EOPNOTSUPP;
3438 goto out;
3439 }
52539ca8
THJ
3440 txq_memory_limit = nla_get_u32(
3441 info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
3442 changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
3443 }
3444
3445 if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
3446 if (!wiphy_ext_feature_isset(&rdev->wiphy,
a05829a7
JB
3447 NL80211_EXT_FEATURE_TXQS)) {
3448 result = -EOPNOTSUPP;
3449 goto out;
3450 }
52539ca8
THJ
3451 txq_quantum = nla_get_u32(
3452 info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
3453 changed |= WIPHY_PARAM_TXQ_QUANTUM;
3454 }
3455
b9a5f8ca
JM
3456 if (changed) {
3457 u8 old_retry_short, old_retry_long;
3458 u32 old_frag_threshold, old_rts_threshold;
81077e82 3459 u8 old_coverage_class;
52539ca8 3460 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
b9a5f8ca 3461
a05829a7
JB
3462 if (!rdev->ops->set_wiphy_params) {
3463 result = -EOPNOTSUPP;
3464 goto out;
3465 }
b9a5f8ca
JM
3466
3467 old_retry_short = rdev->wiphy.retry_short;
3468 old_retry_long = rdev->wiphy.retry_long;
3469 old_frag_threshold = rdev->wiphy.frag_threshold;
3470 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 3471 old_coverage_class = rdev->wiphy.coverage_class;
52539ca8
THJ
3472 old_txq_limit = rdev->wiphy.txq_limit;
3473 old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
3474 old_txq_quantum = rdev->wiphy.txq_quantum;
b9a5f8ca
JM
3475
3476 if (changed & WIPHY_PARAM_RETRY_SHORT)
3477 rdev->wiphy.retry_short = retry_short;
3478 if (changed & WIPHY_PARAM_RETRY_LONG)
3479 rdev->wiphy.retry_long = retry_long;
3480 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
3481 rdev->wiphy.frag_threshold = frag_threshold;
3482 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
3483 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
3484 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
3485 rdev->wiphy.coverage_class = coverage_class;
52539ca8
THJ
3486 if (changed & WIPHY_PARAM_TXQ_LIMIT)
3487 rdev->wiphy.txq_limit = txq_limit;
3488 if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
3489 rdev->wiphy.txq_memory_limit = txq_memory_limit;
3490 if (changed & WIPHY_PARAM_TXQ_QUANTUM)
3491 rdev->wiphy.txq_quantum = txq_quantum;
b9a5f8ca 3492
e35e4d28 3493 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
3494 if (result) {
3495 rdev->wiphy.retry_short = old_retry_short;
3496 rdev->wiphy.retry_long = old_retry_long;
3497 rdev->wiphy.frag_threshold = old_frag_threshold;
3498 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 3499 rdev->wiphy.coverage_class = old_coverage_class;
52539ca8
THJ
3500 rdev->wiphy.txq_limit = old_txq_limit;
3501 rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
3502 rdev->wiphy.txq_quantum = old_txq_quantum;
a05829a7 3503 goto out;
b9a5f8ca
JM
3504 }
3505 }
a05829a7
JB
3506
3507 result = 0;
3508
3509out:
3510 wiphy_unlock(&rdev->wiphy);
3511 return result;
55682965
JB
3512}
3513
683b6d3b 3514static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 3515 const struct cfg80211_chan_def *chandef)
683b6d3b 3516{
601555cd
JB
3517 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
3518 return -EINVAL;
3d9d1d66 3519
683b6d3b
JB
3520 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
3521 chandef->chan->center_freq))
3522 return -ENOBUFS;
942ba88b
TP
3523 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
3524 chandef->chan->freq_offset))
3525 return -ENOBUFS;
3d9d1d66
JB
3526 switch (chandef->width) {
3527 case NL80211_CHAN_WIDTH_20_NOHT:
3528 case NL80211_CHAN_WIDTH_20:
3529 case NL80211_CHAN_WIDTH_40:
3530 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3531 cfg80211_get_chandef_type(chandef)))
3532 return -ENOBUFS;
3533 break;
3534 default:
3535 break;
3536 }
3537 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
3538 return -ENOBUFS;
3539 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
3540 return -ENOBUFS;
3541 if (chandef->center_freq2 &&
3542 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
3543 return -ENOBUFS;
3544 return 0;
3545}
3546
15e47304 3547static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 3548 struct cfg80211_registered_device *rdev,
3d1a5bbf
AZ
3549 struct wireless_dev *wdev,
3550 enum nl80211_commands cmd)
55682965 3551{
72fb2abc 3552 struct net_device *dev = wdev->netdev;
55682965
JB
3553 void *hdr;
3554
3d1a5bbf
AZ
3555 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
3556 cmd != NL80211_CMD_DEL_INTERFACE &&
3557 cmd != NL80211_CMD_SET_INTERFACE);
8f894be2
TB
3558
3559 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
3560 if (!hdr)
3561 return -1;
3562
72fb2abc
JB
3563 if (dev &&
3564 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 3565 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
3566 goto nla_put_failure;
3567
3568 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3569 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
3570 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
3571 NL80211_ATTR_PAD) ||
98104fde 3572 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
3573 nla_put_u32(msg, NL80211_ATTR_GENERATION,
3574 rdev->devlist_generation ^
446faa15
AQ
3575 (cfg80211_rdev_list_generation << 2)) ||
3576 nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
9360ffd1 3577 goto nla_put_failure;
f5ea9120 3578
5b7ccaf3 3579 if (rdev->ops->get_channel) {
683b6d3b 3580 int ret;
f43e5210 3581 struct cfg80211_chan_def chandef = {};
683b6d3b
JB
3582
3583 ret = rdev_get_channel(rdev, wdev, &chandef);
3584 if (ret == 0) {
3585 if (nl80211_send_chandef(msg, &chandef))
3586 goto nla_put_failure;
3587 }
d91df0e3
PF
3588 }
3589
d55d0d59
RM
3590 if (rdev->ops->get_tx_power) {
3591 int dbm, ret;
3592
3593 ret = rdev_get_tx_power(rdev, wdev, &dbm);
3594 if (ret == 0 &&
3595 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
3596 DBM_TO_MBM(dbm)))
3597 goto nla_put_failure;
3598 }
3599
44905265
JB
3600 wdev_lock(wdev);
3601 switch (wdev->iftype) {
3602 case NL80211_IFTYPE_AP:
3603 if (wdev->ssid_len &&
3604 nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
4564b187 3605 goto nla_put_failure_locked;
44905265
JB
3606 break;
3607 case NL80211_IFTYPE_STATION:
3608 case NL80211_IFTYPE_P2P_CLIENT:
3609 case NL80211_IFTYPE_ADHOC: {
3610 const u8 *ssid_ie;
3611 if (!wdev->current_bss)
3612 break;
7a94b8c2 3613 rcu_read_lock();
44905265
JB
3614 ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
3615 WLAN_EID_SSID);
7a94b8c2
DB
3616 if (ssid_ie &&
3617 nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2))
3618 goto nla_put_failure_rcu_locked;
3619 rcu_read_unlock();
44905265
JB
3620 break;
3621 }
3622 default:
3623 /* nothing */
3624 break;
b84e7a05 3625 }
44905265 3626 wdev_unlock(wdev);
b84e7a05 3627
52539ca8
THJ
3628 if (rdev->ops->get_txq_stats) {
3629 struct cfg80211_txq_stats txqstats = {};
3630 int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
3631
3632 if (ret == 0 &&
3633 !nl80211_put_txq_stats(msg, &txqstats,
3634 NL80211_ATTR_TXQ_STATS))
3635 goto nla_put_failure;
3636 }
3637
053c095a
JB
3638 genlmsg_end(msg, hdr);
3639 return 0;
55682965 3640
7a94b8c2
DB
3641 nla_put_failure_rcu_locked:
3642 rcu_read_unlock();
4564b187
JB
3643 nla_put_failure_locked:
3644 wdev_unlock(wdev);
55682965 3645 nla_put_failure:
bc3ed28c
TG
3646 genlmsg_cancel(msg, hdr);
3647 return -EMSGSIZE;
55682965
JB
3648}
3649
3650static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
3651{
3652 int wp_idx = 0;
3653 int if_idx = 0;
3654 int wp_start = cb->args[0];
3655 int if_start = cb->args[1];
b7fb44da 3656 int filter_wiphy = -1;
f5ea9120 3657 struct cfg80211_registered_device *rdev;
55682965 3658 struct wireless_dev *wdev;
ea90e0dc 3659 int ret;
55682965 3660
5fe231e8 3661 rtnl_lock();
b7fb44da
DK
3662 if (!cb->args[2]) {
3663 struct nl80211_dump_wiphy_state state = {
3664 .filter_wiphy = -1,
3665 };
b7fb44da
DK
3666
3667 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
3668 if (ret)
ea90e0dc 3669 goto out_unlock;
b7fb44da
DK
3670
3671 filter_wiphy = state.filter_wiphy;
3672
3673 /*
3674 * if filtering, set cb->args[2] to +1 since 0 is the default
3675 * value needed to determine that parsing is necessary.
3676 */
3677 if (filter_wiphy >= 0)
3678 cb->args[2] = filter_wiphy + 1;
3679 else
3680 cb->args[2] = -1;
3681 } else if (cb->args[2] > 0) {
3682 filter_wiphy = cb->args[2] - 1;
3683 }
3684
f5ea9120
JB
3685 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
3686 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 3687 continue;
bba95fef
JB
3688 if (wp_idx < wp_start) {
3689 wp_idx++;
55682965 3690 continue;
bba95fef 3691 }
b7fb44da
DK
3692
3693 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
3694 continue;
3695
55682965
JB
3696 if_idx = 0;
3697
53873f13 3698 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
3699 if (if_idx < if_start) {
3700 if_idx++;
55682965 3701 continue;
bba95fef 3702 }
15e47304 3703 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 3704 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3d1a5bbf
AZ
3705 rdev, wdev,
3706 NL80211_CMD_NEW_INTERFACE) < 0) {
bba95fef
JB
3707 goto out;
3708 }
3709 if_idx++;
55682965 3710 }
bba95fef
JB
3711
3712 wp_idx++;
55682965 3713 }
bba95fef 3714 out:
55682965
JB
3715 cb->args[0] = wp_idx;
3716 cb->args[1] = if_idx;
3717
ea90e0dc
JB
3718 ret = skb->len;
3719 out_unlock:
3720 rtnl_unlock();
3721
3722 return ret;
55682965
JB
3723}
3724
3725static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
3726{
3727 struct sk_buff *msg;
1b8ec87a 3728 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 3729 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3730
fd2120ca 3731 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 3732 if (!msg)
4c476991 3733 return -ENOMEM;
55682965 3734
15e47304 3735 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 3736 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
4c476991
JB
3737 nlmsg_free(msg);
3738 return -ENOBUFS;
3739 }
55682965 3740
134e6375 3741 return genlmsg_reply(msg, info);
55682965
JB
3742}
3743
66f7ac50
MW
3744static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
3745 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
3746 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
3747 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
3748 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
3749 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 3750 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
3751};
3752
3753static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
3754{
3755 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
3756 int flag;
3757
3758 *mntrflags = 0;
3759
3760 if (!nla)
3761 return -EINVAL;
3762
8cb08174 3763 if (nla_parse_nested_deprecated(flags, NL80211_MNTR_FLAG_MAX, nla, mntr_flags_policy, NULL))
66f7ac50
MW
3764 return -EINVAL;
3765
3766 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
3767 if (flags[flag])
3768 *mntrflags |= (1<<flag);
3769
818a986e
JB
3770 *mntrflags |= MONITOR_FLAG_CHANGED;
3771
66f7ac50
MW
3772 return 0;
3773}
3774
1db77596
JB
3775static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
3776 enum nl80211_iftype type,
3777 struct genl_info *info,
3778 struct vif_params *params)
3779{
3780 bool change = false;
3781 int err;
3782
3783 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
3784 if (type != NL80211_IFTYPE_MONITOR)
3785 return -EINVAL;
3786
3787 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
3788 &params->flags);
3789 if (err)
3790 return err;
3791
3792 change = true;
3793 }
3794
3795 if (params->flags & MONITOR_FLAG_ACTIVE &&
3796 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
3797 return -EOPNOTSUPP;
3798
3799 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
3800 const u8 *mumimo_groups;
3801 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3802
3803 if (type != NL80211_IFTYPE_MONITOR)
3804 return -EINVAL;
3805
3806 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3807 return -EOPNOTSUPP;
3808
3809 mumimo_groups =
3810 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
3811
3812 /* bits 0 and 63 are reserved and must be zero */
4954601f
JB
3813 if ((mumimo_groups[0] & BIT(0)) ||
3814 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
1db77596
JB
3815 return -EINVAL;
3816
3817 params->vht_mumimo_groups = mumimo_groups;
3818 change = true;
3819 }
3820
3821 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
3822 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3823
3824 if (type != NL80211_IFTYPE_MONITOR)
3825 return -EINVAL;
3826
3827 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3828 return -EOPNOTSUPP;
3829
3830 params->vht_mumimo_follow_addr =
3831 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
3832 change = true;
3833 }
3834
3835 return change ? 1 : 0;
3836}
3837
9bc383de 3838static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
3839 struct net_device *netdev, u8 use_4addr,
3840 enum nl80211_iftype iftype)
9bc383de 3841{
ad4bb6f8 3842 if (!use_4addr) {
2e92a2d0 3843 if (netdev && netif_is_bridge_port(netdev))
ad4bb6f8 3844 return -EBUSY;
9bc383de 3845 return 0;
ad4bb6f8 3846 }
9bc383de
JB
3847
3848 switch (iftype) {
3849 case NL80211_IFTYPE_AP_VLAN:
3850 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
3851 return 0;
3852 break;
3853 case NL80211_IFTYPE_STATION:
3854 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
3855 return 0;
3856 break;
3857 default:
3858 break;
3859 }
3860
3861 return -EOPNOTSUPP;
3862}
3863
55682965
JB
3864static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3865{
4c476991 3866 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3867 struct vif_params params;
e36d56b6 3868 int err;
04a773ad 3869 enum nl80211_iftype otype, ntype;
4c476991 3870 struct net_device *dev = info->user_ptr[1];
ac7f9cfa 3871 bool change = false;
55682965 3872
2ec600d6
LCC
3873 memset(&params, 0, sizeof(params));
3874
04a773ad 3875 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 3876
723b038d 3877 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 3878 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 3879 if (otype != ntype)
ac7f9cfa 3880 change = true;
723b038d
JB
3881 }
3882
92ffe055 3883 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
3884 struct wireless_dev *wdev = dev->ieee80211_ptr;
3885
4c476991
JB
3886 if (ntype != NL80211_IFTYPE_MESH_POINT)
3887 return -EINVAL;
29cbe68c
JB
3888 if (netif_running(dev))
3889 return -EBUSY;
3890
3891 wdev_lock(wdev);
3892 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3893 IEEE80211_MAX_MESH_ID_LEN);
3894 wdev->mesh_id_up_len =
3895 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3896 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3897 wdev->mesh_id_up_len);
3898 wdev_unlock(wdev);
2ec600d6
LCC
3899 }
3900
8b787643
FF
3901 if (info->attrs[NL80211_ATTR_4ADDR]) {
3902 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
3903 change = true;
ad4bb6f8 3904 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 3905 if (err)
4c476991 3906 return err;
8b787643
FF
3907 } else {
3908 params.use_4addr = -1;
3909 }
3910
1db77596
JB
3911 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
3912 if (err < 0)
3913 return err;
3914 if (err > 0)
c6e6a0c8 3915 change = true;
e057d3c3 3916
ac7f9cfa 3917 if (change)
818a986e 3918 err = cfg80211_change_iface(rdev, dev, ntype, &params);
ac7f9cfa
JB
3919 else
3920 err = 0;
60719ffd 3921
9bc383de
JB
3922 if (!err && params.use_4addr != -1)
3923 dev->ieee80211_ptr->use_4addr = params.use_4addr;
3924
3d1a5bbf
AZ
3925 if (change && !err) {
3926 struct wireless_dev *wdev = dev->ieee80211_ptr;
3927
3928 nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
3929 }
3930
55682965
JB
3931 return err;
3932}
3933
ea6b2098 3934static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
55682965 3935{
4c476991 3936 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3937 struct vif_params params;
84efbb84 3938 struct wireless_dev *wdev;
896ff063 3939 struct sk_buff *msg;
55682965
JB
3940 int err;
3941 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
3942
2ec600d6
LCC
3943 memset(&params, 0, sizeof(params));
3944
55682965
JB
3945 if (!info->attrs[NL80211_ATTR_IFNAME])
3946 return -EINVAL;
3947
ab0d76f6 3948 if (info->attrs[NL80211_ATTR_IFTYPE])
55682965 3949 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
55682965 3950
33d915d9 3951 if (!rdev->ops->add_virtual_intf)
4c476991 3952 return -EOPNOTSUPP;
55682965 3953
cb3b7d87 3954 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
3955 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
3956 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
3957 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
3958 ETH_ALEN);
3959 if (!is_valid_ether_addr(params.macaddr))
3960 return -EADDRNOTAVAIL;
3961 }
3962
9bc383de 3963 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 3964 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 3965 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 3966 if (err)
4c476991 3967 return err;
9bc383de 3968 }
8b787643 3969
e6f40511 3970 if (!cfg80211_iftype_allowed(&rdev->wiphy, type, params.use_4addr, 0))
33d915d9
MP
3971 return -EOPNOTSUPP;
3972
1db77596
JB
3973 err = nl80211_parse_mon_options(rdev, type, info, &params);
3974 if (err < 0)
3975 return err;
e057d3c3 3976
a18c7192
JB
3977 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3978 if (!msg)
3979 return -ENOMEM;
3980
e35e4d28
HG
3981 wdev = rdev_add_virtual_intf(rdev,
3982 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
818a986e 3983 NET_NAME_USER, type, &params);
d687cbb7
RM
3984 if (WARN_ON(!wdev)) {
3985 nlmsg_free(msg);
3986 return -EPROTO;
3987 } else if (IS_ERR(wdev)) {
1c90f9d4 3988 nlmsg_free(msg);
84efbb84 3989 return PTR_ERR(wdev);
1c90f9d4 3990 }
2ec600d6 3991
18e5ca65 3992 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
3993 wdev->owner_nlportid = info->snd_portid;
3994
98104fde
JB
3995 switch (type) {
3996 case NL80211_IFTYPE_MESH_POINT:
3997 if (!info->attrs[NL80211_ATTR_MESH_ID])
3998 break;
29cbe68c
JB
3999 wdev_lock(wdev);
4000 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
4001 IEEE80211_MAX_MESH_ID_LEN);
4002 wdev->mesh_id_up_len =
4003 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4004 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
4005 wdev->mesh_id_up_len);
4006 wdev_unlock(wdev);
98104fde 4007 break;
cb3b7d87 4008 case NL80211_IFTYPE_NAN:
98104fde
JB
4009 case NL80211_IFTYPE_P2P_DEVICE:
4010 /*
cb3b7d87 4011 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
4012 * through the netdev notifier and must be added here
4013 */
9bdaf3b9
JB
4014 cfg80211_init_wdev(wdev);
4015 cfg80211_register_wdev(rdev, wdev);
98104fde
JB
4016 break;
4017 default:
4018 break;
29cbe68c
JB
4019 }
4020
15e47304 4021 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 4022 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
1c90f9d4
JB
4023 nlmsg_free(msg);
4024 return -ENOBUFS;
4025 }
4026
4027 return genlmsg_reply(msg, info);
55682965
JB
4028}
4029
ea6b2098
JB
4030static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
4031{
4032 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4033 int ret;
4034
4035 /* to avoid failing a new interface creation due to pending removal */
4036 cfg80211_destroy_ifaces(rdev);
4037
4038 wiphy_lock(&rdev->wiphy);
4039 ret = _nl80211_new_interface(skb, info);
4040 wiphy_unlock(&rdev->wiphy);
4041
4042 return ret;
4043}
4044
55682965
JB
4045static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
4046{
4c476991 4047 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 4048 struct wireless_dev *wdev = info->user_ptr[1];
55682965 4049
4c476991
JB
4050 if (!rdev->ops->del_virtual_intf)
4051 return -EOPNOTSUPP;
55682965 4052
a05829a7
JB
4053 /*
4054 * We hold RTNL, so this is safe, without RTNL opencount cannot
4055 * reach 0, and thus the rdev cannot be deleted.
4056 *
4057 * We need to do it for the dev_close(), since that will call
4058 * the netdev notifiers, and we need to acquire the mutex there
4059 * but don't know if we get there from here or from some other
4060 * place (e.g. "ip link set ... down").
4061 */
4062 mutex_unlock(&rdev->wiphy.mtx);
4063
84efbb84
JB
4064 /*
4065 * If we remove a wireless device without a netdev then clear
4066 * user_ptr[1] so that nl80211_post_doit won't dereference it
4067 * to check if it needs to do dev_put(). Otherwise it crashes
4068 * since the wdev has been freed, unlike with a netdev where
4069 * we need the dev_put() for the netdev to really be freed.
4070 */
4071 if (!wdev->netdev)
4072 info->user_ptr[1] = NULL;
a05829a7
JB
4073 else
4074 dev_close(wdev->netdev);
4075
4076 mutex_lock(&rdev->wiphy.mtx);
84efbb84 4077
7f8ed01e 4078 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
4079}
4080
1d9d9213
SW
4081static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
4082{
4083 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4084 struct net_device *dev = info->user_ptr[1];
4085 u16 noack_map;
4086
4087 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
4088 return -EINVAL;
4089
4090 if (!rdev->ops->set_noack_map)
4091 return -EOPNOTSUPP;
4092
4093 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
4094
e35e4d28 4095 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
4096}
4097
41ade00f
JB
4098struct get_key_cookie {
4099 struct sk_buff *msg;
4100 int error;
b9454e83 4101 int idx;
41ade00f
JB
4102};
4103
4104static void get_key_callback(void *c, struct key_params *params)
4105{
b9454e83 4106 struct nlattr *key;
41ade00f
JB
4107 struct get_key_cookie *cookie = c;
4108
9360ffd1
DM
4109 if ((params->key &&
4110 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
4111 params->key_len, params->key)) ||
4112 (params->seq &&
4113 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
4114 params->seq_len, params->seq)) ||
4115 (params->cipher &&
4116 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
4117 params->cipher)))
4118 goto nla_put_failure;
41ade00f 4119
ae0be8de 4120 key = nla_nest_start_noflag(cookie->msg, NL80211_ATTR_KEY);
b9454e83
JB
4121 if (!key)
4122 goto nla_put_failure;
4123
9360ffd1
DM
4124 if ((params->key &&
4125 nla_put(cookie->msg, NL80211_KEY_DATA,
4126 params->key_len, params->key)) ||
4127 (params->seq &&
4128 nla_put(cookie->msg, NL80211_KEY_SEQ,
4129 params->seq_len, params->seq)) ||
4130 (params->cipher &&
4131 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
4132 params->cipher)))
4133 goto nla_put_failure;
b9454e83 4134
efdfce72 4135 if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
9360ffd1 4136 goto nla_put_failure;
b9454e83
JB
4137
4138 nla_nest_end(cookie->msg, key);
4139
41ade00f
JB
4140 return;
4141 nla_put_failure:
4142 cookie->error = 1;
4143}
4144
4145static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
4146{
4c476991 4147 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 4148 int err;
4c476991 4149 struct net_device *dev = info->user_ptr[1];
41ade00f 4150 u8 key_idx = 0;
e31b8213
JB
4151 const u8 *mac_addr = NULL;
4152 bool pairwise;
41ade00f
JB
4153 struct get_key_cookie cookie = {
4154 .error = 0,
4155 };
4156 void *hdr;
4157 struct sk_buff *msg;
155d7c73
JB
4158 bool bigtk_support = false;
4159
4160 if (wiphy_ext_feature_isset(&rdev->wiphy,
4161 NL80211_EXT_FEATURE_BEACON_PROTECTION))
4162 bigtk_support = true;
4163
4164 if ((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_STATION ||
4165 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
4166 wiphy_ext_feature_isset(&rdev->wiphy,
4167 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
4168 bigtk_support = true;
41ade00f 4169
56be393f 4170 if (info->attrs[NL80211_ATTR_KEY_IDX]) {
41ade00f 4171 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
155d7c73
JB
4172
4173 if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) {
4174 GENL_SET_ERR_MSG(info, "BIGTK not supported");
56be393f 4175 return -EINVAL;
155d7c73 4176 }
56be393f 4177 }
41ade00f 4178
41ade00f
JB
4179 if (info->attrs[NL80211_ATTR_MAC])
4180 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4181
e31b8213
JB
4182 pairwise = !!mac_addr;
4183 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
4184 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 4185
e31b8213
JB
4186 if (kt != NL80211_KEYTYPE_GROUP &&
4187 kt != NL80211_KEYTYPE_PAIRWISE)
4188 return -EINVAL;
4189 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
4190 }
4191
4c476991
JB
4192 if (!rdev->ops->get_key)
4193 return -EOPNOTSUPP;
41ade00f 4194
0fa7b391
JB
4195 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4196 return -ENOENT;
4197
fd2120ca 4198 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
4199 if (!msg)
4200 return -ENOMEM;
41ade00f 4201
15e47304 4202 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 4203 NL80211_CMD_NEW_KEY);
cb35fba3 4204 if (!hdr)
9fe271af 4205 goto nla_put_failure;
41ade00f
JB
4206
4207 cookie.msg = msg;
b9454e83 4208 cookie.idx = key_idx;
41ade00f 4209
9360ffd1
DM
4210 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4211 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
4212 goto nla_put_failure;
4213 if (mac_addr &&
4214 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
4215 goto nla_put_failure;
41ade00f 4216
e35e4d28
HG
4217 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
4218 get_key_callback);
41ade00f
JB
4219
4220 if (err)
6c95e2a2 4221 goto free_msg;
41ade00f
JB
4222
4223 if (cookie.error)
4224 goto nla_put_failure;
4225
4226 genlmsg_end(msg, hdr);
4c476991 4227 return genlmsg_reply(msg, info);
41ade00f
JB
4228
4229 nla_put_failure:
4230 err = -ENOBUFS;
6c95e2a2 4231 free_msg:
41ade00f 4232 nlmsg_free(msg);
41ade00f
JB
4233 return err;
4234}
4235
4236static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
4237{
4c476991 4238 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 4239 struct key_parse key;
41ade00f 4240 int err;
4c476991 4241 struct net_device *dev = info->user_ptr[1];
41ade00f 4242
b9454e83
JB
4243 err = nl80211_parse_key(info, &key);
4244 if (err)
4245 return err;
41ade00f 4246
b9454e83 4247 if (key.idx < 0)
41ade00f
JB
4248 return -EINVAL;
4249
6cdd3979
AW
4250 /* Only support setting default key and
4251 * Extended Key ID action NL80211_KEY_SET_TX.
4252 */
56be393f 4253 if (!key.def && !key.defmgmt && !key.defbeacon &&
6cdd3979 4254 !(key.p.mode == NL80211_KEY_SET_TX))
41ade00f
JB
4255 return -EINVAL;
4256
dbd2fd65 4257 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 4258
dbd2fd65
JB
4259 if (key.def) {
4260 if (!rdev->ops->set_default_key) {
4261 err = -EOPNOTSUPP;
4262 goto out;
4263 }
41ade00f 4264
dbd2fd65
JB
4265 err = nl80211_key_allowed(dev->ieee80211_ptr);
4266 if (err)
4267 goto out;
4268
e35e4d28 4269 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
4270 key.def_uni, key.def_multi);
4271
4272 if (err)
4273 goto out;
fffd0934 4274
3d23e349 4275#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
4276 dev->ieee80211_ptr->wext.default_key = key.idx;
4277#endif
6cdd3979 4278 } else if (key.defmgmt) {
dbd2fd65
JB
4279 if (key.def_uni || !key.def_multi) {
4280 err = -EINVAL;
4281 goto out;
4282 }
4283
4284 if (!rdev->ops->set_default_mgmt_key) {
4285 err = -EOPNOTSUPP;
4286 goto out;
4287 }
4288
4289 err = nl80211_key_allowed(dev->ieee80211_ptr);
4290 if (err)
4291 goto out;
4292
e35e4d28 4293 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
4294 if (err)
4295 goto out;
4296
4297#ifdef CONFIG_CFG80211_WEXT
4298 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 4299#endif
56be393f
JM
4300 } else if (key.defbeacon) {
4301 if (key.def_uni || !key.def_multi) {
4302 err = -EINVAL;
4303 goto out;
4304 }
4305
4306 if (!rdev->ops->set_default_beacon_key) {
4307 err = -EOPNOTSUPP;
4308 goto out;
4309 }
4310
4311 err = nl80211_key_allowed(dev->ieee80211_ptr);
4312 if (err)
4313 goto out;
4314
4315 err = rdev_set_default_beacon_key(rdev, dev, key.idx);
4316 if (err)
4317 goto out;
6cdd3979
AW
4318 } else if (key.p.mode == NL80211_KEY_SET_TX &&
4319 wiphy_ext_feature_isset(&rdev->wiphy,
4320 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
4321 u8 *mac_addr = NULL;
4322
4323 if (info->attrs[NL80211_ATTR_MAC])
4324 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4325
4326 if (!mac_addr || key.idx < 0 || key.idx > 1) {
4327 err = -EINVAL;
4328 goto out;
4329 }
dbd2fd65 4330
6cdd3979
AW
4331 err = rdev_add_key(rdev, dev, key.idx,
4332 NL80211_KEYTYPE_PAIRWISE,
4333 mac_addr, &key.p);
4334 } else {
4335 err = -EINVAL;
4336 }
dbd2fd65 4337 out:
fffd0934 4338 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4339
41ade00f
JB
4340 return err;
4341}
4342
4343static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
4344{
4c476991 4345 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 4346 int err;
4c476991 4347 struct net_device *dev = info->user_ptr[1];
b9454e83 4348 struct key_parse key;
e31b8213 4349 const u8 *mac_addr = NULL;
41ade00f 4350
b9454e83
JB
4351 err = nl80211_parse_key(info, &key);
4352 if (err)
4353 return err;
41ade00f 4354
f8af764b
JM
4355 if (!key.p.key) {
4356 GENL_SET_ERR_MSG(info, "no key");
41ade00f 4357 return -EINVAL;
f8af764b 4358 }
41ade00f 4359
41ade00f
JB
4360 if (info->attrs[NL80211_ATTR_MAC])
4361 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4362
e31b8213
JB
4363 if (key.type == -1) {
4364 if (mac_addr)
4365 key.type = NL80211_KEYTYPE_PAIRWISE;
4366 else
4367 key.type = NL80211_KEYTYPE_GROUP;
4368 }
4369
4370 /* for now */
4371 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
f8af764b
JM
4372 key.type != NL80211_KEYTYPE_GROUP) {
4373 GENL_SET_ERR_MSG(info, "key type not pairwise or group");
e31b8213 4374 return -EINVAL;
f8af764b 4375 }
e31b8213 4376
14f34e36
GG
4377 if (key.type == NL80211_KEYTYPE_GROUP &&
4378 info->attrs[NL80211_ATTR_VLAN_ID])
4379 key.p.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
4380
4c476991
JB
4381 if (!rdev->ops->add_key)
4382 return -EOPNOTSUPP;
25e47c18 4383
e31b8213
JB
4384 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
4385 key.type == NL80211_KEYTYPE_PAIRWISE,
f8af764b
JM
4386 mac_addr)) {
4387 GENL_SET_ERR_MSG(info, "key setting validation failed");
4c476991 4388 return -EINVAL;
f8af764b 4389 }
41ade00f 4390
fffd0934
JB
4391 wdev_lock(dev->ieee80211_ptr);
4392 err = nl80211_key_allowed(dev->ieee80211_ptr);
f8af764b
JM
4393 if (err)
4394 GENL_SET_ERR_MSG(info, "key not allowed");
4395 if (!err) {
e35e4d28
HG
4396 err = rdev_add_key(rdev, dev, key.idx,
4397 key.type == NL80211_KEYTYPE_PAIRWISE,
4398 mac_addr, &key.p);
f8af764b
JM
4399 if (err)
4400 GENL_SET_ERR_MSG(info, "key addition failed");
4401 }
fffd0934 4402 wdev_unlock(dev->ieee80211_ptr);
41ade00f 4403
41ade00f
JB
4404 return err;
4405}
4406
4407static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
4408{
4c476991 4409 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 4410 int err;
4c476991 4411 struct net_device *dev = info->user_ptr[1];
41ade00f 4412 u8 *mac_addr = NULL;
b9454e83 4413 struct key_parse key;
41ade00f 4414
b9454e83
JB
4415 err = nl80211_parse_key(info, &key);
4416 if (err)
4417 return err;
41ade00f
JB
4418
4419 if (info->attrs[NL80211_ATTR_MAC])
4420 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4421
e31b8213
JB
4422 if (key.type == -1) {
4423 if (mac_addr)
4424 key.type = NL80211_KEYTYPE_PAIRWISE;
4425 else
4426 key.type = NL80211_KEYTYPE_GROUP;
4427 }
4428
4429 /* for now */
4430 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
4431 key.type != NL80211_KEYTYPE_GROUP)
4432 return -EINVAL;
4433
2d946308
AT
4434 if (!cfg80211_valid_key_idx(rdev, key.idx,
4435 key.type == NL80211_KEYTYPE_PAIRWISE))
4436 return -EINVAL;
4437
4c476991
JB
4438 if (!rdev->ops->del_key)
4439 return -EOPNOTSUPP;
41ade00f 4440
fffd0934
JB
4441 wdev_lock(dev->ieee80211_ptr);
4442 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 4443
0fa7b391 4444 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
4445 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4446 err = -ENOENT;
4447
fffd0934 4448 if (!err)
e35e4d28
HG
4449 err = rdev_del_key(rdev, dev, key.idx,
4450 key.type == NL80211_KEYTYPE_PAIRWISE,
4451 mac_addr);
41ade00f 4452
3d23e349 4453#ifdef CONFIG_CFG80211_WEXT
08645126 4454 if (!err) {
b9454e83 4455 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 4456 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 4457 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
4458 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
4459 }
4460#endif
fffd0934 4461 wdev_unlock(dev->ieee80211_ptr);
08645126 4462
41ade00f
JB
4463 return err;
4464}
4465
77765eaf
VT
4466/* This function returns an error or the number of nested attributes */
4467static int validate_acl_mac_addrs(struct nlattr *nl_attr)
4468{
4469 struct nlattr *attr;
4470 int n_entries = 0, tmp;
4471
4472 nla_for_each_nested(attr, nl_attr, tmp) {
4473 if (nla_len(attr) != ETH_ALEN)
4474 return -EINVAL;
4475
4476 n_entries++;
4477 }
4478
4479 return n_entries;
4480}
4481
4482/*
4483 * This function parses ACL information and allocates memory for ACL data.
4484 * On successful return, the calling function is responsible to free the
4485 * ACL buffer returned by this function.
4486 */
4487static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
4488 struct genl_info *info)
4489{
4490 enum nl80211_acl_policy acl_policy;
4491 struct nlattr *attr;
4492 struct cfg80211_acl_data *acl;
4493 int i = 0, n_entries, tmp;
4494
4495 if (!wiphy->max_acl_mac_addrs)
4496 return ERR_PTR(-EOPNOTSUPP);
4497
4498 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
4499 return ERR_PTR(-EINVAL);
4500
4501 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
4502 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
4503 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
4504 return ERR_PTR(-EINVAL);
4505
4506 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
4507 return ERR_PTR(-EINVAL);
4508
4509 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
4510 if (n_entries < 0)
4511 return ERR_PTR(n_entries);
4512
4513 if (n_entries > wiphy->max_acl_mac_addrs)
4514 return ERR_PTR(-ENOTSUPP);
4515
391d132c 4516 acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
77765eaf
VT
4517 if (!acl)
4518 return ERR_PTR(-ENOMEM);
4519
4520 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
4521 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
4522 i++;
4523 }
4524
4525 acl->n_acl_entries = n_entries;
4526 acl->acl_policy = acl_policy;
4527
4528 return acl;
4529}
4530
4531static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
4532{
4533 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4534 struct net_device *dev = info->user_ptr[1];
4535 struct cfg80211_acl_data *acl;
4536 int err;
4537
4538 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4539 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4540 return -EOPNOTSUPP;
4541
4542 if (!dev->ieee80211_ptr->beacon_interval)
4543 return -EINVAL;
4544
4545 acl = parse_acl_data(&rdev->wiphy, info);
4546 if (IS_ERR(acl))
4547 return PTR_ERR(acl);
4548
4549 err = rdev_set_mac_acl(rdev, dev, acl);
4550
4551 kfree(acl);
4552
4553 return err;
4554}
4555
a7c7fbff
PK
4556static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
4557 u8 *rates, u8 rates_len)
4558{
4559 u8 i;
4560 u32 mask = 0;
4561
4562 for (i = 0; i < rates_len; i++) {
4563 int rate = (rates[i] & 0x7f) * 5;
4564 int ridx;
4565
4566 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
4567 struct ieee80211_rate *srate =
4568 &sband->bitrates[ridx];
4569 if (rate == srate->bitrate) {
4570 mask |= 1 << ridx;
4571 break;
4572 }
4573 }
4574 if (ridx == sband->n_bitrates)
4575 return 0; /* rate not found */
4576 }
4577
4578 return mask;
4579}
4580
4581static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
4582 u8 *rates, u8 rates_len,
4583 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
4584{
4585 u8 i;
4586
4587 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
4588
4589 for (i = 0; i < rates_len; i++) {
4590 int ridx, rbit;
4591
4592 ridx = rates[i] / 8;
4593 rbit = BIT(rates[i] % 8);
4594
4595 /* check validity */
4596 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
4597 return false;
4598
4599 /* check availability */
30fe6d50 4600 ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
a7c7fbff
PK
4601 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
4602 mcs[ridx] |= rbit;
4603 else
4604 return false;
4605 }
4606
4607 return true;
4608}
4609
4610static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
4611{
4612 u16 mcs_mask = 0;
4613
4614 switch (vht_mcs_map) {
4615 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
4616 break;
4617 case IEEE80211_VHT_MCS_SUPPORT_0_7:
4618 mcs_mask = 0x00FF;
4619 break;
4620 case IEEE80211_VHT_MCS_SUPPORT_0_8:
4621 mcs_mask = 0x01FF;
4622 break;
4623 case IEEE80211_VHT_MCS_SUPPORT_0_9:
4624 mcs_mask = 0x03FF;
4625 break;
4626 default:
4627 break;
4628 }
4629
4630 return mcs_mask;
4631}
4632
4633static void vht_build_mcs_mask(u16 vht_mcs_map,
4634 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
4635{
4636 u8 nss;
4637
4638 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
4639 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
4640 vht_mcs_map >>= 2;
4641 }
4642}
4643
4644static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
4645 struct nl80211_txrate_vht *txrate,
4646 u16 mcs[NL80211_VHT_NSS_MAX])
4647{
4648 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4649 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
4650 u8 i;
4651
4652 if (!sband->vht_cap.vht_supported)
4653 return false;
4654
4655 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
4656
4657 /* Build vht_mcs_mask from VHT capabilities */
4658 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4659
4660 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
4661 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4662 mcs[i] = txrate->mcs[i];
4663 else
4664 return false;
4665 }
4666
4667 return true;
4668}
4669
eb89a6a6
MH
4670static u16 he_mcs_map_to_mcs_mask(u8 he_mcs_map)
4671{
4672 switch (he_mcs_map) {
4673 case IEEE80211_HE_MCS_NOT_SUPPORTED:
4674 return 0;
4675 case IEEE80211_HE_MCS_SUPPORT_0_7:
4676 return 0x00FF;
4677 case IEEE80211_HE_MCS_SUPPORT_0_9:
4678 return 0x03FF;
4679 case IEEE80211_HE_MCS_SUPPORT_0_11:
4680 return 0xFFF;
4681 default:
4682 break;
4683 }
4684 return 0;
4685}
4686
4687static void he_build_mcs_mask(u16 he_mcs_map,
4688 u16 he_mcs_mask[NL80211_HE_NSS_MAX])
4689{
4690 u8 nss;
4691
4692 for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
4693 he_mcs_mask[nss] = he_mcs_map_to_mcs_mask(he_mcs_map & 0x03);
4694 he_mcs_map >>= 2;
4695 }
4696}
4697
4698static u16 he_get_txmcsmap(struct genl_info *info,
4699 const struct ieee80211_sta_he_cap *he_cap)
4700{
4701 struct net_device *dev = info->user_ptr[1];
4702 struct wireless_dev *wdev = dev->ieee80211_ptr;
4703 __le16 tx_mcs;
4704
4705 switch (wdev->chandef.width) {
4706 case NL80211_CHAN_WIDTH_80P80:
4707 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80p80;
4708 break;
4709 case NL80211_CHAN_WIDTH_160:
4710 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_160;
4711 break;
4712 default:
4713 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80;
4714 break;
4715 }
4716 return le16_to_cpu(tx_mcs);
4717}
4718
4719static bool he_set_mcs_mask(struct genl_info *info,
4720 struct wireless_dev *wdev,
4721 struct ieee80211_supported_band *sband,
4722 struct nl80211_txrate_he *txrate,
4723 u16 mcs[NL80211_HE_NSS_MAX])
4724{
4725 const struct ieee80211_sta_he_cap *he_cap;
4726 u16 tx_mcs_mask[NL80211_HE_NSS_MAX] = {};
4727 u16 tx_mcs_map = 0;
4728 u8 i;
4729
4730 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
4731 if (!he_cap)
4732 return false;
4733
4734 memset(mcs, 0, sizeof(u16) * NL80211_HE_NSS_MAX);
4735
4736 tx_mcs_map = he_get_txmcsmap(info, he_cap);
4737
4738 /* Build he_mcs_mask from HE capabilities */
4739 he_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4740
4741 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
4742 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4743 mcs[i] = txrate->mcs[i];
4744 else
4745 return false;
4746 }
4747
4748 return true;
4749}
4750
a7c7fbff 4751static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
9a5f6488
TC
4752 struct nlattr *attrs[],
4753 enum nl80211_attrs attr,
eb89a6a6 4754 struct cfg80211_bitrate_mask *mask,
857b34c4
RM
4755 struct net_device *dev,
4756 bool default_all_enabled)
a7c7fbff
PK
4757{
4758 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4759 struct cfg80211_registered_device *rdev = info->user_ptr[0];
eb89a6a6 4760 struct wireless_dev *wdev = dev->ieee80211_ptr;
a7c7fbff
PK
4761 int rem, i;
4762 struct nlattr *tx_rates;
4763 struct ieee80211_supported_band *sband;
eb89a6a6 4764 u16 vht_tx_mcs_map, he_tx_mcs_map;
a7c7fbff
PK
4765
4766 memset(mask, 0, sizeof(*mask));
4767 /* Default to all rates enabled */
4768 for (i = 0; i < NUM_NL80211_BANDS; i++) {
eb89a6a6
MH
4769 const struct ieee80211_sta_he_cap *he_cap;
4770
857b34c4
RM
4771 if (!default_all_enabled)
4772 break;
4773
a7c7fbff
PK
4774 sband = rdev->wiphy.bands[i];
4775
4776 if (!sband)
4777 continue;
4778
4779 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
4780 memcpy(mask->control[i].ht_mcs,
4781 sband->ht_cap.mcs.rx_mask,
4782 sizeof(mask->control[i].ht_mcs));
4783
9df66d5b
PKS
4784 if (sband->vht_cap.vht_supported) {
4785 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4786 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
4787 }
eb89a6a6
MH
4788
4789 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
4790 if (!he_cap)
4791 continue;
4792
4793 he_tx_mcs_map = he_get_txmcsmap(info, he_cap);
4794 he_build_mcs_mask(he_tx_mcs_map, mask->control[i].he_mcs);
4795
4796 mask->control[i].he_gi = 0xFF;
4797 mask->control[i].he_ltf = 0xFF;
a7c7fbff
PK
4798 }
4799
4800 /* if no rates are given set it back to the defaults */
9a5f6488 4801 if (!attrs[attr])
a7c7fbff
PK
4802 goto out;
4803
4804 /* The nested attribute uses enum nl80211_band as the index. This maps
4805 * directly to the enum nl80211_band values used in cfg80211.
4806 */
4807 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
9a5f6488 4808 nla_for_each_nested(tx_rates, attrs[attr], rem) {
a7c7fbff
PK
4809 enum nl80211_band band = nla_type(tx_rates);
4810 int err;
4811
4812 if (band < 0 || band >= NUM_NL80211_BANDS)
4813 return -EINVAL;
4814 sband = rdev->wiphy.bands[band];
4815 if (sband == NULL)
4816 return -EINVAL;
8cb08174
JB
4817 err = nla_parse_nested_deprecated(tb, NL80211_TXRATE_MAX,
4818 tx_rates,
4819 nl80211_txattr_policy,
4820 info->extack);
a7c7fbff
PK
4821 if (err)
4822 return err;
4823 if (tb[NL80211_TXRATE_LEGACY]) {
4824 mask->control[band].legacy = rateset_to_mask(
4825 sband,
4826 nla_data(tb[NL80211_TXRATE_LEGACY]),
4827 nla_len(tb[NL80211_TXRATE_LEGACY]));
4828 if ((mask->control[band].legacy == 0) &&
4829 nla_len(tb[NL80211_TXRATE_LEGACY]))
4830 return -EINVAL;
4831 }
4832 if (tb[NL80211_TXRATE_HT]) {
4833 if (!ht_rateset_to_mask(
4834 sband,
4835 nla_data(tb[NL80211_TXRATE_HT]),
4836 nla_len(tb[NL80211_TXRATE_HT]),
4837 mask->control[band].ht_mcs))
4838 return -EINVAL;
4839 }
c4a30446 4840
a7c7fbff
PK
4841 if (tb[NL80211_TXRATE_VHT]) {
4842 if (!vht_set_mcs_mask(
4843 sband,
4844 nla_data(tb[NL80211_TXRATE_VHT]),
4845 mask->control[band].vht_mcs))
4846 return -EINVAL;
4847 }
c4a30446 4848
a7c7fbff
PK
4849 if (tb[NL80211_TXRATE_GI]) {
4850 mask->control[band].gi =
4851 nla_get_u8(tb[NL80211_TXRATE_GI]);
4852 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
4853 return -EINVAL;
4854 }
eb89a6a6
MH
4855 if (tb[NL80211_TXRATE_HE] &&
4856 !he_set_mcs_mask(info, wdev, sband,
4857 nla_data(tb[NL80211_TXRATE_HE]),
4858 mask->control[band].he_mcs))
4859 return -EINVAL;
c4a30446 4860
eb89a6a6
MH
4861 if (tb[NL80211_TXRATE_HE_GI])
4862 mask->control[band].he_gi =
4863 nla_get_u8(tb[NL80211_TXRATE_HE_GI]);
4864 if (tb[NL80211_TXRATE_HE_LTF])
4865 mask->control[band].he_ltf =
4866 nla_get_u8(tb[NL80211_TXRATE_HE_LTF]);
a7c7fbff
PK
4867
4868 if (mask->control[band].legacy == 0) {
eb89a6a6 4869 /* don't allow empty legacy rates if HT, VHT or HE
a7c7fbff
PK
4870 * are not even supported.
4871 */
4872 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
eb89a6a6
MH
4873 rdev->wiphy.bands[band]->vht_cap.vht_supported ||
4874 ieee80211_get_he_iftype_cap(sband, wdev->iftype)))
a7c7fbff
PK
4875 return -EINVAL;
4876
4877 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
4878 if (mask->control[band].ht_mcs[i])
4879 goto out;
4880
4881 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
4882 if (mask->control[band].vht_mcs[i])
4883 goto out;
4884
eb89a6a6
MH
4885 for (i = 0; i < NL80211_HE_NSS_MAX; i++)
4886 if (mask->control[band].he_mcs[i])
4887 goto out;
4888
a7c7fbff
PK
4889 /* legacy and mcs rates may not be both empty */
4890 return -EINVAL;
4891 }
4892 }
4893
4894out:
4895 return 0;
4896}
4897
8564e382
JB
4898static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
4899 enum nl80211_band band,
4900 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 4901{
c4a30446 4902 u32 count_ht, count_vht, count_he, i;
8564e382 4903 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
4904
4905 /* Allow only one rate */
4906 if (hweight32(rate) > 1)
4907 return -EINVAL;
4908
4909 count_ht = 0;
4910 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 4911 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 4912 return -EINVAL;
8564e382 4913 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
4914 count_ht++;
4915 if (count_ht > 1)
4916 return -EINVAL;
4917 }
4918 if (count_ht && rate)
4919 return -EINVAL;
4920 }
4921
4922 count_vht = 0;
4923 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 4924 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 4925 return -EINVAL;
8564e382 4926 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
4927 count_vht++;
4928 if (count_vht > 1)
4929 return -EINVAL;
4930 }
4931 if (count_vht && rate)
4932 return -EINVAL;
4933 }
4934
c4a30446
RM
4935 count_he = 0;
4936 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
4937 if (hweight16(beacon_rate->control[band].he_mcs[i]) > 1) {
4938 return -EINVAL;
4939 } else if (beacon_rate->control[band].he_mcs[i]) {
4940 count_he++;
4941 if (count_he > 1)
4942 return -EINVAL;
4943 }
4944 if (count_he && rate)
4945 return -EINVAL;
4946 }
4947
4948 if ((count_ht && count_vht && count_he) ||
4949 (!rate && !count_ht && !count_vht && !count_he))
a7c7fbff
PK
4950 return -EINVAL;
4951
8564e382
JB
4952 if (rate &&
4953 !wiphy_ext_feature_isset(&rdev->wiphy,
4954 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
4955 return -EINVAL;
4956 if (count_ht &&
4957 !wiphy_ext_feature_isset(&rdev->wiphy,
4958 NL80211_EXT_FEATURE_BEACON_RATE_HT))
4959 return -EINVAL;
4960 if (count_vht &&
4961 !wiphy_ext_feature_isset(&rdev->wiphy,
4962 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
4963 return -EINVAL;
c4a30446
RM
4964 if (count_he &&
4965 !wiphy_ext_feature_isset(&rdev->wiphy,
4966 NL80211_EXT_FEATURE_BEACON_RATE_HE))
4967 return -EINVAL;
8564e382 4968
a7c7fbff
PK
4969 return 0;
4970}
4971
81e54d08
PKC
4972static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
4973 struct nlattr *attrs[],
8860020e 4974 struct cfg80211_beacon_data *bcn)
ed1b6cc7 4975{
8860020e 4976 bool haveinfo = false;
81e54d08 4977 int err;
ed1b6cc7 4978
8860020e 4979 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 4980
a1193be8
SW
4981 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
4982 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
4983 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
4984 if (!bcn->head_len)
4985 return -EINVAL;
4986 haveinfo = true;
ed1b6cc7
JB
4987 }
4988
a1193be8
SW
4989 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
4990 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
4991 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 4992 haveinfo = true;
ed1b6cc7
JB
4993 }
4994
4c476991
JB
4995 if (!haveinfo)
4996 return -EINVAL;
3b85875a 4997
a1193be8
SW
4998 if (attrs[NL80211_ATTR_IE]) {
4999 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
5000 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
5001 }
5002
a1193be8 5003 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 5004 bcn->proberesp_ies =
a1193be8 5005 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 5006 bcn->proberesp_ies_len =
a1193be8 5007 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
5008 }
5009
a1193be8 5010 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 5011 bcn->assocresp_ies =
a1193be8 5012 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 5013 bcn->assocresp_ies_len =
a1193be8 5014 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
5015 }
5016
a1193be8
SW
5017 if (attrs[NL80211_ATTR_PROBE_RESP]) {
5018 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
5019 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
5020 }
5021
81e54d08
PKC
5022 if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
5023 struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
5024
8cb08174
JB
5025 err = nla_parse_nested_deprecated(tb,
5026 NL80211_FTM_RESP_ATTR_MAX,
5027 attrs[NL80211_ATTR_FTM_RESPONDER],
5028 NULL, NULL);
81e54d08
PKC
5029 if (err)
5030 return err;
5031
5032 if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
5033 wiphy_ext_feature_isset(&rdev->wiphy,
5034 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
5035 bcn->ftm_responder = 1;
5036 else
5037 return -EOPNOTSUPP;
5038
5039 if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
5040 bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
5041 bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
5042 }
5043
5044 if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
5045 bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5046 bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5047 }
5048 } else {
5049 bcn->ftm_responder = -1;
5050 }
5051
8860020e
JB
5052 return 0;
5053}
5054
796e90f4
JC
5055static int nl80211_parse_he_obss_pd(struct nlattr *attrs,
5056 struct ieee80211_he_obss_pd *he_obss_pd)
5057{
5058 struct nlattr *tb[NL80211_HE_OBSS_PD_ATTR_MAX + 1];
5059 int err;
5060
5061 err = nla_parse_nested(tb, NL80211_HE_OBSS_PD_ATTR_MAX, attrs,
5062 he_obss_pd_policy, NULL);
5063 if (err)
5064 return err;
5065
f5bec330
RM
5066 if (!tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL])
5067 return -EINVAL;
5068
5069 he_obss_pd->sr_ctrl = nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL]);
5070
6c8b6e4a
RM
5071 if (tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET])
5072 he_obss_pd->min_offset =
5073 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
5074 if (tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
5075 he_obss_pd->max_offset =
5076 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
f5bec330
RM
5077 if (tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET])
5078 he_obss_pd->non_srg_max_offset =
5079 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET]);
6c8b6e4a
RM
5080
5081 if (he_obss_pd->min_offset > he_obss_pd->max_offset)
796e90f4
JC
5082 return -EINVAL;
5083
f5bec330
RM
5084 if (tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP])
5085 memcpy(he_obss_pd->bss_color_bitmap,
5086 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP]),
5087 sizeof(he_obss_pd->bss_color_bitmap));
5088
5089 if (tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP])
5090 memcpy(he_obss_pd->partial_bssid_bitmap,
5091 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP]),
5092 sizeof(he_obss_pd->partial_bssid_bitmap));
5093
796e90f4
JC
5094 he_obss_pd->enable = true;
5095
5096 return 0;
5097}
5098
5c5e52d1
JC
5099static int nl80211_parse_he_bss_color(struct nlattr *attrs,
5100 struct cfg80211_he_bss_color *he_bss_color)
5101{
5102 struct nlattr *tb[NL80211_HE_BSS_COLOR_ATTR_MAX + 1];
5103 int err;
5104
5105 err = nla_parse_nested(tb, NL80211_HE_BSS_COLOR_ATTR_MAX, attrs,
5106 he_bss_color_policy, NULL);
5107 if (err)
5108 return err;
5109
5110 if (!tb[NL80211_HE_BSS_COLOR_ATTR_COLOR])
5111 return -EINVAL;
5112
5113 he_bss_color->color =
5114 nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
75e6b594
JB
5115 he_bss_color->enabled =
5116 !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
5c5e52d1
JC
5117 he_bss_color->partial =
5118 nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
5119
5120 return 0;
5121}
5122
291c49de
AD
5123static int nl80211_parse_fils_discovery(struct cfg80211_registered_device *rdev,
5124 struct nlattr *attrs,
5125 struct cfg80211_ap_settings *params)
5126{
5127 struct nlattr *tb[NL80211_FILS_DISCOVERY_ATTR_MAX + 1];
5128 int ret;
5129 struct cfg80211_fils_discovery *fd = &params->fils_discovery;
5130
5131 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5132 NL80211_EXT_FEATURE_FILS_DISCOVERY))
5133 return -EINVAL;
5134
5135 ret = nla_parse_nested(tb, NL80211_FILS_DISCOVERY_ATTR_MAX, attrs,
5136 NULL, NULL);
5137 if (ret)
5138 return ret;
5139
5140 if (!tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN] ||
5141 !tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX] ||
5142 !tb[NL80211_FILS_DISCOVERY_ATTR_TMPL])
5143 return -EINVAL;
5144
5145 fd->tmpl_len = nla_len(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5146 fd->tmpl = nla_data(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5147 fd->min_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN]);
5148 fd->max_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX]);
5149
5150 return 0;
5151}
5152
7443dcd1
AD
5153static int
5154nl80211_parse_unsol_bcast_probe_resp(struct cfg80211_registered_device *rdev,
5155 struct nlattr *attrs,
5156 struct cfg80211_ap_settings *params)
5157{
5158 struct nlattr *tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1];
5159 int ret;
5160 struct cfg80211_unsol_bcast_probe_resp *presp =
5161 &params->unsol_bcast_probe_resp;
5162
5163 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5164 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
5165 return -EINVAL;
5166
5167 ret = nla_parse_nested(tb, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX,
5168 attrs, NULL, NULL);
5169 if (ret)
5170 return ret;
5171
5172 if (!tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] ||
5173 !tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL])
5174 return -EINVAL;
5175
5176 presp->tmpl = nla_data(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5177 presp->tmpl_len = nla_len(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5178 presp->interval = nla_get_u32(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT]);
5179 return 0;
5180}
5181
66cd794e
JB
5182static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
5183 const u8 *rates)
5184{
5185 int i;
5186
5187 if (!rates)
5188 return;
5189
5190 for (i = 0; i < rates[1]; i++) {
5191 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
5192 params->ht_required = true;
5193 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
5194 params->vht_required = true;
2a392596
IP
5195 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HE_PHY)
5196 params->he_required = true;
d6587602
IP
5197 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_SAE_H2E)
5198 params->sae_h2e_required = true;
66cd794e
JB
5199 }
5200}
5201
5202/*
5203 * Since the nl80211 API didn't include, from the beginning, attributes about
5204 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
5205 * benefit of drivers that rebuild IEs in the firmware.
5206 */
5207static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
5208{
5209 const struct cfg80211_beacon_data *bcn = &params->beacon;
ba83bfb1
IM
5210 size_t ies_len = bcn->tail_len;
5211 const u8 *ies = bcn->tail;
66cd794e
JB
5212 const u8 *rates;
5213 const u8 *cap;
5214
5215 rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
5216 nl80211_check_ap_rate_selectors(params, rates);
5217
5218 rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
5219 nl80211_check_ap_rate_selectors(params, rates);
5220
5221 cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
5222 if (cap && cap[1] >= sizeof(*params->ht_cap))
5223 params->ht_cap = (void *)(cap + 2);
5224 cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
5225 if (cap && cap[1] >= sizeof(*params->vht_cap))
5226 params->vht_cap = (void *)(cap + 2);
244eb9ae
ST
5227 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
5228 if (cap && cap[1] >= sizeof(*params->he_cap) + 1)
5229 params->he_cap = (void *)(cap + 3);
7e8d6f12
ST
5230 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
5231 if (cap && cap[1] >= sizeof(*params->he_oper) + 1)
5232 params->he_oper = (void *)(cap + 3);
66cd794e
JB
5233}
5234
46c1dd0c
FF
5235static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
5236 struct cfg80211_ap_settings *params)
5237{
5238 struct wireless_dev *wdev;
5239 bool ret = false;
5240
53873f13 5241 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
5242 if (wdev->iftype != NL80211_IFTYPE_AP &&
5243 wdev->iftype != NL80211_IFTYPE_P2P_GO)
5244 continue;
5245
683b6d3b 5246 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
5247 continue;
5248
683b6d3b 5249 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
5250 ret = true;
5251 break;
5252 }
5253
46c1dd0c
FF
5254 return ret;
5255}
5256
e39e5b5e
JM
5257static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
5258 enum nl80211_auth_type auth_type,
5259 enum nl80211_commands cmd)
5260{
5261 if (auth_type > NL80211_AUTHTYPE_MAX)
5262 return false;
5263
5264 switch (cmd) {
5265 case NL80211_CMD_AUTHENTICATE:
5266 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
5267 auth_type == NL80211_AUTHTYPE_SAE)
5268 return false;
63181060
JM
5269 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5270 NL80211_EXT_FEATURE_FILS_STA) &&
5271 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
5272 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5273 auth_type == NL80211_AUTHTYPE_FILS_PK))
5274 return false;
e39e5b5e
JM
5275 return true;
5276 case NL80211_CMD_CONNECT:
10773a7c 5277 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
26f7044e
CHH
5278 !wiphy_ext_feature_isset(&rdev->wiphy,
5279 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
10773a7c 5280 auth_type == NL80211_AUTHTYPE_SAE)
a3caf744 5281 return false;
10773a7c 5282
a3caf744
VK
5283 /* FILS with SK PFS or PK not supported yet */
5284 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5285 auth_type == NL80211_AUTHTYPE_FILS_PK)
5286 return false;
5287 if (!wiphy_ext_feature_isset(
5288 &rdev->wiphy,
5289 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
5290 auth_type == NL80211_AUTHTYPE_FILS_SK)
5291 return false;
5292 return true;
e39e5b5e 5293 case NL80211_CMD_START_AP:
2831a631
CHH
5294 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5295 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP) &&
5296 auth_type == NL80211_AUTHTYPE_SAE)
e39e5b5e 5297 return false;
63181060
JM
5298 /* FILS not supported yet */
5299 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
5300 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
5301 auth_type == NL80211_AUTHTYPE_FILS_PK)
5302 return false;
e39e5b5e
JM
5303 return true;
5304 default:
5305 return false;
5306 }
5307}
5308
8860020e
JB
5309static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
5310{
5311 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5312 struct net_device *dev = info->user_ptr[1];
5313 struct wireless_dev *wdev = dev->ieee80211_ptr;
5314 struct cfg80211_ap_settings params;
5315 int err;
5316
5317 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5318 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5319 return -EOPNOTSUPP;
5320
5321 if (!rdev->ops->start_ap)
5322 return -EOPNOTSUPP;
5323
5324 if (wdev->beacon_interval)
5325 return -EALREADY;
5326
5327 memset(&params, 0, sizeof(params));
5328
5329 /* these are required for START_AP */
5330 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
5331 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
5332 !info->attrs[NL80211_ATTR_BEACON_HEAD])
5333 return -EINVAL;
5334
81e54d08 5335 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon);
8860020e
JB
5336 if (err)
5337 return err;
5338
5339 params.beacon_interval =
5340 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
5341 params.dtim_period =
5342 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
5343
0c317a02
PK
5344 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
5345 params.beacon_interval);
8860020e
JB
5346 if (err)
5347 return err;
5348
5349 /*
5350 * In theory, some of these attributes should be required here
5351 * but since they were not used when the command was originally
5352 * added, keep them optional for old user space programs to let
5353 * them continue to work with drivers that do not need the
5354 * additional information -- drivers must check!
5355 */
5356 if (info->attrs[NL80211_ATTR_SSID]) {
5357 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
5358 params.ssid_len =
5359 nla_len(info->attrs[NL80211_ATTR_SSID]);
cb9abd48 5360 if (params.ssid_len == 0)
8860020e
JB
5361 return -EINVAL;
5362 }
5363
ab0d76f6 5364 if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
8860020e
JB
5365 params.hidden_ssid = nla_get_u32(
5366 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
8860020e
JB
5367
5368 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
5369
5370 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
5371 params.auth_type = nla_get_u32(
5372 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
5373 if (!nl80211_valid_auth_type(rdev, params.auth_type,
5374 NL80211_CMD_START_AP))
8860020e
JB
5375 return -EINVAL;
5376 } else
5377 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
5378
5379 err = nl80211_crypto_settings(rdev, info, &params.crypto,
5380 NL80211_MAX_NR_CIPHER_SUITES);
5381 if (err)
5382 return err;
5383
1b658f11
VT
5384 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
5385 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
5386 return -EOPNOTSUPP;
5387 params.inactivity_timeout = nla_get_u16(
5388 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
5389 }
5390
53cabad7
JB
5391 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
5392 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5393 return -EINVAL;
5394 params.p2p_ctwindow =
5395 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
5396 if (params.p2p_ctwindow != 0 &&
5397 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
5398 return -EINVAL;
5399 }
5400
5401 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
5402 u8 tmp;
5403
5404 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5405 return -EINVAL;
5406 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
5407 params.p2p_opp_ps = tmp;
5408 if (params.p2p_opp_ps != 0 &&
5409 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
5410 return -EINVAL;
5411 }
5412
aa430da4 5413 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
5414 err = nl80211_parse_chandef(rdev, info, &params.chandef);
5415 if (err)
5416 return err;
5417 } else if (wdev->preset_chandef.chan) {
5418 params.chandef = wdev->preset_chandef;
46c1dd0c 5419 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
5420 return -EINVAL;
5421
923b352f
AN
5422 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
5423 wdev->iftype))
aa430da4
JB
5424 return -EINVAL;
5425
a7c7fbff 5426 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9a5f6488
TC
5427 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
5428 NL80211_ATTR_TX_RATES,
eb89a6a6 5429 &params.beacon_rate,
857b34c4 5430 dev, false);
a7c7fbff
PK
5431 if (err)
5432 return err;
5433
8564e382
JB
5434 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
5435 &params.beacon_rate);
a7c7fbff
PK
5436 if (err)
5437 return err;
5438 }
5439
18998c38
EP
5440 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
5441 params.smps_mode =
5442 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
5443 switch (params.smps_mode) {
5444 case NL80211_SMPS_OFF:
5445 break;
5446 case NL80211_SMPS_STATIC:
5447 if (!(rdev->wiphy.features &
5448 NL80211_FEATURE_STATIC_SMPS))
5449 return -EINVAL;
5450 break;
5451 case NL80211_SMPS_DYNAMIC:
5452 if (!(rdev->wiphy.features &
5453 NL80211_FEATURE_DYNAMIC_SMPS))
5454 return -EINVAL;
5455 break;
5456 default:
5457 return -EINVAL;
5458 }
5459 } else {
5460 params.smps_mode = NL80211_SMPS_OFF;
5461 }
5462
6e8ef842
PK
5463 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
5464 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
5465 return -EOPNOTSUPP;
5466
4baf6bea
OO
5467 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
5468 params.acl = parse_acl_data(&rdev->wiphy, info);
5469 if (IS_ERR(params.acl))
5470 return PTR_ERR(params.acl);
5471 }
5472
a0de1ca3
JC
5473 params.twt_responder =
5474 nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
5475
796e90f4
JC
5476 if (info->attrs[NL80211_ATTR_HE_OBSS_PD]) {
5477 err = nl80211_parse_he_obss_pd(
5478 info->attrs[NL80211_ATTR_HE_OBSS_PD],
5479 &params.he_obss_pd);
bc7a39b4
LC
5480 if (err)
5481 goto out;
796e90f4
JC
5482 }
5483
5c5e52d1
JC
5484 if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
5485 err = nl80211_parse_he_bss_color(
5486 info->attrs[NL80211_ATTR_HE_BSS_COLOR],
5487 &params.he_bss_color);
5488 if (err)
60a0121f 5489 goto out;
5c5e52d1
JC
5490 }
5491
291c49de
AD
5492 if (info->attrs[NL80211_ATTR_FILS_DISCOVERY]) {
5493 err = nl80211_parse_fils_discovery(rdev,
5494 info->attrs[NL80211_ATTR_FILS_DISCOVERY],
5495 &params);
5496 if (err)
5497 goto out;
5498 }
5499
7443dcd1
AD
5500 if (info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP]) {
5501 err = nl80211_parse_unsol_bcast_probe_resp(
5502 rdev, info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP],
5503 &params);
5504 if (err)
abaf94ec 5505 goto out;
7443dcd1
AD
5506 }
5507
66cd794e
JB
5508 nl80211_calculate_ap_params(&params);
5509
fe494370
SD
5510 if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
5511 params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
5512
c56589ed 5513 wdev_lock(wdev);
e35e4d28 5514 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 5515 if (!err) {
683b6d3b 5516 wdev->preset_chandef = params.chandef;
8860020e 5517 wdev->beacon_interval = params.beacon_interval;
9e0e2961 5518 wdev->chandef = params.chandef;
06e191e2
AQ
5519 wdev->ssid_len = params.ssid_len;
5520 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
466a3061
DK
5521
5522 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
5523 wdev->conn_owner_nlportid = info->snd_portid;
46c1dd0c 5524 }
c56589ed 5525 wdev_unlock(wdev);
77765eaf 5526
9951ebfc 5527out:
77765eaf
VT
5528 kfree(params.acl);
5529
56d1893d 5530 return err;
ed1b6cc7
JB
5531}
5532
8860020e
JB
5533static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
5534{
5535 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5536 struct net_device *dev = info->user_ptr[1];
5537 struct wireless_dev *wdev = dev->ieee80211_ptr;
5538 struct cfg80211_beacon_data params;
5539 int err;
5540
5541 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5542 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5543 return -EOPNOTSUPP;
5544
5545 if (!rdev->ops->change_beacon)
5546 return -EOPNOTSUPP;
5547
5548 if (!wdev->beacon_interval)
5549 return -EINVAL;
5550
81e54d08 5551 err = nl80211_parse_beacon(rdev, info->attrs, &params);
8860020e
JB
5552 if (err)
5553 return err;
5554
c56589ed
SW
5555 wdev_lock(wdev);
5556 err = rdev_change_beacon(rdev, dev, &params);
5557 wdev_unlock(wdev);
5558
5559 return err;
8860020e
JB
5560}
5561
5562static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 5563{
4c476991
JB
5564 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5565 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 5566
7c8d5e03 5567 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
5568}
5569
5727ef1b
JB
5570static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
5571 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
5572 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
5573 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 5574 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 5575 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 5576 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
5577};
5578
eccb8e8f 5579static int parse_station_flags(struct genl_info *info,
bdd3ae3d 5580 enum nl80211_iftype iftype,
eccb8e8f 5581 struct station_parameters *params)
5727ef1b
JB
5582{
5583 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 5584 struct nlattr *nla;
5727ef1b
JB
5585 int flag;
5586
eccb8e8f
JB
5587 /*
5588 * Try parsing the new attribute first so userspace
5589 * can specify both for older kernels.
5590 */
5591 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
5592 if (nla) {
5593 struct nl80211_sta_flag_update *sta_flags;
5594
5595 sta_flags = nla_data(nla);
5596 params->sta_flags_mask = sta_flags->mask;
5597 params->sta_flags_set = sta_flags->set;
77ee7c89 5598 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
5599 if ((params->sta_flags_mask |
5600 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
5601 return -EINVAL;
5602 return 0;
5603 }
5604
5605 /* if present, parse the old attribute */
5727ef1b 5606
eccb8e8f 5607 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
5608 if (!nla)
5609 return 0;
5610
8cb08174 5611 if (nla_parse_nested_deprecated(flags, NL80211_STA_FLAG_MAX, nla, sta_flags_policy, info->extack))
5727ef1b
JB
5612 return -EINVAL;
5613
bdd3ae3d
JB
5614 /*
5615 * Only allow certain flags for interface types so that
5616 * other attributes are silently ignored. Remember that
5617 * this is backward compatibility code with old userspace
5618 * and shouldn't be hit in other cases anyway.
5619 */
5620 switch (iftype) {
5621 case NL80211_IFTYPE_AP:
5622 case NL80211_IFTYPE_AP_VLAN:
5623 case NL80211_IFTYPE_P2P_GO:
5624 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5625 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
5626 BIT(NL80211_STA_FLAG_WME) |
5627 BIT(NL80211_STA_FLAG_MFP);
5628 break;
5629 case NL80211_IFTYPE_P2P_CLIENT:
5630 case NL80211_IFTYPE_STATION:
5631 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
5632 BIT(NL80211_STA_FLAG_TDLS_PEER);
5633 break;
5634 case NL80211_IFTYPE_MESH_POINT:
5635 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5636 BIT(NL80211_STA_FLAG_MFP) |
5637 BIT(NL80211_STA_FLAG_AUTHORIZED);
5cf3006c 5638 break;
bdd3ae3d
JB
5639 default:
5640 return -EINVAL;
5641 }
5727ef1b 5642
3383b5a6
JB
5643 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
5644 if (flags[flag]) {
eccb8e8f 5645 params->sta_flags_set |= (1<<flag);
5727ef1b 5646
3383b5a6
JB
5647 /* no longer support new API additions in old API */
5648 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
5649 return -EINVAL;
5650 }
5651 }
5652
5727ef1b
JB
5653 return 0;
5654}
5655
9bb7e0f2 5656bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
c8dcfd8a
FF
5657{
5658 struct nlattr *rate;
8eb41c8d
VK
5659 u32 bitrate;
5660 u16 bitrate_compat;
bbf67e45 5661 enum nl80211_rate_info rate_flg;
c8dcfd8a 5662
ae0be8de 5663 rate = nla_nest_start_noflag(msg, attr);
c8dcfd8a 5664 if (!rate)
db9c64cf 5665 return false;
c8dcfd8a
FF
5666
5667 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
5668 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
5669 /* report 16-bit bitrate only if we can */
5670 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
5671 if (bitrate > 0 &&
5672 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
5673 return false;
5674 if (bitrate_compat > 0 &&
5675 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
5676 return false;
5677
b51f3bee
JB
5678 switch (info->bw) {
5679 case RATE_INFO_BW_5:
5680 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
5681 break;
5682 case RATE_INFO_BW_10:
5683 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
5684 break;
5685 default:
5686 WARN_ON(1);
7b506ff6 5687 fallthrough;
b51f3bee
JB
5688 case RATE_INFO_BW_20:
5689 rate_flg = 0;
5690 break;
5691 case RATE_INFO_BW_40:
5692 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
5693 break;
5694 case RATE_INFO_BW_80:
5695 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
5696 break;
5697 case RATE_INFO_BW_160:
5698 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
5699 break;
c4cbaf79
LC
5700 case RATE_INFO_BW_HE_RU:
5701 rate_flg = 0;
5702 WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
b51f3bee
JB
5703 }
5704
5705 if (rate_flg && nla_put_flag(msg, rate_flg))
5706 return false;
5707
db9c64cf
JB
5708 if (info->flags & RATE_INFO_FLAGS_MCS) {
5709 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
5710 return false;
db9c64cf
JB
5711 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5712 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5713 return false;
5714 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
5715 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
5716 return false;
5717 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
5718 return false;
db9c64cf
JB
5719 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
5720 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
5721 return false;
c4cbaf79
LC
5722 } else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
5723 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
5724 return false;
5725 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
5726 return false;
5727 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
5728 return false;
5729 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
5730 return false;
5731 if (info->bw == RATE_INFO_BW_HE_RU &&
5732 nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
5733 info->he_ru_alloc))
5734 return false;
db9c64cf 5735 }
c8dcfd8a
FF
5736
5737 nla_nest_end(msg, rate);
5738 return true;
c8dcfd8a
FF
5739}
5740
119363c7
FF
5741static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
5742 int id)
5743{
5744 void *attr;
5745 int i = 0;
5746
5747 if (!mask)
5748 return true;
5749
ae0be8de 5750 attr = nla_nest_start_noflag(msg, id);
119363c7
FF
5751 if (!attr)
5752 return false;
5753
5754 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
5755 if (!(mask & BIT(i)))
5756 continue;
5757
5758 if (nla_put_u8(msg, i, signal[i]))
5759 return false;
5760 }
5761
5762 nla_nest_end(msg, attr);
5763
5764 return true;
5765}
5766
cf5ead82
JB
5767static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
5768 u32 seq, int flags,
66266b3a
JL
5769 struct cfg80211_registered_device *rdev,
5770 struct net_device *dev,
98b62183 5771 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
5772{
5773 void *hdr;
f4263c98 5774 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 5775
cf5ead82 5776 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
f77bf486
AS
5777 if (!hdr) {
5778 cfg80211_sinfo_release_content(sinfo);
fd5b74dc 5779 return -1;
f77bf486 5780 }
fd5b74dc 5781
9360ffd1
DM
5782 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5783 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
5784 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
5785 goto nla_put_failure;
f5ea9120 5786
ae0be8de 5787 sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
2ec600d6 5788 if (!sinfoattr)
fd5b74dc 5789 goto nla_put_failure;
319090bf
JB
5790
5791#define PUT_SINFO(attr, memb, type) do { \
d686b920 5792 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
397c657a 5793 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
319090bf
JB
5794 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
5795 sinfo->memb)) \
5796 goto nla_put_failure; \
5797 } while (0)
d686b920 5798#define PUT_SINFO_U64(attr, memb) do { \
397c657a 5799 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
d686b920
JB
5800 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
5801 sinfo->memb, NL80211_STA_INFO_PAD)) \
5802 goto nla_put_failure; \
5803 } while (0)
319090bf
JB
5804
5805 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
5806 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
6c7a0033 5807 PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at);
319090bf 5808
397c657a
OE
5809 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
5810 BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 5811 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 5812 (u32)sinfo->rx_bytes))
9360ffd1 5813 goto nla_put_failure;
319090bf 5814
397c657a
OE
5815 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
5816 BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 5817 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
5818 (u32)sinfo->tx_bytes))
5819 goto nla_put_failure;
319090bf 5820
d686b920
JB
5821 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
5822 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
5823 PUT_SINFO(LLID, llid, u16);
5824 PUT_SINFO(PLID, plid, u16);
5825 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 5826 PUT_SINFO_U64(RX_DURATION, rx_duration);
36647055
THJ
5827 PUT_SINFO_U64(TX_DURATION, tx_duration);
5828
5829 if (wiphy_ext_feature_isset(&rdev->wiphy,
5830 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
5831 PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
319090bf 5832
66266b3a
JL
5833 switch (rdev->wiphy.signal_type) {
5834 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
5835 PUT_SINFO(SIGNAL, signal, u8);
5836 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
5837 break;
5838 default:
5839 break;
5840 }
397c657a 5841 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
5842 if (!nl80211_put_signal(msg, sinfo->chains,
5843 sinfo->chain_signal,
5844 NL80211_STA_INFO_CHAIN_SIGNAL))
5845 goto nla_put_failure;
5846 }
397c657a 5847 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
5848 if (!nl80211_put_signal(msg, sinfo->chains,
5849 sinfo->chain_signal_avg,
5850 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
5851 goto nla_put_failure;
5852 }
397c657a 5853 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
5854 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
5855 NL80211_STA_INFO_TX_BITRATE))
5856 goto nla_put_failure;
5857 }
397c657a 5858 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
5859 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
5860 NL80211_STA_INFO_RX_BITRATE))
420e7fab 5861 goto nla_put_failure;
420e7fab 5862 }
319090bf
JB
5863
5864 PUT_SINFO(RX_PACKETS, rx_packets, u32);
5865 PUT_SINFO(TX_PACKETS, tx_packets, u32);
5866 PUT_SINFO(TX_RETRIES, tx_retries, u32);
5867 PUT_SINFO(TX_FAILED, tx_failed, u32);
5868 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
ab60633c 5869 PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
319090bf
JB
5870 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
5871 PUT_SINFO(LOCAL_PM, local_pm, u32);
5872 PUT_SINFO(PEER_PM, peer_pm, u32);
5873 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
dbdaee7a 5874 PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
1303a51c 5875 PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8);
319090bf 5876
397c657a 5877 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
ae0be8de
MK
5878 bss_param = nla_nest_start_noflag(msg,
5879 NL80211_STA_INFO_BSS_PARAM);
f4263c98
PS
5880 if (!bss_param)
5881 goto nla_put_failure;
5882
9360ffd1
DM
5883 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
5884 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
5885 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
5886 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
5887 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
5888 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
5889 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
5890 sinfo->bss_param.dtim_period) ||
5891 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
5892 sinfo->bss_param.beacon_interval))
5893 goto nla_put_failure;
f4263c98
PS
5894
5895 nla_nest_end(msg, bss_param);
5896 }
397c657a 5897 if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
5898 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
5899 sizeof(struct nl80211_sta_flag_update),
5900 &sinfo->sta_flags))
5901 goto nla_put_failure;
319090bf 5902
d686b920
JB
5903 PUT_SINFO_U64(T_OFFSET, t_offset);
5904 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
5905 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 5906 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
0d4e14a3
AB
5907 PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
5908 PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
81d5439d 5909 if (wiphy_ext_feature_isset(&rdev->wiphy,
9c06602b
BP
5910 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
5911 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
5912 PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
5913 }
319090bf
JB
5914
5915#undef PUT_SINFO
d686b920 5916#undef PUT_SINFO_U64
6de39808 5917
8689c051 5918 if (sinfo->pertid) {
6de39808
JB
5919 struct nlattr *tidsattr;
5920 int tid;
5921
ae0be8de
MK
5922 tidsattr = nla_nest_start_noflag(msg,
5923 NL80211_STA_INFO_TID_STATS);
6de39808
JB
5924 if (!tidsattr)
5925 goto nla_put_failure;
5926
5927 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
5928 struct cfg80211_tid_stats *tidstats;
5929 struct nlattr *tidattr;
5930
5931 tidstats = &sinfo->pertid[tid];
5932
5933 if (!tidstats->filled)
5934 continue;
5935
ae0be8de 5936 tidattr = nla_nest_start_noflag(msg, tid + 1);
6de39808
JB
5937 if (!tidattr)
5938 goto nla_put_failure;
5939
d686b920 5940#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 5941 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
5942 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
5943 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
5944 goto nla_put_failure; \
5945 } while (0)
5946
d686b920
JB
5947 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
5948 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
5949 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
5950 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 5951
d686b920 5952#undef PUT_TIDVAL_U64
52539ca8
THJ
5953 if ((tidstats->filled &
5954 BIT(NL80211_TID_STATS_TXQ_STATS)) &&
5955 !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
5956 NL80211_TID_STATS_TXQ_STATS))
5957 goto nla_put_failure;
5958
6de39808
JB
5959 nla_nest_end(msg, tidattr);
5960 }
5961
5962 nla_nest_end(msg, tidsattr);
5963 }
5964
2ec600d6 5965 nla_nest_end(msg, sinfoattr);
fd5b74dc 5966
319090bf 5967 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
5968 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
5969 sinfo->assoc_req_ies))
5970 goto nla_put_failure;
50d3dfb7 5971
7ea3e110 5972 cfg80211_sinfo_release_content(sinfo);
053c095a
JB
5973 genlmsg_end(msg, hdr);
5974 return 0;
fd5b74dc
JB
5975
5976 nla_put_failure:
7ea3e110 5977 cfg80211_sinfo_release_content(sinfo);
bc3ed28c
TG
5978 genlmsg_cancel(msg, hdr);
5979 return -EMSGSIZE;
fd5b74dc
JB
5980}
5981
2ec600d6 5982static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 5983 struct netlink_callback *cb)
2ec600d6 5984{
73887fd9 5985 struct station_info sinfo;
1b8ec87a 5986 struct cfg80211_registered_device *rdev;
97990a06 5987 struct wireless_dev *wdev;
2ec600d6 5988 u8 mac_addr[ETH_ALEN];
97990a06 5989 int sta_idx = cb->args[2];
2ec600d6 5990 int err;
2ec600d6 5991
5297c65c 5992 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 5993 if (err)
a05829a7
JB
5994 return err;
5995 /* nl80211_prepare_wdev_dump acquired it in the successful case */
5996 __acquire(&rdev->wiphy.mtx);
bba95fef 5997
97990a06
JB
5998 if (!wdev->netdev) {
5999 err = -EINVAL;
6000 goto out_err;
6001 }
6002
1b8ec87a 6003 if (!rdev->ops->dump_station) {
eec60b03 6004 err = -EOPNOTSUPP;
bba95fef
JB
6005 goto out_err;
6006 }
6007
bba95fef 6008 while (1) {
73887fd9 6009 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 6010 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
73887fd9 6011 mac_addr, &sinfo);
bba95fef
JB
6012 if (err == -ENOENT)
6013 break;
6014 if (err)
3b85875a 6015 goto out_err;
bba95fef 6016
cf5ead82 6017 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 6018 NETLINK_CB(cb->skb).portid,
bba95fef 6019 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 6020 rdev, wdev->netdev, mac_addr,
73887fd9 6021 &sinfo) < 0)
bba95fef
JB
6022 goto out;
6023
6024 sta_idx++;
6025 }
6026
bba95fef 6027 out:
97990a06 6028 cb->args[2] = sta_idx;
bba95fef 6029 err = skb->len;
bba95fef 6030 out_err:
a05829a7 6031 wiphy_unlock(&rdev->wiphy);
bba95fef
JB
6032
6033 return err;
2ec600d6 6034}
fd5b74dc 6035
5727ef1b
JB
6036static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
6037{
4c476991
JB
6038 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6039 struct net_device *dev = info->user_ptr[1];
73887fd9 6040 struct station_info sinfo;
fd5b74dc
JB
6041 struct sk_buff *msg;
6042 u8 *mac_addr = NULL;
4c476991 6043 int err;
fd5b74dc 6044
73887fd9 6045 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc 6046
73887fd9
JB
6047 if (!info->attrs[NL80211_ATTR_MAC])
6048 return -EINVAL;
fd5b74dc
JB
6049
6050 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6051
73887fd9
JB
6052 if (!rdev->ops->get_station)
6053 return -EOPNOTSUPP;
3b85875a 6054
73887fd9 6055 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 6056 if (err)
73887fd9 6057 return err;
2ec600d6 6058
fd2120ca 6059 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7ea3e110 6060 if (!msg) {
ba8f566a 6061 cfg80211_sinfo_release_content(&sinfo);
73887fd9 6062 return -ENOMEM;
7ea3e110 6063 }
fd5b74dc 6064
cf5ead82
JB
6065 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
6066 info->snd_portid, info->snd_seq, 0,
73887fd9 6067 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991 6068 nlmsg_free(msg);
73887fd9 6069 return -ENOBUFS;
4c476991 6070 }
3b85875a 6071
73887fd9 6072 return genlmsg_reply(msg, info);
5727ef1b
JB
6073}
6074
77ee7c89
JB
6075int cfg80211_check_station_change(struct wiphy *wiphy,
6076 struct station_parameters *params,
6077 enum cfg80211_station_type statype)
6078{
e4208427
AB
6079 if (params->listen_interval != -1 &&
6080 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 6081 return -EINVAL;
e4208427 6082
17b94247
AB
6083 if (params->support_p2p_ps != -1 &&
6084 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
6085 return -EINVAL;
6086
c72e1140 6087 if (params->aid &&
e4208427
AB
6088 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
6089 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
6090 return -EINVAL;
6091
6092 /* When you run into this, adjust the code below for the new flag */
6093 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
6094
6095 switch (statype) {
eef941e6
TP
6096 case CFG80211_STA_MESH_PEER_KERNEL:
6097 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
6098 /*
6099 * No ignoring the TDLS flag here -- the userspace mesh
6100 * code doesn't have the bug of including TDLS in the
6101 * mask everywhere.
6102 */
6103 if (params->sta_flags_mask &
6104 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6105 BIT(NL80211_STA_FLAG_MFP) |
6106 BIT(NL80211_STA_FLAG_AUTHORIZED)))
6107 return -EINVAL;
6108 break;
6109 case CFG80211_STA_TDLS_PEER_SETUP:
6110 case CFG80211_STA_TDLS_PEER_ACTIVE:
6111 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
6112 return -EINVAL;
6113 /* ignore since it can't change */
6114 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
6115 break;
6116 default:
6117 /* disallow mesh-specific things */
6118 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
6119 return -EINVAL;
6120 if (params->local_pm)
6121 return -EINVAL;
6122 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
6123 return -EINVAL;
6124 }
6125
6126 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
6127 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
6128 /* TDLS can't be set, ... */
6129 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
6130 return -EINVAL;
6131 /*
6132 * ... but don't bother the driver with it. This works around
6133 * a hostapd/wpa_supplicant issue -- it always includes the
6134 * TLDS_PEER flag in the mask even for AP mode.
6135 */
6136 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
6137 }
6138
47edb11b
AB
6139 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
6140 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
6141 /* reject other things that can't change */
6142 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
6143 return -EINVAL;
6144 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
6145 return -EINVAL;
6146 if (params->supported_rates)
6147 return -EINVAL;
c4cbaf79
LC
6148 if (params->ext_capab || params->ht_capa || params->vht_capa ||
6149 params->he_capa)
77ee7c89
JB
6150 return -EINVAL;
6151 }
6152
47edb11b
AB
6153 if (statype != CFG80211_STA_AP_CLIENT &&
6154 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
6155 if (params->vlan)
6156 return -EINVAL;
6157 }
6158
6159 switch (statype) {
6160 case CFG80211_STA_AP_MLME_CLIENT:
6161 /* Use this only for authorizing/unauthorizing a station */
6162 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
6163 return -EOPNOTSUPP;
6164 break;
6165 case CFG80211_STA_AP_CLIENT:
47edb11b 6166 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
6167 /* accept only the listed bits */
6168 if (params->sta_flags_mask &
6169 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
6170 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6171 BIT(NL80211_STA_FLAG_ASSOCIATED) |
6172 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
6173 BIT(NL80211_STA_FLAG_WME) |
6174 BIT(NL80211_STA_FLAG_MFP)))
6175 return -EINVAL;
6176
6177 /* but authenticated/associated only if driver handles it */
6178 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
6179 params->sta_flags_mask &
6180 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6181 BIT(NL80211_STA_FLAG_ASSOCIATED)))
6182 return -EINVAL;
6183 break;
6184 case CFG80211_STA_IBSS:
6185 case CFG80211_STA_AP_STA:
6186 /* reject any changes other than AUTHORIZED */
6187 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
6188 return -EINVAL;
6189 break;
6190 case CFG80211_STA_TDLS_PEER_SETUP:
6191 /* reject any changes other than AUTHORIZED or WME */
6192 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
6193 BIT(NL80211_STA_FLAG_WME)))
6194 return -EINVAL;
6195 /* force (at least) rates when authorizing */
6196 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
6197 !params->supported_rates)
6198 return -EINVAL;
6199 break;
6200 case CFG80211_STA_TDLS_PEER_ACTIVE:
6201 /* reject any changes */
6202 return -EINVAL;
eef941e6 6203 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
6204 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
6205 return -EINVAL;
6206 break;
eef941e6 6207 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
6208 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
6209 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
6210 return -EINVAL;
6211 break;
6212 }
6213
06f7c88c
BL
6214 /*
6215 * Older kernel versions ignored this attribute entirely, so don't
6216 * reject attempts to update it but mark it as unused instead so the
6217 * driver won't look at the data.
6218 */
6219 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
6220 statype != CFG80211_STA_TDLS_PEER_SETUP)
6221 params->opmode_notif_used = false;
6222
77ee7c89
JB
6223 return 0;
6224}
6225EXPORT_SYMBOL(cfg80211_check_station_change);
6226
5727ef1b 6227/*
c258d2de 6228 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 6229 */
80b99899
JB
6230static struct net_device *get_vlan(struct genl_info *info,
6231 struct cfg80211_registered_device *rdev)
5727ef1b 6232{
463d0183 6233 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
6234 struct net_device *v;
6235 int ret;
6236
6237 if (!vlanattr)
6238 return NULL;
6239
6240 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
6241 if (!v)
6242 return ERR_PTR(-ENODEV);
6243
6244 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
6245 ret = -EINVAL;
6246 goto error;
5727ef1b 6247 }
80b99899 6248
77ee7c89
JB
6249 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
6250 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
6251 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
6252 ret = -EINVAL;
6253 goto error;
6254 }
6255
80b99899
JB
6256 if (!netif_running(v)) {
6257 ret = -ENETDOWN;
6258 goto error;
6259 }
6260
6261 return v;
6262 error:
6263 dev_put(v);
6264 return ERR_PTR(ret);
5727ef1b
JB
6265}
6266
94e860f1
JB
6267static const struct nla_policy
6268nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
6269 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
6270 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
6271};
6272
ff276691
JB
6273static int nl80211_parse_sta_wme(struct genl_info *info,
6274 struct station_parameters *params)
df881293 6275{
df881293
JM
6276 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
6277 struct nlattr *nla;
6278 int err;
6279
df881293
JM
6280 /* parse WME attributes if present */
6281 if (!info->attrs[NL80211_ATTR_STA_WME])
6282 return 0;
6283
6284 nla = info->attrs[NL80211_ATTR_STA_WME];
8cb08174
JB
6285 err = nla_parse_nested_deprecated(tb, NL80211_STA_WME_MAX, nla,
6286 nl80211_sta_wme_policy,
6287 info->extack);
df881293
JM
6288 if (err)
6289 return err;
6290
6291 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
6292 params->uapsd_queues = nla_get_u8(
6293 tb[NL80211_STA_WME_UAPSD_QUEUES]);
6294 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
6295 return -EINVAL;
6296
6297 if (tb[NL80211_STA_WME_MAX_SP])
6298 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
6299
6300 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
6301 return -EINVAL;
6302
6303 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
6304
6305 return 0;
6306}
6307
c01fc9ad
SD
6308static int nl80211_parse_sta_channel_info(struct genl_info *info,
6309 struct station_parameters *params)
6310{
6311 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
6312 params->supported_channels =
6313 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
6314 params->supported_channels_len =
6315 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
6316 /*
6317 * Need to include at least one (first channel, number of
cb9abd48
JB
6318 * channels) tuple for each subband (checked in policy),
6319 * and must have proper tuples for the rest of the data as well.
c01fc9ad 6320 */
c01fc9ad
SD
6321 if (params->supported_channels_len % 2)
6322 return -EINVAL;
6323 }
6324
6325 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
6326 params->supported_oper_classes =
6327 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
6328 params->supported_oper_classes_len =
6329 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
c01fc9ad
SD
6330 }
6331 return 0;
6332}
6333
ff276691
JB
6334static int nl80211_set_station_tdls(struct genl_info *info,
6335 struct station_parameters *params)
6336{
c01fc9ad 6337 int err;
ff276691 6338 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
6339 if (info->attrs[NL80211_ATTR_PEER_AID])
6340 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
6341 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
6342 params->ht_capa =
6343 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
6344 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
6345 params->vht_capa =
6346 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
c4cbaf79
LC
6347 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
6348 params->he_capa =
6349 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6350 params->he_capa_len =
6351 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
c4cbaf79 6352 }
ff276691 6353
c01fc9ad
SD
6354 err = nl80211_parse_sta_channel_info(info, params);
6355 if (err)
6356 return err;
6357
ff276691
JB
6358 return nl80211_parse_sta_wme(info, params);
6359}
6360
e96d1cd2
ARN
6361static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
6362 struct station_parameters *params)
6363{
6364 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6365 int idx;
6366
6367 if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
6368 if (!rdev->ops->set_tx_power ||
6369 !wiphy_ext_feature_isset(&rdev->wiphy,
6370 NL80211_EXT_FEATURE_STA_TX_PWR))
6371 return -EOPNOTSUPP;
6372
6373 idx = NL80211_ATTR_STA_TX_POWER_SETTING;
6374 params->txpwr.type = nla_get_u8(info->attrs[idx]);
6375
6376 if (params->txpwr.type == NL80211_TX_POWER_LIMITED) {
6377 idx = NL80211_ATTR_STA_TX_POWER;
6378
6379 if (info->attrs[idx])
6380 params->txpwr.power =
6381 nla_get_s16(info->attrs[idx]);
6382 else
6383 return -EINVAL;
6384 }
6385 params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER;
6386 }
6387
6388 return 0;
6389}
6390
5727ef1b
JB
6391static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
6392{
4c476991 6393 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 6394 struct net_device *dev = info->user_ptr[1];
5727ef1b 6395 struct station_parameters params;
77ee7c89
JB
6396 u8 *mac_addr;
6397 int err;
5727ef1b
JB
6398
6399 memset(&params, 0, sizeof(params));
6400
77ee7c89
JB
6401 if (!rdev->ops->change_station)
6402 return -EOPNOTSUPP;
6403
e4208427
AB
6404 /*
6405 * AID and listen_interval properties can be set only for unassociated
6406 * station. Include these parameters here and will check them in
6407 * cfg80211_check_station_change().
6408 */
a9bc31e4
AB
6409 if (info->attrs[NL80211_ATTR_STA_AID])
6410 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427 6411
14f34e36
GG
6412 if (info->attrs[NL80211_ATTR_VLAN_ID])
6413 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
6414
e4208427
AB
6415 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
6416 params.listen_interval =
6417 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
6418 else
6419 params.listen_interval = -1;
5727ef1b 6420
ab0d76f6
JB
6421 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
6422 params.support_p2p_ps =
6423 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
6424 else
17b94247 6425 params.support_p2p_ps = -1;
17b94247 6426
5727ef1b
JB
6427 if (!info->attrs[NL80211_ATTR_MAC])
6428 return -EINVAL;
6429
6430 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6431
6432 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
6433 params.supported_rates =
6434 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6435 params.supported_rates_len =
6436 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6437 }
6438
9d62a986
JM
6439 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
6440 params.capability =
6441 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
6442 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
6443 }
6444
6445 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
6446 params.ext_capab =
6447 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6448 params.ext_capab_len =
6449 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6450 }
6451
bdd3ae3d 6452 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
6453 return -EINVAL;
6454
ab0d76f6 6455 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2ec600d6 6456 params.plink_action =
f8bacc21 6457 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2ec600d6 6458
f8bacc21 6459 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 6460 params.plink_state =
f8bacc21 6461 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
ab0d76f6 6462 if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
7d27a0ba
MH
6463 params.peer_aid = nla_get_u16(
6464 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
f8bacc21
JB
6465 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
6466 }
9c3990aa 6467
ab0d76f6
JB
6468 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
6469 params.local_pm = nla_get_u32(
3b1c5a53
MP
6470 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
6471
06f7c88c
BL
6472 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
6473 params.opmode_notif_used = true;
6474 params.opmode_notif =
6475 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
6476 }
6477
43e64bf3
RM
6478 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
6479 params.he_6ghz_capa =
fce2ff72 6480 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
43e64bf3 6481
36647055
THJ
6482 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
6483 params.airtime_weight =
6484 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
6485
6486 if (params.airtime_weight &&
6487 !wiphy_ext_feature_isset(&rdev->wiphy,
6488 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6489 return -EOPNOTSUPP;
6490
e96d1cd2
ARN
6491 err = nl80211_parse_sta_txpower_setting(info, &params);
6492 if (err)
6493 return err;
6494
77ee7c89
JB
6495 /* Include parameters for TDLS peer (will check later) */
6496 err = nl80211_set_station_tdls(info, &params);
6497 if (err)
6498 return err;
6499
6500 params.vlan = get_vlan(info, rdev);
6501 if (IS_ERR(params.vlan))
6502 return PTR_ERR(params.vlan);
6503
a97f4424
JB
6504 switch (dev->ieee80211_ptr->iftype) {
6505 case NL80211_IFTYPE_AP:
6506 case NL80211_IFTYPE_AP_VLAN:
074ac8df 6507 case NL80211_IFTYPE_P2P_GO:
074ac8df 6508 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 6509 case NL80211_IFTYPE_STATION:
267335d6 6510 case NL80211_IFTYPE_ADHOC:
a97f4424 6511 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
6512 break;
6513 default:
77ee7c89
JB
6514 err = -EOPNOTSUPP;
6515 goto out_put_vlan;
034d655e
JB
6516 }
6517
77ee7c89 6518 /* driver will call cfg80211_check_station_change() */
e35e4d28 6519 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 6520
77ee7c89 6521 out_put_vlan:
5727ef1b
JB
6522 if (params.vlan)
6523 dev_put(params.vlan);
3b85875a 6524
5727ef1b
JB
6525 return err;
6526}
6527
6528static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
6529{
4c476991 6530 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 6531 int err;
4c476991 6532 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
6533 struct station_parameters params;
6534 u8 *mac_addr = NULL;
bda95eb1
JB
6535 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6536 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
6537
6538 memset(&params, 0, sizeof(params));
6539
984c311b
JB
6540 if (!rdev->ops->add_station)
6541 return -EOPNOTSUPP;
6542
5727ef1b
JB
6543 if (!info->attrs[NL80211_ATTR_MAC])
6544 return -EINVAL;
6545
5727ef1b
JB
6546 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
6547 return -EINVAL;
6548
6549 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
6550 return -EINVAL;
6551
5e4b6f56
JM
6552 if (!info->attrs[NL80211_ATTR_STA_AID] &&
6553 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
6554 return -EINVAL;
6555
5727ef1b
JB
6556 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6557 params.supported_rates =
6558 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6559 params.supported_rates_len =
6560 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
6561 params.listen_interval =
6562 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 6563
14f34e36
GG
6564 if (info->attrs[NL80211_ATTR_VLAN_ID])
6565 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
6566
17b94247 6567 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
ab0d76f6
JB
6568 params.support_p2p_ps =
6569 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
17b94247
AB
6570 } else {
6571 /*
6572 * if not specified, assume it's supported for P2P GO interface,
6573 * and is NOT supported for AP interface
6574 */
6575 params.support_p2p_ps =
6576 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
6577 }
6578
3d124ea2 6579 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 6580 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
6581 else
6582 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
51b50fbe 6583
9d62a986
JM
6584 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
6585 params.capability =
6586 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
6587 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
6588 }
6589
6590 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
6591 params.ext_capab =
6592 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6593 params.ext_capab_len =
6594 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
6595 }
6596
36aedc90
JM
6597 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
6598 params.ht_capa =
6599 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 6600
f461be3e
MP
6601 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
6602 params.vht_capa =
6603 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
6604
c4cbaf79
LC
6605 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
6606 params.he_capa =
6607 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
6608 params.he_capa_len =
6609 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
c4cbaf79
LC
6610 }
6611
43e64bf3
RM
6612 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
6613 params.he_6ghz_capa =
6614 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
6615
60f4a7b1
MK
6616 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
6617 params.opmode_notif_used = true;
6618 params.opmode_notif =
6619 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
6620 }
6621
ab0d76f6 6622 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
96b78dff 6623 params.plink_action =
f8bacc21 6624 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
96b78dff 6625
36647055
THJ
6626 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
6627 params.airtime_weight =
6628 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
6629
6630 if (params.airtime_weight &&
6631 !wiphy_ext_feature_isset(&rdev->wiphy,
6632 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6633 return -EOPNOTSUPP;
6634
e96d1cd2
ARN
6635 err = nl80211_parse_sta_txpower_setting(info, &params);
6636 if (err)
6637 return err;
6638
c01fc9ad
SD
6639 err = nl80211_parse_sta_channel_info(info, &params);
6640 if (err)
6641 return err;
6642
ff276691
JB
6643 err = nl80211_parse_sta_wme(info, &params);
6644 if (err)
6645 return err;
bdd90d5e 6646
bdd3ae3d 6647 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
6648 return -EINVAL;
6649
496fcc29
JB
6650 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
6651 * as userspace might just pass through the capabilities from the IEs
6652 * directly, rather than enforcing this restriction and returning an
6653 * error in this case.
6654 */
6655 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
6656 params.ht_capa = NULL;
6657 params.vht_capa = NULL;
c4cbaf79
LC
6658
6659 /* HE requires WME */
43e64bf3 6660 if (params.he_capa_len || params.he_6ghz_capa)
c4cbaf79 6661 return -EINVAL;
496fcc29
JB
6662 }
6663
43e64bf3
RM
6664 /* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */
6665 if (params.he_6ghz_capa && (params.ht_capa || params.vht_capa))
6666 return -EINVAL;
6667
77ee7c89
JB
6668 /* When you run into this, adjust the code below for the new flag */
6669 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
6670
bdd90d5e
JB
6671 switch (dev->ieee80211_ptr->iftype) {
6672 case NL80211_IFTYPE_AP:
6673 case NL80211_IFTYPE_AP_VLAN:
6674 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
6675 /* ignore WME attributes if iface/sta is not capable */
6676 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
6677 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
6678 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 6679
bdd90d5e 6680 /* TDLS peers cannot be added */
3d124ea2
JM
6681 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
6682 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 6683 return -EINVAL;
bdd90d5e
JB
6684 /* but don't bother the driver with it */
6685 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 6686
d582cffb
JB
6687 /* allow authenticated/associated only if driver handles it */
6688 if (!(rdev->wiphy.features &
6689 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 6690 params.sta_flags_mask & auth_assoc)
d582cffb
JB
6691 return -EINVAL;
6692
bda95eb1
JB
6693 /* Older userspace, or userspace wanting to be compatible with
6694 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
6695 * and assoc flags in the mask, but assumes the station will be
6696 * added as associated anyway since this was the required driver
6697 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
6698 * introduced.
6699 * In order to not bother drivers with this quirk in the API
6700 * set the flags in both the mask and set for new stations in
6701 * this case.
6702 */
6703 if (!(params.sta_flags_mask & auth_assoc)) {
6704 params.sta_flags_mask |= auth_assoc;
6705 params.sta_flags_set |= auth_assoc;
6706 }
6707
bdd90d5e
JB
6708 /* must be last in here for error handling */
6709 params.vlan = get_vlan(info, rdev);
6710 if (IS_ERR(params.vlan))
6711 return PTR_ERR(params.vlan);
6712 break;
6713 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
6714 /* ignore uAPSD data */
6715 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
6716
d582cffb
JB
6717 /* associated is disallowed */
6718 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
6719 return -EINVAL;
bdd90d5e 6720 /* TDLS peers cannot be added */
3d124ea2
JM
6721 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
6722 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
6723 return -EINVAL;
6724 break;
6725 case NL80211_IFTYPE_STATION:
93d08f0b 6726 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
6727 /* ignore uAPSD data */
6728 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
6729
77ee7c89
JB
6730 /* these are disallowed */
6731 if (params.sta_flags_mask &
6732 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
6733 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 6734 return -EINVAL;
bdd90d5e
JB
6735 /* Only TDLS peers can be added */
6736 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
6737 return -EINVAL;
6738 /* Can only add if TDLS ... */
6739 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
6740 return -EOPNOTSUPP;
6741 /* ... with external setup is supported */
6742 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
6743 return -EOPNOTSUPP;
77ee7c89
JB
6744 /*
6745 * Older wpa_supplicant versions always mark the TDLS peer
6746 * as authorized, but it shouldn't yet be.
6747 */
6748 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
6749 break;
6750 default:
6751 return -EOPNOTSUPP;
c75786c9
EP
6752 }
6753
bdd90d5e 6754 /* be aware of params.vlan when changing code here */
5727ef1b 6755
e35e4d28 6756 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 6757
5727ef1b
JB
6758 if (params.vlan)
6759 dev_put(params.vlan);
5727ef1b
JB
6760 return err;
6761}
6762
6763static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
6764{
4c476991
JB
6765 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6766 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
6767 struct station_del_parameters params;
6768
6769 memset(&params, 0, sizeof(params));
5727ef1b
JB
6770
6771 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 6772 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 6773
306b79ea
JB
6774 switch (dev->ieee80211_ptr->iftype) {
6775 case NL80211_IFTYPE_AP:
6776 case NL80211_IFTYPE_AP_VLAN:
6777 case NL80211_IFTYPE_MESH_POINT:
6778 case NL80211_IFTYPE_P2P_GO:
6779 /* always accept these */
6780 break;
6781 case NL80211_IFTYPE_ADHOC:
6782 /* conditionally accept */
6783 if (wiphy_ext_feature_isset(&rdev->wiphy,
6784 NL80211_EXT_FEATURE_DEL_IBSS_STA))
6785 break;
edafcf42 6786 return -EINVAL;
306b79ea 6787 default:
4c476991 6788 return -EINVAL;
306b79ea 6789 }
5727ef1b 6790
4c476991
JB
6791 if (!rdev->ops->del_station)
6792 return -EOPNOTSUPP;
3b85875a 6793
98856866
JM
6794 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
6795 params.subtype =
6796 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
6797 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
6798 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
6799 return -EINVAL;
6800 } else {
6801 /* Default to Deauthentication frame */
6802 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
6803 }
6804
6805 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
6806 params.reason_code =
6807 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
6808 if (params.reason_code == 0)
6809 return -EINVAL; /* 0 is reserved */
6810 } else {
6811 /* Default to reason code 2 */
6812 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
6813 }
6814
89c771e5 6815 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
6816}
6817
15e47304 6818static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
6819 int flags, struct net_device *dev,
6820 u8 *dst, u8 *next_hop,
6821 struct mpath_info *pinfo)
6822{
6823 void *hdr;
6824 struct nlattr *pinfoattr;
6825
1ef4c850 6826 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
6827 if (!hdr)
6828 return -1;
6829
9360ffd1
DM
6830 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6831 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
6832 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
6833 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
6834 goto nla_put_failure;
f5ea9120 6835
ae0be8de 6836 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MPATH_INFO);
2ec600d6
LCC
6837 if (!pinfoattr)
6838 goto nla_put_failure;
9360ffd1
DM
6839 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
6840 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
6841 pinfo->frame_qlen))
6842 goto nla_put_failure;
6843 if (((pinfo->filled & MPATH_INFO_SN) &&
6844 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
6845 ((pinfo->filled & MPATH_INFO_METRIC) &&
6846 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
6847 pinfo->metric)) ||
6848 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
6849 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
6850 pinfo->exptime)) ||
6851 ((pinfo->filled & MPATH_INFO_FLAGS) &&
6852 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
6853 pinfo->flags)) ||
6854 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
6855 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
6856 pinfo->discovery_timeout)) ||
6857 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
6858 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
cc241636
JH
6859 pinfo->discovery_retries)) ||
6860 ((pinfo->filled & MPATH_INFO_HOP_COUNT) &&
6861 nla_put_u8(msg, NL80211_MPATH_INFO_HOP_COUNT,
540bbcb9
JH
6862 pinfo->hop_count)) ||
6863 ((pinfo->filled & MPATH_INFO_PATH_CHANGE) &&
6864 nla_put_u32(msg, NL80211_MPATH_INFO_PATH_CHANGE,
6865 pinfo->path_change_count)))
9360ffd1 6866 goto nla_put_failure;
2ec600d6
LCC
6867
6868 nla_nest_end(msg, pinfoattr);
6869
053c095a
JB
6870 genlmsg_end(msg, hdr);
6871 return 0;
2ec600d6
LCC
6872
6873 nla_put_failure:
bc3ed28c
TG
6874 genlmsg_cancel(msg, hdr);
6875 return -EMSGSIZE;
2ec600d6
LCC
6876}
6877
6878static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 6879 struct netlink_callback *cb)
2ec600d6 6880{
2ec600d6 6881 struct mpath_info pinfo;
1b8ec87a 6882 struct cfg80211_registered_device *rdev;
97990a06 6883 struct wireless_dev *wdev;
2ec600d6
LCC
6884 u8 dst[ETH_ALEN];
6885 u8 next_hop[ETH_ALEN];
97990a06 6886 int path_idx = cb->args[2];
2ec600d6 6887 int err;
2ec600d6 6888
5297c65c 6889 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 6890 if (err)
a05829a7
JB
6891 return err;
6892 /* nl80211_prepare_wdev_dump acquired it in the successful case */
6893 __acquire(&rdev->wiphy.mtx);
bba95fef 6894
1b8ec87a 6895 if (!rdev->ops->dump_mpath) {
eec60b03 6896 err = -EOPNOTSUPP;
bba95fef
JB
6897 goto out_err;
6898 }
6899
97990a06 6900 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 6901 err = -EOPNOTSUPP;
0448b5fc 6902 goto out_err;
eec60b03
JM
6903 }
6904
bba95fef 6905 while (1) {
1b8ec87a 6906 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 6907 next_hop, &pinfo);
bba95fef 6908 if (err == -ENOENT)
2ec600d6 6909 break;
bba95fef 6910 if (err)
3b85875a 6911 goto out_err;
2ec600d6 6912
15e47304 6913 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 6914 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 6915 wdev->netdev, dst, next_hop,
bba95fef
JB
6916 &pinfo) < 0)
6917 goto out;
2ec600d6 6918
bba95fef 6919 path_idx++;
2ec600d6 6920 }
2ec600d6 6921
bba95fef 6922 out:
97990a06 6923 cb->args[2] = path_idx;
bba95fef 6924 err = skb->len;
bba95fef 6925 out_err:
a05829a7 6926 wiphy_unlock(&rdev->wiphy);
bba95fef 6927 return err;
2ec600d6
LCC
6928}
6929
6930static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
6931{
4c476991 6932 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 6933 int err;
4c476991 6934 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6935 struct mpath_info pinfo;
6936 struct sk_buff *msg;
6937 u8 *dst = NULL;
6938 u8 next_hop[ETH_ALEN];
6939
6940 memset(&pinfo, 0, sizeof(pinfo));
6941
6942 if (!info->attrs[NL80211_ATTR_MAC])
6943 return -EINVAL;
6944
6945 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6946
4c476991
JB
6947 if (!rdev->ops->get_mpath)
6948 return -EOPNOTSUPP;
2ec600d6 6949
4c476991
JB
6950 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6951 return -EOPNOTSUPP;
eec60b03 6952
e35e4d28 6953 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 6954 if (err)
4c476991 6955 return err;
2ec600d6 6956
fd2120ca 6957 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 6958 if (!msg)
4c476991 6959 return -ENOMEM;
2ec600d6 6960
15e47304 6961 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
6962 dev, dst, next_hop, &pinfo) < 0) {
6963 nlmsg_free(msg);
6964 return -ENOBUFS;
6965 }
3b85875a 6966
4c476991 6967 return genlmsg_reply(msg, info);
2ec600d6
LCC
6968}
6969
6970static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
6971{
4c476991
JB
6972 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6973 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6974 u8 *dst = NULL;
6975 u8 *next_hop = NULL;
6976
6977 if (!info->attrs[NL80211_ATTR_MAC])
6978 return -EINVAL;
6979
6980 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
6981 return -EINVAL;
6982
6983 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6984 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
6985
4c476991
JB
6986 if (!rdev->ops->change_mpath)
6987 return -EOPNOTSUPP;
35a8efe1 6988
4c476991
JB
6989 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6990 return -EOPNOTSUPP;
2ec600d6 6991
e35e4d28 6992 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 6993}
4c476991 6994
2ec600d6
LCC
6995static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
6996{
4c476991
JB
6997 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6998 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6999 u8 *dst = NULL;
7000 u8 *next_hop = NULL;
7001
7002 if (!info->attrs[NL80211_ATTR_MAC])
7003 return -EINVAL;
7004
7005 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
7006 return -EINVAL;
7007
7008 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7009 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
7010
4c476991
JB
7011 if (!rdev->ops->add_mpath)
7012 return -EOPNOTSUPP;
35a8efe1 7013
4c476991
JB
7014 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7015 return -EOPNOTSUPP;
2ec600d6 7016
e35e4d28 7017 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
7018}
7019
7020static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
7021{
4c476991
JB
7022 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7023 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
7024 u8 *dst = NULL;
7025
7026 if (info->attrs[NL80211_ATTR_MAC])
7027 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7028
4c476991
JB
7029 if (!rdev->ops->del_mpath)
7030 return -EOPNOTSUPP;
3b85875a 7031
b501426c
MP
7032 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7033 return -EOPNOTSUPP;
7034
e35e4d28 7035 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
7036}
7037
66be7d2b
HR
7038static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
7039{
7040 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7041 int err;
7042 struct net_device *dev = info->user_ptr[1];
7043 struct mpath_info pinfo;
7044 struct sk_buff *msg;
7045 u8 *dst = NULL;
7046 u8 mpp[ETH_ALEN];
7047
7048 memset(&pinfo, 0, sizeof(pinfo));
7049
7050 if (!info->attrs[NL80211_ATTR_MAC])
7051 return -EINVAL;
7052
7053 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7054
7055 if (!rdev->ops->get_mpp)
7056 return -EOPNOTSUPP;
7057
7058 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7059 return -EOPNOTSUPP;
7060
7061 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
7062 if (err)
7063 return err;
7064
7065 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7066 if (!msg)
7067 return -ENOMEM;
7068
7069 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
7070 dev, dst, mpp, &pinfo) < 0) {
7071 nlmsg_free(msg);
7072 return -ENOBUFS;
7073 }
7074
7075 return genlmsg_reply(msg, info);
7076}
7077
7078static int nl80211_dump_mpp(struct sk_buff *skb,
7079 struct netlink_callback *cb)
7080{
7081 struct mpath_info pinfo;
7082 struct cfg80211_registered_device *rdev;
7083 struct wireless_dev *wdev;
7084 u8 dst[ETH_ALEN];
7085 u8 mpp[ETH_ALEN];
7086 int path_idx = cb->args[2];
7087 int err;
7088
5297c65c 7089 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
66be7d2b 7090 if (err)
a05829a7
JB
7091 return err;
7092 /* nl80211_prepare_wdev_dump acquired it in the successful case */
7093 __acquire(&rdev->wiphy.mtx);
66be7d2b
HR
7094
7095 if (!rdev->ops->dump_mpp) {
7096 err = -EOPNOTSUPP;
7097 goto out_err;
7098 }
7099
7100 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
7101 err = -EOPNOTSUPP;
7102 goto out_err;
7103 }
7104
7105 while (1) {
7106 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
7107 mpp, &pinfo);
7108 if (err == -ENOENT)
7109 break;
7110 if (err)
7111 goto out_err;
7112
7113 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
7114 cb->nlh->nlmsg_seq, NLM_F_MULTI,
7115 wdev->netdev, dst, mpp,
7116 &pinfo) < 0)
7117 goto out;
7118
7119 path_idx++;
7120 }
7121
7122 out:
7123 cb->args[2] = path_idx;
7124 err = skb->len;
7125 out_err:
a05829a7 7126 wiphy_unlock(&rdev->wiphy);
66be7d2b
HR
7127 return err;
7128}
7129
9f1ba906
JM
7130static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
7131{
4c476991
JB
7132 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7133 struct net_device *dev = info->user_ptr[1];
c56589ed 7134 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 7135 struct bss_parameters params;
c56589ed 7136 int err;
9f1ba906
JM
7137
7138 memset(&params, 0, sizeof(params));
7139 /* default to not changing parameters */
7140 params.use_cts_prot = -1;
7141 params.use_short_preamble = -1;
7142 params.use_short_slot_time = -1;
fd8aaaf3 7143 params.ap_isolate = -1;
50b12f59 7144 params.ht_opmode = -1;
53cabad7
JB
7145 params.p2p_ctwindow = -1;
7146 params.p2p_opp_ps = -1;
9f1ba906
JM
7147
7148 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
7149 params.use_cts_prot =
7150 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
7151 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
7152 params.use_short_preamble =
7153 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
7154 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
7155 params.use_short_slot_time =
7156 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
7157 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
7158 params.basic_rates =
7159 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7160 params.basic_rates_len =
7161 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7162 }
fd8aaaf3
FF
7163 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
7164 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
7165 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
7166 params.ht_opmode =
7167 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 7168
53cabad7
JB
7169 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
7170 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7171 return -EINVAL;
7172 params.p2p_ctwindow =
ab0d76f6 7173 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
7174 if (params.p2p_ctwindow != 0 &&
7175 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
7176 return -EINVAL;
7177 }
7178
7179 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
7180 u8 tmp;
7181
7182 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7183 return -EINVAL;
7184 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
7185 params.p2p_opp_ps = tmp;
7186 if (params.p2p_opp_ps &&
7187 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
7188 return -EINVAL;
7189 }
7190
4c476991
JB
7191 if (!rdev->ops->change_bss)
7192 return -EOPNOTSUPP;
9f1ba906 7193
074ac8df 7194 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
7195 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
7196 return -EOPNOTSUPP;
3b85875a 7197
c56589ed
SW
7198 wdev_lock(wdev);
7199 err = rdev_change_bss(rdev, dev, &params);
7200 wdev_unlock(wdev);
7201
7202 return err;
9f1ba906
JM
7203}
7204
b2e1b302
LR
7205static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
7206{
b2e1b302 7207 char *data = NULL;
05050753 7208 bool is_indoor;
57b5ce07 7209 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
7210 u32 owner_nlportid;
7211
80778f18
LR
7212 /*
7213 * You should only get this when cfg80211 hasn't yet initialized
7214 * completely when built-in to the kernel right between the time
7215 * window between nl80211_init() and regulatory_init(), if that is
7216 * even possible.
7217 */
458f4f9e 7218 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 7219 return -EINPROGRESS;
80778f18 7220
57b5ce07
LR
7221 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
7222 user_reg_hint_type =
7223 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
7224 else
7225 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
7226
7227 switch (user_reg_hint_type) {
7228 case NL80211_USER_REG_HINT_USER:
7229 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
7230 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
7231 return -EINVAL;
7232
7233 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
7234 return regulatory_hint_user(data, user_reg_hint_type);
7235 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
7236 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
7237 owner_nlportid = info->snd_portid;
7238 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
7239 } else {
7240 owner_nlportid = 0;
7241 is_indoor = true;
7242 }
7243
7244 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
7245 default:
7246 return -EINVAL;
7247 }
b2e1b302
LR
7248}
7249
1ea4ff3e
JB
7250static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
7251{
7252 return reg_reload_regdb();
7253}
7254
24bdd9f4 7255static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 7256 struct genl_info *info)
93da9cc1 7257{
4c476991 7258 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 7259 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
7260 struct wireless_dev *wdev = dev->ieee80211_ptr;
7261 struct mesh_config cur_params;
7262 int err = 0;
93da9cc1 7263 void *hdr;
7264 struct nlattr *pinfoattr;
7265 struct sk_buff *msg;
7266
29cbe68c
JB
7267 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
7268 return -EOPNOTSUPP;
7269
24bdd9f4 7270 if (!rdev->ops->get_mesh_config)
4c476991 7271 return -EOPNOTSUPP;
f3f92586 7272
29cbe68c
JB
7273 wdev_lock(wdev);
7274 /* If not connected, get default parameters */
7275 if (!wdev->mesh_id_len)
7276 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
7277 else
e35e4d28 7278 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
7279 wdev_unlock(wdev);
7280
93da9cc1 7281 if (err)
4c476991 7282 return err;
93da9cc1 7283
7284 /* Draw up a netlink message to send back */
fd2120ca 7285 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
7286 if (!msg)
7287 return -ENOMEM;
15e47304 7288 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 7289 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 7290 if (!hdr)
efe1cf0c 7291 goto out;
ae0be8de 7292 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 7293 if (!pinfoattr)
7294 goto nla_put_failure;
9360ffd1
DM
7295 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
7296 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
7297 cur_params.dot11MeshRetryTimeout) ||
7298 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
7299 cur_params.dot11MeshConfirmTimeout) ||
7300 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
7301 cur_params.dot11MeshHoldingTimeout) ||
7302 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
7303 cur_params.dot11MeshMaxPeerLinks) ||
7304 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
7305 cur_params.dot11MeshMaxRetries) ||
7306 nla_put_u8(msg, NL80211_MESHCONF_TTL,
7307 cur_params.dot11MeshTTL) ||
7308 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
7309 cur_params.element_ttl) ||
7310 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
7311 cur_params.auto_open_plinks) ||
7eab0f64
JL
7312 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
7313 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
7314 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
7315 cur_params.dot11MeshHWMPmaxPREQretries) ||
7316 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
7317 cur_params.path_refresh_time) ||
7318 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
7319 cur_params.min_discovery_timeout) ||
7320 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
7321 cur_params.dot11MeshHWMPactivePathTimeout) ||
7322 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
7323 cur_params.dot11MeshHWMPpreqMinInterval) ||
7324 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
7325 cur_params.dot11MeshHWMPperrMinInterval) ||
7326 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
7327 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
7328 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
7329 cur_params.dot11MeshHWMPRootMode) ||
7330 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
7331 cur_params.dot11MeshHWMPRannInterval) ||
7332 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
7333 cur_params.dot11MeshGateAnnouncementProtocol) ||
7334 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
7335 cur_params.dot11MeshForwarding) ||
335d5349 7336 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
7337 cur_params.rssi_threshold) ||
7338 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
7339 cur_params.ht_opmode) ||
7340 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
7341 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
7342 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
7343 cur_params.dot11MeshHWMProotInterval) ||
7344 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
7345 cur_params.dot11MeshHWMPconfirmationInterval) ||
7346 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
7347 cur_params.power_mode) ||
7348 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
7349 cur_params.dot11MeshAwakeWindowDuration) ||
7350 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
01d66fbd
BC
7351 cur_params.plink_timeout) ||
7352 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
e3718a61
LL
7353 cur_params.dot11MeshConnectedToMeshGate) ||
7354 nla_put_u8(msg, NL80211_MESHCONF_NOLEARN,
184eebe6
MT
7355 cur_params.dot11MeshNolearn) ||
7356 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_AS,
7357 cur_params.dot11MeshConnectedToAuthServer))
9360ffd1 7358 goto nla_put_failure;
93da9cc1 7359 nla_nest_end(msg, pinfoattr);
7360 genlmsg_end(msg, hdr);
4c476991 7361 return genlmsg_reply(msg, info);
93da9cc1 7362
3b85875a 7363 nla_put_failure:
efe1cf0c 7364 out:
d080e275 7365 nlmsg_free(msg);
4c476991 7366 return -ENOBUFS;
93da9cc1 7367}
7368
ab0d76f6
JB
7369static const struct nla_policy
7370nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
7371 [NL80211_MESHCONF_RETRY_TIMEOUT] =
7372 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7373 [NL80211_MESHCONF_CONFIRM_TIMEOUT] =
7374 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7375 [NL80211_MESHCONF_HOLDING_TIMEOUT] =
7376 NLA_POLICY_RANGE(NLA_U16, 1, 255),
7377 [NL80211_MESHCONF_MAX_PEER_LINKS] =
7378 NLA_POLICY_RANGE(NLA_U16, 0, 255),
7379 [NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
7380 [NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
7381 [NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
7382 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
7383 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
7384 NLA_POLICY_RANGE(NLA_U32, 1, 255),
93da9cc1 7385 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
7386 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
ab0d76f6 7387 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
93da9cc1 7388 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
7389 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
7390 NLA_POLICY_MIN(NLA_U16, 1),
7391 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
7392 NLA_POLICY_MIN(NLA_U16, 1),
7393 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
7394 NLA_POLICY_MIN(NLA_U16, 1),
7395 [NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
7396 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
7397 NLA_POLICY_MIN(NLA_U16, 1),
7398 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
7399 [NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
7400 [NL80211_MESHCONF_RSSI_THRESHOLD] =
7401 NLA_POLICY_RANGE(NLA_S32, -255, 0),
a4f606ea 7402 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6 7403 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
7404 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
7405 NLA_POLICY_MIN(NLA_U16, 1),
7406 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
7407 NLA_POLICY_MIN(NLA_U16, 1),
7408 [NL80211_MESHCONF_POWER_MODE] =
7409 NLA_POLICY_RANGE(NLA_U32,
7410 NL80211_MESH_POWER_ACTIVE,
7411 NL80211_MESH_POWER_MAX),
3b1c5a53 7412 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 7413 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
01d66fbd 7414 [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
e3718a61 7415 [NL80211_MESHCONF_NOLEARN] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
184eebe6 7416 [NL80211_MESHCONF_CONNECTED_TO_AS] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
93da9cc1 7417};
7418
c80d545d
JC
7419static const struct nla_policy
7420 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 7421 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
7422 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
7423 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 7424 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 7425 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 7426 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
3d7af878
JB
7427 [NL80211_MESH_SETUP_IE] =
7428 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
7429 IEEE80211_MAX_DATA_LEN),
b130e5ce 7430 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
7431};
7432
24bdd9f4 7433static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
7434 struct mesh_config *cfg,
7435 u32 *mask_out)
93da9cc1 7436{
93da9cc1 7437 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 7438 u32 mask = 0;
9757235f 7439 u16 ht_opmode;
93da9cc1 7440
ab0d76f6
JB
7441#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
7442do { \
7443 if (tb[attr]) { \
7444 cfg->param = fn(tb[attr]); \
7445 mask |= BIT((attr) - 1); \
7446 } \
ea54fba2 7447} while (0)
bd90fdcc 7448
24bdd9f4 7449 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 7450 return -EINVAL;
8cb08174 7451 if (nla_parse_nested_deprecated(tb, NL80211_MESHCONF_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy, info->extack))
93da9cc1 7452 return -EINVAL;
7453
93da9cc1 7454 /* This makes sure that there aren't more than 32 mesh config
7455 * parameters (otherwise our bitfield scheme would not work.) */
7456 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
7457
7458 /* Fill in the params struct */
ab0d76f6
JB
7459 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
7460 NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
7461 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
7462 NL80211_MESHCONF_CONFIRM_TIMEOUT,
7463 nla_get_u16);
7464 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
7465 NL80211_MESHCONF_HOLDING_TIMEOUT,
7466 nla_get_u16);
7467 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
7468 NL80211_MESHCONF_MAX_PEER_LINKS,
7469 nla_get_u16);
7470 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
7471 NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
7472 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
7473 NL80211_MESHCONF_TTL, nla_get_u8);
7474 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
7475 NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
7476 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
7477 NL80211_MESHCONF_AUTO_OPEN_PLINKS,
7478 nla_get_u8);
ea54fba2 7479 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
ab0d76f6 7480 mask,
a4f606ea 7481 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
ab0d76f6
JB
7482 nla_get_u32);
7483 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
7484 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
7485 nla_get_u8);
7486 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
7487 NL80211_MESHCONF_PATH_REFRESH_TIME,
7488 nla_get_u32);
7489 if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
7490 (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
7491 return -EINVAL;
7492 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
7493 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
7494 nla_get_u16);
ea54fba2 7495 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
ab0d76f6 7496 mask,
a4f606ea 7497 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
ab0d76f6
JB
7498 nla_get_u32);
7499 if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
7500 (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
7501 cfg->dot11MeshHWMPactivePathTimeout > 65535))
7502 return -EINVAL;
7503 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
ea54fba2 7504 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
ab0d76f6
JB
7505 nla_get_u16);
7506 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
ea54fba2 7507 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
ab0d76f6 7508 nla_get_u16);
93da9cc1 7509 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6 7510 dot11MeshHWMPnetDiameterTraversalTime, mask,
a4f606ea 7511 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
ab0d76f6
JB
7512 nla_get_u16);
7513 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
7514 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
7515 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
7516 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
7517 nla_get_u16);
7518 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
ea54fba2 7519 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
ab0d76f6
JB
7520 nla_get_u8);
7521 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
7522 NL80211_MESHCONF_FORWARDING, nla_get_u8);
7523 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
7524 NL80211_MESHCONF_RSSI_THRESHOLD,
7525 nla_get_s32);
01d66fbd
BC
7526 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
7527 NL80211_MESHCONF_CONNECTED_TO_GATE,
7528 nla_get_u8);
184eebe6
MT
7529 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToAuthServer, mask,
7530 NL80211_MESHCONF_CONNECTED_TO_AS,
7531 nla_get_u8);
9757235f
MH
7532 /*
7533 * Check HT operation mode based on
188f60ab 7534 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
9757235f
MH
7535 */
7536 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
7537 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
7538
7539 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
7540 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
7541 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
7542 return -EINVAL;
7543
188f60ab
BC
7544 /* NON_HT_STA bit is reserved, but some programs set it */
7545 ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
9757235f 7546
9757235f 7547 cfg->ht_opmode = ht_opmode;
fd551bac 7548 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
9757235f 7549 }
728b19e5 7550 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6
JB
7551 dot11MeshHWMPactivePathToRootTimeout, mask,
7552 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
7553 nla_get_u32);
7554 if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
7555 (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
7556 cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
7557 return -EINVAL;
7558 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
7559 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
7560 nla_get_u16);
7561 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
7562 mask,
728b19e5 7563 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
ab0d76f6
JB
7564 nla_get_u16);
7565 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
7566 NL80211_MESHCONF_POWER_MODE, nla_get_u32);
7567 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
7568 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
7569 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
7570 NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
e3718a61
LL
7571 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNolearn, mask,
7572 NL80211_MESHCONF_NOLEARN, nla_get_u8);
bd90fdcc
JB
7573 if (mask_out)
7574 *mask_out = mask;
c80d545d 7575
bd90fdcc
JB
7576 return 0;
7577
7578#undef FILL_IN_MESH_PARAM_IF_SET
7579}
7580
c80d545d
JC
7581static int nl80211_parse_mesh_setup(struct genl_info *info,
7582 struct mesh_setup *setup)
7583{
bb2798d4 7584 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
7585 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
7586
7587 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
7588 return -EINVAL;
8cb08174 7589 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
7590 return -EINVAL;
7591
d299a1f2
JC
7592 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
7593 setup->sync_method =
7594 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
7595 IEEE80211_SYNC_METHOD_VENDOR :
7596 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
7597
c80d545d
JC
7598 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
7599 setup->path_sel_proto =
7600 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
7601 IEEE80211_PATH_PROTOCOL_VENDOR :
7602 IEEE80211_PATH_PROTOCOL_HWMP;
7603
7604 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
7605 setup->path_metric =
7606 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
7607 IEEE80211_PATH_METRIC_VENDOR :
7608 IEEE80211_PATH_METRIC_AIRTIME;
7609
581a8b0f 7610 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 7611 struct nlattr *ieattr =
581a8b0f 7612 tb[NL80211_MESH_SETUP_IE];
581a8b0f
JC
7613 setup->ie = nla_data(ieattr);
7614 setup->ie_len = nla_len(ieattr);
c80d545d 7615 }
bb2798d4
TP
7616 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
7617 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
7618 return -EINVAL;
7619 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
7620 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
7621 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
7622 if (setup->is_secure)
7623 setup->user_mpm = true;
c80d545d 7624
6e16d90b
CT
7625 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
7626 if (!setup->user_mpm)
7627 return -EINVAL;
7628 setup->auth_id =
7629 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
7630 }
7631
c80d545d
JC
7632 return 0;
7633}
7634
24bdd9f4 7635static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 7636 struct genl_info *info)
bd90fdcc
JB
7637{
7638 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7639 struct net_device *dev = info->user_ptr[1];
29cbe68c 7640 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
7641 struct mesh_config cfg;
7642 u32 mask;
7643 int err;
7644
29cbe68c
JB
7645 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
7646 return -EOPNOTSUPP;
7647
24bdd9f4 7648 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
7649 return -EOPNOTSUPP;
7650
24bdd9f4 7651 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
7652 if (err)
7653 return err;
7654
29cbe68c
JB
7655 wdev_lock(wdev);
7656 if (!wdev->mesh_id_len)
7657 err = -ENOLINK;
7658
7659 if (!err)
e35e4d28 7660 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
7661
7662 wdev_unlock(wdev);
7663
7664 return err;
93da9cc1 7665}
7666
ad30ca2c
AN
7667static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
7668 struct sk_buff *msg)
f130347c 7669{
f130347c
LR
7670 struct nlattr *nl_reg_rules;
7671 unsigned int i;
f130347c 7672
458f4f9e
JB
7673 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
7674 (regdom->dfs_region &&
7675 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 7676 goto nla_put_failure;
458f4f9e 7677
ae0be8de 7678 nl_reg_rules = nla_nest_start_noflag(msg, NL80211_ATTR_REG_RULES);
f130347c 7679 if (!nl_reg_rules)
ad30ca2c 7680 goto nla_put_failure;
f130347c 7681
458f4f9e 7682 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
7683 struct nlattr *nl_reg_rule;
7684 const struct ieee80211_reg_rule *reg_rule;
7685 const struct ieee80211_freq_range *freq_range;
7686 const struct ieee80211_power_rule *power_rule;
97524820 7687 unsigned int max_bandwidth_khz;
f130347c 7688
458f4f9e 7689 reg_rule = &regdom->reg_rules[i];
f130347c
LR
7690 freq_range = &reg_rule->freq_range;
7691 power_rule = &reg_rule->power_rule;
7692
ae0be8de 7693 nl_reg_rule = nla_nest_start_noflag(msg, i);
f130347c 7694 if (!nl_reg_rule)
ad30ca2c 7695 goto nla_put_failure;
f130347c 7696
97524820
JD
7697 max_bandwidth_khz = freq_range->max_bandwidth_khz;
7698 if (!max_bandwidth_khz)
7699 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
7700 reg_rule);
7701
9360ffd1
DM
7702 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
7703 reg_rule->flags) ||
7704 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
7705 freq_range->start_freq_khz) ||
7706 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
7707 freq_range->end_freq_khz) ||
7708 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 7709 max_bandwidth_khz) ||
9360ffd1
DM
7710 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
7711 power_rule->max_antenna_gain) ||
7712 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
7713 power_rule->max_eirp) ||
7714 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
7715 reg_rule->dfs_cac_ms))
ad30ca2c 7716 goto nla_put_failure;
f130347c
LR
7717
7718 nla_nest_end(msg, nl_reg_rule);
7719 }
7720
7721 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
7722 return 0;
7723
7724nla_put_failure:
7725 return -EMSGSIZE;
7726}
7727
7728static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
7729{
7730 const struct ieee80211_regdomain *regdom = NULL;
7731 struct cfg80211_registered_device *rdev;
7732 struct wiphy *wiphy = NULL;
7733 struct sk_buff *msg;
7734 void *hdr;
7735
7736 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7737 if (!msg)
7738 return -ENOBUFS;
7739
7740 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7741 NL80211_CMD_GET_REG);
7742 if (!hdr)
7743 goto put_failure;
7744
a05829a7
JB
7745 rtnl_lock();
7746
ad30ca2c 7747 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
7748 bool self_managed;
7749
ad30ca2c
AN
7750 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
7751 if (IS_ERR(rdev)) {
7752 nlmsg_free(msg);
a05829a7 7753 rtnl_unlock();
ad30ca2c
AN
7754 return PTR_ERR(rdev);
7755 }
7756
7757 wiphy = &rdev->wiphy;
1bdd716c
AN
7758 self_managed = wiphy->regulatory_flags &
7759 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
7760 regdom = get_wiphy_regdom(wiphy);
7761
1bdd716c
AN
7762 /* a self-managed-reg device must have a private regdom */
7763 if (WARN_ON(!regdom && self_managed)) {
7764 nlmsg_free(msg);
a05829a7 7765 rtnl_unlock();
1bdd716c
AN
7766 return -EINVAL;
7767 }
7768
ad30ca2c
AN
7769 if (regdom &&
7770 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
7771 goto nla_put_failure;
7772 }
7773
7774 if (!wiphy && reg_last_request_cell_base() &&
7775 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
7776 NL80211_USER_REG_HINT_CELL_BASE))
7777 goto nla_put_failure;
7778
7779 rcu_read_lock();
7780
7781 if (!regdom)
7782 regdom = rcu_dereference(cfg80211_regdomain);
7783
7784 if (nl80211_put_regdom(regdom, msg))
7785 goto nla_put_failure_rcu;
7786
7787 rcu_read_unlock();
f130347c
LR
7788
7789 genlmsg_end(msg, hdr);
a05829a7 7790 rtnl_unlock();
5fe231e8 7791 return genlmsg_reply(msg, info);
f130347c 7792
458f4f9e
JB
7793nla_put_failure_rcu:
7794 rcu_read_unlock();
f130347c 7795nla_put_failure:
a05829a7 7796 rtnl_unlock();
efe1cf0c 7797put_failure:
d080e275 7798 nlmsg_free(msg);
5fe231e8 7799 return -EMSGSIZE;
f130347c
LR
7800}
7801
ad30ca2c
AN
7802static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
7803 u32 seq, int flags, struct wiphy *wiphy,
7804 const struct ieee80211_regdomain *regdom)
7805{
7806 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
7807 NL80211_CMD_GET_REG);
7808
7809 if (!hdr)
7810 return -1;
7811
0a833c29 7812 genl_dump_check_consistent(cb, hdr);
ad30ca2c
AN
7813
7814 if (nl80211_put_regdom(regdom, msg))
7815 goto nla_put_failure;
7816
7817 if (!wiphy && reg_last_request_cell_base() &&
7818 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
7819 NL80211_USER_REG_HINT_CELL_BASE))
7820 goto nla_put_failure;
7821
7822 if (wiphy &&
7823 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
7824 goto nla_put_failure;
7825
1bdd716c
AN
7826 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
7827 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
7828 goto nla_put_failure;
7829
053c095a
JB
7830 genlmsg_end(msg, hdr);
7831 return 0;
ad30ca2c
AN
7832
7833nla_put_failure:
7834 genlmsg_cancel(msg, hdr);
7835 return -EMSGSIZE;
7836}
7837
7838static int nl80211_get_reg_dump(struct sk_buff *skb,
7839 struct netlink_callback *cb)
7840{
7841 const struct ieee80211_regdomain *regdom = NULL;
7842 struct cfg80211_registered_device *rdev;
7843 int err, reg_idx, start = cb->args[2];
7844
7845 rtnl_lock();
7846
7847 if (cfg80211_regdomain && start == 0) {
7848 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
7849 NLM_F_MULTI, NULL,
7850 rtnl_dereference(cfg80211_regdomain));
7851 if (err < 0)
7852 goto out_err;
7853 }
7854
7855 /* the global regdom is idx 0 */
7856 reg_idx = 1;
7857 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
7858 regdom = get_wiphy_regdom(&rdev->wiphy);
7859 if (!regdom)
7860 continue;
7861
7862 if (++reg_idx <= start)
7863 continue;
7864
7865 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
7866 NLM_F_MULTI, &rdev->wiphy, regdom);
7867 if (err < 0) {
7868 reg_idx--;
7869 break;
7870 }
7871 }
7872
7873 cb->args[2] = reg_idx;
7874 err = skb->len;
7875out_err:
7876 rtnl_unlock();
7877 return err;
7878}
7879
b6863036
JB
7880#ifdef CONFIG_CFG80211_CRDA_SUPPORT
7881static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
7882 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
7883 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
7884 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
7885 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
7886 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
7887 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
7888 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
7889};
7890
7891static int parse_reg_rule(struct nlattr *tb[],
7892 struct ieee80211_reg_rule *reg_rule)
7893{
7894 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
7895 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
7896
7897 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
7898 return -EINVAL;
7899 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
7900 return -EINVAL;
7901 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
7902 return -EINVAL;
7903 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
7904 return -EINVAL;
7905 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
7906 return -EINVAL;
7907
7908 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
7909
7910 freq_range->start_freq_khz =
7911 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
7912 freq_range->end_freq_khz =
7913 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
7914 freq_range->max_bandwidth_khz =
7915 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
7916
7917 power_rule->max_eirp =
7918 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
7919
7920 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
7921 power_rule->max_antenna_gain =
7922 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
7923
7924 if (tb[NL80211_ATTR_DFS_CAC_TIME])
7925 reg_rule->dfs_cac_ms =
7926 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
7927
7928 return 0;
7929}
7930
b2e1b302
LR
7931static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
7932{
7933 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
7934 struct nlattr *nl_reg_rule;
ea372c54
JB
7935 char *alpha2;
7936 int rem_reg_rules, r;
391d132c 7937 u32 num_rules = 0, rule_idx = 0;
4c7d3982 7938 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 7939 struct ieee80211_regdomain *rd;
b2e1b302
LR
7940
7941 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
7942 return -EINVAL;
7943
7944 if (!info->attrs[NL80211_ATTR_REG_RULES])
7945 return -EINVAL;
7946
7947 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
7948
8b60b078
LR
7949 if (info->attrs[NL80211_ATTR_DFS_REGION])
7950 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
7951
b2e1b302 7952 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7953 rem_reg_rules) {
b2e1b302
LR
7954 num_rules++;
7955 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 7956 return -EINVAL;
b2e1b302
LR
7957 }
7958
a05829a7
JB
7959 rtnl_lock();
7960 if (!reg_is_valid_request(alpha2)) {
7961 r = -EINVAL;
7962 goto out;
7963 }
e438768f 7964
391d132c 7965 rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
a05829a7
JB
7966 if (!rd) {
7967 r = -ENOMEM;
7968 goto out;
7969 }
b2e1b302
LR
7970
7971 rd->n_reg_rules = num_rules;
7972 rd->alpha2[0] = alpha2[0];
7973 rd->alpha2[1] = alpha2[1];
7974
8b60b078
LR
7975 /*
7976 * Disable DFS master mode if the DFS region was
7977 * not supported or known on this kernel.
7978 */
7979 if (reg_supported_dfs_region(dfs_region))
7980 rd->dfs_region = dfs_region;
7981
b2e1b302 7982 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7983 rem_reg_rules) {
8cb08174
JB
7984 r = nla_parse_nested_deprecated(tb, NL80211_REG_RULE_ATTR_MAX,
7985 nl_reg_rule, reg_rule_policy,
7986 info->extack);
ae811e21
JB
7987 if (r)
7988 goto bad_reg;
b2e1b302
LR
7989 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
7990 if (r)
7991 goto bad_reg;
7992
7993 rule_idx++;
7994
d0e18f83
LR
7995 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
7996 r = -EINVAL;
b2e1b302 7997 goto bad_reg;
d0e18f83 7998 }
b2e1b302
LR
7999 }
8000
a05829a7 8001 r = set_regdom(rd, REGD_SOURCE_CRDA);
06627990 8002 /* set_regdom takes ownership of rd */
a05829a7 8003 rd = NULL;
d2372b31 8004 bad_reg:
b2e1b302 8005 kfree(rd);
a05829a7
JB
8006 out:
8007 rtnl_unlock();
d0e18f83 8008 return r;
b2e1b302 8009}
b6863036 8010#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 8011
83f5e2cf
JB
8012static int validate_scan_freqs(struct nlattr *freqs)
8013{
8014 struct nlattr *attr1, *attr2;
8015 int n_channels = 0, tmp1, tmp2;
8016
d7f13f74
SD
8017 nla_for_each_nested(attr1, freqs, tmp1)
8018 if (nla_len(attr1) != sizeof(u32))
8019 return 0;
8020
83f5e2cf
JB
8021 nla_for_each_nested(attr1, freqs, tmp1) {
8022 n_channels++;
8023 /*
8024 * Some hardware has a limited channel list for
8025 * scanning, and it is pretty much nonsensical
8026 * to scan for a channel twice, so disallow that
8027 * and don't require drivers to check that the
8028 * channel list they get isn't longer than what
8029 * they can scan, as long as they can scan all
8030 * the channels they registered at once.
8031 */
8032 nla_for_each_nested(attr2, freqs, tmp2)
8033 if (attr1 != attr2 &&
8034 nla_get_u32(attr1) == nla_get_u32(attr2))
8035 return 0;
8036 }
8037
8038 return n_channels;
8039}
8040
57fbcce3 8041static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 8042{
57fbcce3 8043 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
8044}
8045
8046static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
8047 struct cfg80211_bss_selection *bss_select)
8048{
8049 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
8050 struct nlattr *nest;
8051 int err;
8052 bool found = false;
8053 int i;
8054
8055 /* only process one nested attribute */
8056 nest = nla_data(nla);
8057 if (!nla_ok(nest, nla_len(nest)))
8058 return -EINVAL;
8059
8cb08174
JB
8060 err = nla_parse_nested_deprecated(attr, NL80211_BSS_SELECT_ATTR_MAX,
8061 nest, nl80211_bss_select_policy,
8062 NULL);
38de03d2
AS
8063 if (err)
8064 return err;
8065
8066 /* only one attribute may be given */
8067 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
8068 if (attr[i]) {
8069 if (found)
8070 return -EINVAL;
8071 found = true;
8072 }
8073 }
8074
8075 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
8076
8077 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
8078 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
8079
8080 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
8081 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
8082 bss_select->param.band_pref =
8083 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
8084 if (!is_band_valid(wiphy, bss_select->param.band_pref))
8085 return -EINVAL;
8086 }
8087
8088 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
8089 struct nl80211_bss_select_rssi_adjust *adj_param;
8090
8091 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
8092 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
8093 bss_select->param.adjust.band = adj_param->band;
8094 bss_select->param.adjust.delta = adj_param->delta;
8095 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
8096 return -EINVAL;
8097 }
8098
8099 /* user-space did not provide behaviour attribute */
8100 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
8101 return -EINVAL;
8102
8103 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
8104 return -EINVAL;
8105
8106 return 0;
8107}
8108
9bb7e0f2
JB
8109int nl80211_parse_random_mac(struct nlattr **attrs,
8110 u8 *mac_addr, u8 *mac_addr_mask)
ad2b26ab
JB
8111{
8112 int i;
8113
8114 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
8115 eth_zero_addr(mac_addr);
8116 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
8117 mac_addr[0] = 0x2;
8118 mac_addr_mask[0] = 0x3;
8119
8120 return 0;
8121 }
8122
8123 /* need both or none */
8124 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
8125 return -EINVAL;
8126
8127 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
8128 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
8129
8130 /* don't allow or configure an mcast address */
8131 if (!is_multicast_ether_addr(mac_addr_mask) ||
8132 is_multicast_ether_addr(mac_addr))
8133 return -EINVAL;
8134
8135 /*
8136 * allow users to pass a MAC address that has bits set outside
8137 * of the mask, but don't bother drivers with having to deal
8138 * with such bits
8139 */
8140 for (i = 0; i < ETH_ALEN; i++)
8141 mac_addr[i] &= mac_addr_mask[i];
8142
8143 return 0;
8144}
8145
34373d12
VT
8146static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
8147{
8148 ASSERT_WDEV_LOCK(wdev);
8149
8150 if (!cfg80211_beaconing_iface_active(wdev))
8151 return true;
8152
8153 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
8154 return true;
8155
8156 return regulatory_pre_cac_allowed(wdev->wiphy);
8157}
8158
db0a4ad8
JB
8159static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
8160 enum nl80211_ext_feature_index feat)
8161{
8162 if (!(flags & flag))
8163 return true;
8164 if (wiphy_ext_feature_isset(wiphy, feat))
8165 return true;
8166 return false;
8167}
8168
2d23d073
RZ
8169static int
8170nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
8171 void *request, struct nlattr **attrs,
8172 bool is_sched_scan)
8173{
8174 u8 *mac_addr, *mac_addr_mask;
8175 u32 *flags;
8176 enum nl80211_feature_flags randomness_flag;
8177
8178 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
8179 return 0;
8180
8181 if (is_sched_scan) {
8182 struct cfg80211_sched_scan_request *req = request;
8183
8184 randomness_flag = wdev ?
8185 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
8186 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
8187 flags = &req->flags;
8188 mac_addr = req->mac_addr;
8189 mac_addr_mask = req->mac_addr_mask;
8190 } else {
8191 struct cfg80211_scan_request *req = request;
8192
8193 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
8194 flags = &req->flags;
8195 mac_addr = req->mac_addr;
8196 mac_addr_mask = req->mac_addr_mask;
8197 }
8198
8199 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
8200
5037a009
SD
8201 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
8202 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
db0a4ad8
JB
8203 !nl80211_check_scan_feat(wiphy, *flags,
8204 NL80211_SCAN_FLAG_LOW_SPAN,
8205 NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
8206 !nl80211_check_scan_feat(wiphy, *flags,
8207 NL80211_SCAN_FLAG_LOW_POWER,
8208 NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
8209 !nl80211_check_scan_feat(wiphy, *flags,
8210 NL80211_SCAN_FLAG_HIGH_ACCURACY,
8211 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
8212 !nl80211_check_scan_feat(wiphy, *flags,
8213 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
8214 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
8215 !nl80211_check_scan_feat(wiphy, *flags,
8216 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
8217 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
8218 !nl80211_check_scan_feat(wiphy, *flags,
8219 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
8220 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
8221 !nl80211_check_scan_feat(wiphy, *flags,
8222 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
2e076f19
JB
8223 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
8224 !nl80211_check_scan_feat(wiphy, *flags,
8225 NL80211_SCAN_FLAG_RANDOM_SN,
8226 NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
8227 !nl80211_check_scan_feat(wiphy, *flags,
8228 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
8229 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
2d23d073
RZ
8230 return -EOPNOTSUPP;
8231
8232 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
8233 int err;
8234
8235 if (!(wiphy->features & randomness_flag) ||
8236 (wdev && wdev->current_bss))
8237 return -EOPNOTSUPP;
8238
8239 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
8240 if (err)
8241 return err;
8242 }
8243
2d23d073
RZ
8244 return 0;
8245}
8246
2a519311
JB
8247static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
8248{
4c476991 8249 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 8250 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 8251 struct cfg80211_scan_request *request;
2032f3b2
TP
8252 struct nlattr *scan_freqs = NULL;
8253 bool scan_freqs_khz = false;
2a519311
JB
8254 struct nlattr *attr;
8255 struct wiphy *wiphy;
83f5e2cf 8256 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 8257 size_t ie_len;
2a519311 8258
79c97e97 8259 wiphy = &rdev->wiphy;
2a519311 8260
cb3b7d87
AB
8261 if (wdev->iftype == NL80211_IFTYPE_NAN)
8262 return -EOPNOTSUPP;
8263
4c476991
JB
8264 if (!rdev->ops->scan)
8265 return -EOPNOTSUPP;
2a519311 8266
83286856
CJ
8267 if (rdev->scan_req || rdev->scan_msg)
8268 return -EBUSY;
2a519311 8269
2032f3b2
TP
8270 if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) {
8271 if (!wiphy_ext_feature_isset(wiphy,
8272 NL80211_EXT_FEATURE_SCAN_FREQ_KHZ))
8273 return -EOPNOTSUPP;
8274 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ];
8275 scan_freqs_khz = true;
8276 } else if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES])
8277 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
8278
8279 if (scan_freqs) {
8280 n_channels = validate_scan_freqs(scan_freqs);
83286856
CJ
8281 if (!n_channels)
8282 return -EINVAL;
2a519311 8283 } else {
bdfbec2d 8284 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
8285 }
8286
8287 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
8288 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
8289 n_ssids++;
8290
83286856
CJ
8291 if (n_ssids > wiphy->max_scan_ssids)
8292 return -EINVAL;
2a519311 8293
70692ad2
JM
8294 if (info->attrs[NL80211_ATTR_IE])
8295 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
8296 else
8297 ie_len = 0;
8298
83286856
CJ
8299 if (ie_len > wiphy->max_scan_ie_len)
8300 return -EINVAL;
18a83659 8301
2a519311 8302 request = kzalloc(sizeof(*request)
a2cd43c5
LC
8303 + sizeof(*request->ssids) * n_ssids
8304 + sizeof(*request->channels) * n_channels
70692ad2 8305 + ie_len, GFP_KERNEL);
83286856
CJ
8306 if (!request)
8307 return -ENOMEM;
2a519311 8308
2a519311 8309 if (n_ssids)
5ba63533 8310 request->ssids = (void *)&request->channels[n_channels];
2a519311 8311 request->n_ssids = n_ssids;
70692ad2 8312 if (ie_len) {
13874e4b 8313 if (n_ssids)
70692ad2
JM
8314 request->ie = (void *)(request->ssids + n_ssids);
8315 else
8316 request->ie = (void *)(request->channels + n_channels);
8317 }
2a519311 8318
584991dc 8319 i = 0;
2032f3b2 8320 if (scan_freqs) {
2a519311 8321 /* user specified, bail out if channel not found */
2032f3b2 8322 nla_for_each_nested(attr, scan_freqs, tmp) {
584991dc 8323 struct ieee80211_channel *chan;
2032f3b2 8324 int freq = nla_get_u32(attr);
584991dc 8325
2032f3b2
TP
8326 if (!scan_freqs_khz)
8327 freq = MHZ_TO_KHZ(freq);
584991dc 8328
2032f3b2 8329 chan = ieee80211_get_channel_khz(wiphy, freq);
584991dc 8330 if (!chan) {
2a519311
JB
8331 err = -EINVAL;
8332 goto out_free;
8333 }
584991dc
JB
8334
8335 /* ignore disabled channels */
8336 if (chan->flags & IEEE80211_CHAN_DISABLED)
8337 continue;
8338
8339 request->channels[i] = chan;
2a519311
JB
8340 i++;
8341 }
8342 } else {
57fbcce3 8343 enum nl80211_band band;
34850ab2 8344
2a519311 8345 /* all channels */
57fbcce3 8346 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 8347 int j;
7a087e74 8348
2a519311
JB
8349 if (!wiphy->bands[band])
8350 continue;
8351 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
8352 struct ieee80211_channel *chan;
8353
8354 chan = &wiphy->bands[band]->channels[j];
8355
8356 if (chan->flags & IEEE80211_CHAN_DISABLED)
8357 continue;
8358
8359 request->channels[i] = chan;
2a519311
JB
8360 i++;
8361 }
8362 }
8363 }
8364
584991dc
JB
8365 if (!i) {
8366 err = -EINVAL;
8367 goto out_free;
8368 }
8369
8370 request->n_channels = i;
8371
34373d12
VT
8372 wdev_lock(wdev);
8373 if (!cfg80211_off_channel_oper_allowed(wdev)) {
8374 struct ieee80211_channel *chan;
8375
8376 if (request->n_channels != 1) {
8377 wdev_unlock(wdev);
8378 err = -EBUSY;
8379 goto out_free;
8380 }
8381
8382 chan = request->channels[0];
8383 if (chan->center_freq != wdev->chandef.chan->center_freq) {
8384 wdev_unlock(wdev);
8385 err = -EBUSY;
8386 goto out_free;
8387 }
8388 }
8389 wdev_unlock(wdev);
8390
2a519311 8391 i = 0;
13874e4b 8392 if (n_ssids) {
2a519311 8393 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 8394 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
8395 err = -EINVAL;
8396 goto out_free;
8397 }
57a27e1d 8398 request->ssids[i].ssid_len = nla_len(attr);
2a519311 8399 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
8400 i++;
8401 }
8402 }
8403
70692ad2
JM
8404 if (info->attrs[NL80211_ATTR_IE]) {
8405 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
8406 memcpy((void *)request->ie,
8407 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
8408 request->ie_len);
8409 }
8410
57fbcce3 8411 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
8412 if (wiphy->bands[i])
8413 request->rates[i] =
8414 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
8415
8416 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
8417 nla_for_each_nested(attr,
8418 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
8419 tmp) {
57fbcce3 8420 enum nl80211_band band = nla_type(attr);
34850ab2 8421
57fbcce3 8422 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
8423 err = -EINVAL;
8424 goto out_free;
8425 }
1b09cd82
FF
8426
8427 if (!wiphy->bands[band])
8428 continue;
8429
34850ab2
JB
8430 err = ieee80211_get_ratemask(wiphy->bands[band],
8431 nla_data(attr),
8432 nla_len(attr),
8433 &request->rates[band]);
8434 if (err)
8435 goto out_free;
8436 }
8437 }
8438
1d76250b 8439 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
1d76250b
AS
8440 request->duration =
8441 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
8442 request->duration_mandatory =
8443 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
8444 }
8445
2d23d073
RZ
8446 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
8447 false);
8448 if (err)
8449 goto out_free;
ed473771 8450
e9f935e3
RM
8451 request->no_cck =
8452 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
8453
2fa436b3
VK
8454 /* Initial implementation used NL80211_ATTR_MAC to set the specific
8455 * BSSID to scan for. This was problematic because that same attribute
8456 * was already used for another purpose (local random MAC address). The
8457 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
8458 * compatibility with older userspace components, also use the
8459 * NL80211_ATTR_MAC value here if it can be determined to be used for
8460 * the specific BSSID use case instead of the random MAC address
8461 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
8462 */
8463 if (info->attrs[NL80211_ATTR_BSSID])
8464 memcpy(request->bssid,
8465 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
8466 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
8467 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
8468 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
8469 ETH_ALEN);
8470 else
8471 eth_broadcast_addr(request->bssid);
8472
fd014284 8473 request->wdev = wdev;
79c97e97 8474 request->wiphy = &rdev->wiphy;
15d6030b 8475 request->scan_start = jiffies;
2a519311 8476
79c97e97 8477 rdev->scan_req = request;
c8cb5b85 8478 err = cfg80211_scan(rdev);
2a519311 8479
504776be
CJ
8480 if (err)
8481 goto out_free;
8482
8483 nl80211_send_scan_start(rdev, wdev);
8484 if (wdev->netdev)
8485 dev_hold(wdev->netdev);
8486
8487 return 0;
8488
2a519311 8489 out_free:
504776be
CJ
8490 rdev->scan_req = NULL;
8491 kfree(request);
3b85875a 8492
2a519311
JB
8493 return err;
8494}
8495
91d3ab46
VK
8496static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
8497{
8498 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8499 struct wireless_dev *wdev = info->user_ptr[1];
8500
8501 if (!rdev->ops->abort_scan)
8502 return -EOPNOTSUPP;
8503
8504 if (rdev->scan_msg)
8505 return 0;
8506
8507 if (!rdev->scan_req)
8508 return -ENOENT;
8509
8510 rdev_abort_scan(rdev, wdev);
8511 return 0;
8512}
8513
3b06d277
AS
8514static int
8515nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
8516 struct cfg80211_sched_scan_request *request,
8517 struct nlattr **attrs)
8518{
8519 int tmp, err, i = 0;
8520 struct nlattr *attr;
8521
8522 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
8523 u32 interval;
8524
8525 /*
8526 * If scan plans are not specified,
5a88de53 8527 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
8528 * case one scan plan will be set with the specified scan
8529 * interval and infinite number of iterations.
8530 */
3b06d277
AS
8531 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
8532 if (!interval)
8533 return -EINVAL;
8534
8535 request->scan_plans[0].interval =
8536 DIV_ROUND_UP(interval, MSEC_PER_SEC);
8537 if (!request->scan_plans[0].interval)
8538 return -EINVAL;
8539
8540 if (request->scan_plans[0].interval >
8541 wiphy->max_sched_scan_plan_interval)
8542 request->scan_plans[0].interval =
8543 wiphy->max_sched_scan_plan_interval;
8544
8545 return 0;
8546 }
8547
8548 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
8549 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
8550
8551 if (WARN_ON(i >= n_plans))
8552 return -EINVAL;
8553
8cb08174
JB
8554 err = nla_parse_nested_deprecated(plan,
8555 NL80211_SCHED_SCAN_PLAN_MAX,
8556 attr, nl80211_plan_policy,
8557 NULL);
3b06d277
AS
8558 if (err)
8559 return err;
8560
8561 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
8562 return -EINVAL;
8563
8564 request->scan_plans[i].interval =
8565 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
8566 if (!request->scan_plans[i].interval ||
8567 request->scan_plans[i].interval >
8568 wiphy->max_sched_scan_plan_interval)
8569 return -EINVAL;
8570
8571 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
8572 request->scan_plans[i].iterations =
8573 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
8574 if (!request->scan_plans[i].iterations ||
8575 (request->scan_plans[i].iterations >
8576 wiphy->max_sched_scan_plan_iterations))
8577 return -EINVAL;
8578 } else if (i < n_plans - 1) {
8579 /*
8580 * All scan plans but the last one must specify
8581 * a finite number of iterations
8582 */
8583 return -EINVAL;
8584 }
8585
8586 i++;
8587 }
8588
8589 /*
8590 * The last scan plan must not specify the number of
8591 * iterations, it is supposed to run infinitely
8592 */
8593 if (request->scan_plans[n_plans - 1].iterations)
8594 return -EINVAL;
8595
8596 return 0;
8597}
8598
1e1b11b6 8599static int
8600nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
8601 struct cfg80211_match_set *match_sets,
8602 struct nlattr *tb_band_rssi,
8603 s32 rssi_thold)
8604{
8605 struct nlattr *attr;
8606 int i, tmp, ret = 0;
8607
8608 if (!wiphy_ext_feature_isset(wiphy,
8609 NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
8610 if (tb_band_rssi)
8611 ret = -EOPNOTSUPP;
8612 else
8613 for (i = 0; i < NUM_NL80211_BANDS; i++)
8614 match_sets->per_band_rssi_thold[i] =
8615 NL80211_SCAN_RSSI_THOLD_OFF;
8616 return ret;
8617 }
8618
8619 for (i = 0; i < NUM_NL80211_BANDS; i++)
8620 match_sets->per_band_rssi_thold[i] = rssi_thold;
8621
8622 nla_for_each_nested(attr, tb_band_rssi, tmp) {
8623 enum nl80211_band band = nla_type(attr);
8624
8625 if (band < 0 || band >= NUM_NL80211_BANDS)
8626 return -EINVAL;
8627
8628 match_sets->per_band_rssi_thold[band] = nla_get_s32(attr);
8629 }
8630
8631 return 0;
8632}
8633
256da02d 8634static struct cfg80211_sched_scan_request *
ad2b26ab 8635nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
aad1e812 8636 struct nlattr **attrs, int max_match_sets)
807f8a8c
LC
8637{
8638 struct cfg80211_sched_scan_request *request;
807f8a8c 8639 struct nlattr *attr;
3b06d277 8640 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 8641 enum nl80211_band band;
807f8a8c 8642 size_t ie_len;
a1f1c21c 8643 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 8644 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 8645
256da02d 8646 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 8647 n_channels = validate_scan_freqs(
256da02d 8648 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 8649 if (!n_channels)
256da02d 8650 return ERR_PTR(-EINVAL);
807f8a8c 8651 } else {
bdfbec2d 8652 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
8653 }
8654
256da02d
LC
8655 if (attrs[NL80211_ATTR_SCAN_SSIDS])
8656 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
8657 tmp)
8658 n_ssids++;
8659
93b6aa69 8660 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 8661 return ERR_PTR(-EINVAL);
807f8a8c 8662
ea73cbce
JB
8663 /*
8664 * First, count the number of 'real' matchsets. Due to an issue with
8665 * the old implementation, matchsets containing only the RSSI attribute
8666 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
8667 * RSSI for all matchsets, rather than their own matchset for reporting
8668 * all APs with a strong RSSI. This is needed to be compatible with
8669 * older userspace that treated a matchset with only the RSSI as the
8670 * global RSSI for all other matchsets - if there are other matchsets.
8671 */
256da02d 8672 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 8673 nla_for_each_nested(attr,
256da02d 8674 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
8675 tmp) {
8676 struct nlattr *rssi;
8677
8cb08174
JB
8678 err = nla_parse_nested_deprecated(tb,
8679 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
8680 attr,
8681 nl80211_match_policy,
8682 NULL);
ea73cbce 8683 if (err)
256da02d 8684 return ERR_PTR(err);
3007e352
AVS
8685
8686 /* SSID and BSSID are mutually exclusive */
8687 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
8688 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
8689 return ERR_PTR(-EINVAL);
8690
ea73cbce 8691 /* add other standalone attributes here */
3007e352
AVS
8692 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
8693 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
ea73cbce
JB
8694 n_match_sets++;
8695 continue;
8696 }
8697 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
8698 if (rssi)
8699 default_match_rssi = nla_get_s32(rssi);
8700 }
8701 }
8702
8703 /* However, if there's no other matchset, add the RSSI one */
8704 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
8705 n_match_sets = 1;
a1f1c21c 8706
aad1e812 8707 if (n_match_sets > max_match_sets)
256da02d 8708 return ERR_PTR(-EINVAL);
a1f1c21c 8709
256da02d
LC
8710 if (attrs[NL80211_ATTR_IE])
8711 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
8712 else
8713 ie_len = 0;
8714
5a865bad 8715 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 8716 return ERR_PTR(-EINVAL);
c10841ca 8717
3b06d277
AS
8718 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
8719 /*
8720 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
8721 * each scan plan already specifies its own interval
8722 */
8723 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
8724 return ERR_PTR(-EINVAL);
8725
8726 nla_for_each_nested(attr,
8727 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
8728 n_plans++;
8729 } else {
8730 /*
8731 * The scan interval attribute is kept for backward
8732 * compatibility. If no scan plans are specified and sched scan
8733 * interval is specified, one scan plan will be set with this
8734 * scan interval and infinite number of iterations.
8735 */
8736 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
8737 return ERR_PTR(-EINVAL);
8738
8739 n_plans = 1;
8740 }
8741
8742 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
8743 return ERR_PTR(-EINVAL);
8744
bf95ecdb 8745 if (!wiphy_ext_feature_isset(
8746 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
8747 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
8748 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
8749 return ERR_PTR(-EINVAL);
8750
807f8a8c 8751 request = kzalloc(sizeof(*request)
a2cd43c5 8752 + sizeof(*request->ssids) * n_ssids
a1f1c21c 8753 + sizeof(*request->match_sets) * n_match_sets
3b06d277 8754 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 8755 + sizeof(*request->channels) * n_channels
807f8a8c 8756 + ie_len, GFP_KERNEL);
256da02d
LC
8757 if (!request)
8758 return ERR_PTR(-ENOMEM);
807f8a8c
LC
8759
8760 if (n_ssids)
8761 request->ssids = (void *)&request->channels[n_channels];
8762 request->n_ssids = n_ssids;
8763 if (ie_len) {
13874e4b 8764 if (n_ssids)
807f8a8c
LC
8765 request->ie = (void *)(request->ssids + n_ssids);
8766 else
8767 request->ie = (void *)(request->channels + n_channels);
8768 }
8769
a1f1c21c
LC
8770 if (n_match_sets) {
8771 if (request->ie)
8772 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 8773 else if (n_ssids)
a1f1c21c
LC
8774 request->match_sets =
8775 (void *)(request->ssids + n_ssids);
8776 else
8777 request->match_sets =
8778 (void *)(request->channels + n_channels);
8779 }
8780 request->n_match_sets = n_match_sets;
8781
3b06d277
AS
8782 if (n_match_sets)
8783 request->scan_plans = (void *)(request->match_sets +
8784 n_match_sets);
8785 else if (request->ie)
8786 request->scan_plans = (void *)(request->ie + ie_len);
8787 else if (n_ssids)
8788 request->scan_plans = (void *)(request->ssids + n_ssids);
8789 else
8790 request->scan_plans = (void *)(request->channels + n_channels);
8791
8792 request->n_scan_plans = n_plans;
8793
807f8a8c 8794 i = 0;
256da02d 8795 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
8796 /* user specified, bail out if channel not found */
8797 nla_for_each_nested(attr,
256da02d 8798 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
8799 tmp) {
8800 struct ieee80211_channel *chan;
8801
8802 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
8803
8804 if (!chan) {
8805 err = -EINVAL;
8806 goto out_free;
8807 }
8808
8809 /* ignore disabled channels */
8810 if (chan->flags & IEEE80211_CHAN_DISABLED)
8811 continue;
8812
8813 request->channels[i] = chan;
8814 i++;
8815 }
8816 } else {
8817 /* all channels */
57fbcce3 8818 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 8819 int j;
7a087e74 8820
807f8a8c
LC
8821 if (!wiphy->bands[band])
8822 continue;
8823 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
8824 struct ieee80211_channel *chan;
8825
8826 chan = &wiphy->bands[band]->channels[j];
8827
8828 if (chan->flags & IEEE80211_CHAN_DISABLED)
8829 continue;
8830
8831 request->channels[i] = chan;
8832 i++;
8833 }
8834 }
8835 }
8836
8837 if (!i) {
8838 err = -EINVAL;
8839 goto out_free;
8840 }
8841
8842 request->n_channels = i;
8843
8844 i = 0;
13874e4b 8845 if (n_ssids) {
256da02d 8846 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 8847 tmp) {
57a27e1d 8848 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
8849 err = -EINVAL;
8850 goto out_free;
8851 }
57a27e1d 8852 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
8853 memcpy(request->ssids[i].ssid, nla_data(attr),
8854 nla_len(attr));
807f8a8c
LC
8855 i++;
8856 }
8857 }
8858
a1f1c21c 8859 i = 0;
256da02d 8860 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 8861 nla_for_each_nested(attr,
256da02d 8862 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 8863 tmp) {
3007e352 8864 struct nlattr *ssid, *bssid, *rssi;
a1f1c21c 8865
8cb08174
JB
8866 err = nla_parse_nested_deprecated(tb,
8867 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
8868 attr,
8869 nl80211_match_policy,
8870 NULL);
ae811e21
JB
8871 if (err)
8872 goto out_free;
4a4ab0d7 8873 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
3007e352 8874 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
d39f3b4f
JB
8875
8876 if (!ssid && !bssid) {
8877 i++;
8878 continue;
8879 }
8880
8881 if (WARN_ON(i >= n_match_sets)) {
8882 /* this indicates a programming error,
8883 * the loop above should have verified
8884 * things properly
8885 */
8886 err = -EINVAL;
8887 goto out_free;
8888 }
8889
8890 if (ssid) {
d39f3b4f
JB
8891 memcpy(request->match_sets[i].ssid.ssid,
8892 nla_data(ssid), nla_len(ssid));
8893 request->match_sets[i].ssid.ssid_len =
8894 nla_len(ssid);
8895 }
cb9abd48 8896 if (bssid)
d39f3b4f
JB
8897 memcpy(request->match_sets[i].bssid,
8898 nla_data(bssid), ETH_ALEN);
3007e352 8899
d39f3b4f
JB
8900 /* special attribute - old implementation w/a */
8901 request->match_sets[i].rssi_thold = default_match_rssi;
8902 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
8903 if (rssi)
ea73cbce 8904 request->match_sets[i].rssi_thold =
d39f3b4f 8905 nla_get_s32(rssi);
1e1b11b6 8906
8907 /* Parse per band RSSI attribute */
8908 err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
8909 &request->match_sets[i],
8910 tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
8911 request->match_sets[i].rssi_thold);
8912 if (err)
8913 goto out_free;
8914
a1f1c21c
LC
8915 i++;
8916 }
ea73cbce
JB
8917
8918 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 8919 if (i == 0 && n_match_sets)
ea73cbce
JB
8920 request->match_sets[0].rssi_thold = default_match_rssi;
8921
8922 request->min_rssi_thold = INT_MAX;
8923 for (i = 0; i < n_match_sets; i++)
8924 request->min_rssi_thold =
8925 min(request->match_sets[i].rssi_thold,
8926 request->min_rssi_thold);
8927 } else {
8928 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
8929 }
8930
9900e484
JB
8931 if (ie_len) {
8932 request->ie_len = ie_len;
807f8a8c 8933 memcpy((void *)request->ie,
256da02d 8934 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
8935 request->ie_len);
8936 }
8937
2d23d073
RZ
8938 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
8939 if (err)
8940 goto out_free;
ed473771 8941
9c748934
LC
8942 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
8943 request->delay =
8944 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
8945
bf95ecdb 8946 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
8947 request->relative_rssi = nla_get_s8(
8948 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
8949 request->relative_rssi_set = true;
8950 }
8951
8952 if (request->relative_rssi_set &&
8953 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
8954 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
8955
8956 rssi_adjust = nla_data(
8957 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
8958 request->rssi_adjust.band = rssi_adjust->band;
8959 request->rssi_adjust.delta = rssi_adjust->delta;
8960 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
8961 err = -EINVAL;
8962 goto out_free;
8963 }
8964 }
8965
3b06d277
AS
8966 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
8967 if (err)
8968 goto out_free;
8969
15d6030b 8970 request->scan_start = jiffies;
807f8a8c 8971
256da02d 8972 return request;
807f8a8c
LC
8973
8974out_free:
8975 kfree(request);
256da02d
LC
8976 return ERR_PTR(err);
8977}
8978
8979static int nl80211_start_sched_scan(struct sk_buff *skb,
8980 struct genl_info *info)
8981{
8982 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8983 struct net_device *dev = info->user_ptr[1];
ad2b26ab 8984 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 8985 struct cfg80211_sched_scan_request *sched_scan_req;
ca986ad9 8986 bool want_multi;
256da02d
LC
8987 int err;
8988
ca986ad9 8989 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
256da02d
LC
8990 return -EOPNOTSUPP;
8991
ca986ad9
AVS
8992 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
8993 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
8994 if (err)
8995 return err;
256da02d 8996
31a60ed1 8997 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
aad1e812
AVS
8998 info->attrs,
8999 rdev->wiphy.max_match_sets);
31a60ed1
JR
9000
9001 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
9002 if (err)
9003 goto out_err;
9004
ca986ad9
AVS
9005 /* leave request id zero for legacy request
9006 * or if driver does not support multi-scheduled scan
9007 */
2fd351a8
DK
9008 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1)
9009 sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
ca986ad9 9010
31a60ed1 9011 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
9012 if (err)
9013 goto out_free;
9014
31a60ed1
JR
9015 sched_scan_req->dev = dev;
9016 sched_scan_req->wiphy = &rdev->wiphy;
9017
93a1e86c
JR
9018 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
9019 sched_scan_req->owner_nlportid = info->snd_portid;
9020
ca986ad9 9021 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
256da02d 9022
96b08fd6 9023 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
256da02d
LC
9024 return 0;
9025
9026out_free:
31a60ed1 9027 kfree(sched_scan_req);
256da02d 9028out_err:
807f8a8c
LC
9029 return err;
9030}
9031
9032static int nl80211_stop_sched_scan(struct sk_buff *skb,
9033 struct genl_info *info)
9034{
ca986ad9 9035 struct cfg80211_sched_scan_request *req;
807f8a8c 9036 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ca986ad9 9037 u64 cookie;
807f8a8c 9038
ca986ad9 9039 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
807f8a8c
LC
9040 return -EOPNOTSUPP;
9041
ca986ad9
AVS
9042 if (info->attrs[NL80211_ATTR_COOKIE]) {
9043 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
9044 return __cfg80211_stop_sched_scan(rdev, cookie, false);
9045 }
9046
9047 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
9048 struct cfg80211_sched_scan_request,
9049 list);
9050 if (!req || req->reqid ||
9051 (req->owner_nlportid &&
9052 req->owner_nlportid != info->snd_portid))
9053 return -ENOENT;
9054
9055 return cfg80211_stop_sched_scan_req(rdev, req, false);
807f8a8c
LC
9056}
9057
04f39047
SW
9058static int nl80211_start_radar_detection(struct sk_buff *skb,
9059 struct genl_info *info)
9060{
9061 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9062 struct net_device *dev = info->user_ptr[1];
9063 struct wireless_dev *wdev = dev->ieee80211_ptr;
13cf6dec 9064 struct wiphy *wiphy = wdev->wiphy;
04f39047 9065 struct cfg80211_chan_def chandef;
55f7435c 9066 enum nl80211_dfs_regions dfs_region;
31559f35 9067 unsigned int cac_time_ms;
04f39047
SW
9068 int err;
9069
13cf6dec 9070 dfs_region = reg_get_dfs_region(wiphy);
55f7435c
LR
9071 if (dfs_region == NL80211_DFS_UNSET)
9072 return -EINVAL;
9073
04f39047
SW
9074 err = nl80211_parse_chandef(rdev, info, &chandef);
9075 if (err)
9076 return err;
9077
ff311bc1
SW
9078 if (netif_carrier_ok(dev))
9079 return -EBUSY;
9080
04f39047
SW
9081 if (wdev->cac_started)
9082 return -EBUSY;
9083
13cf6dec 9084 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
04f39047
SW
9085 if (err < 0)
9086 return err;
9087
9088 if (err == 0)
9089 return -EINVAL;
9090
13cf6dec 9091 if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
04f39047
SW
9092 return -EINVAL;
9093
13cf6dec
DL
9094 /* CAC start is offloaded to HW and can't be started manually */
9095 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
9096 return -EOPNOTSUPP;
9097
04f39047
SW
9098 if (!rdev->ops->start_radar_detection)
9099 return -EOPNOTSUPP;
9100
31559f35
JD
9101 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
9102 if (WARN_ON(!cac_time_ms))
9103 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
9104
a1056b1b 9105 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 9106 if (!err) {
9e0e2961 9107 wdev->chandef = chandef;
04f39047
SW
9108 wdev->cac_started = true;
9109 wdev->cac_start_time = jiffies;
31559f35 9110 wdev->cac_time_ms = cac_time_ms;
04f39047 9111 }
04f39047
SW
9112 return err;
9113}
9114
30c63115
S
9115static int nl80211_notify_radar_detection(struct sk_buff *skb,
9116 struct genl_info *info)
9117{
9118 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9119 struct net_device *dev = info->user_ptr[1];
9120 struct wireless_dev *wdev = dev->ieee80211_ptr;
9121 struct wiphy *wiphy = wdev->wiphy;
9122 struct cfg80211_chan_def chandef;
9123 enum nl80211_dfs_regions dfs_region;
9124 int err;
9125
9126 dfs_region = reg_get_dfs_region(wiphy);
9127 if (dfs_region == NL80211_DFS_UNSET) {
9128 GENL_SET_ERR_MSG(info,
9129 "DFS Region is not set. Unexpected Radar indication");
9130 return -EINVAL;
9131 }
9132
9133 err = nl80211_parse_chandef(rdev, info, &chandef);
9134 if (err) {
9135 GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
9136 return err;
9137 }
9138
9139 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
9140 if (err < 0) {
9141 GENL_SET_ERR_MSG(info, "chandef is invalid");
9142 return err;
9143 }
9144
9145 if (err == 0) {
9146 GENL_SET_ERR_MSG(info,
9147 "Unexpected Radar indication for chandef/iftype");
9148 return -EINVAL;
9149 }
9150
9151 /* Do not process this notification if radar is already detected
9152 * by kernel on this channel, and return success.
9153 */
9154 if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
9155 return 0;
9156
9157 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
9158
9159 cfg80211_sched_dfs_chan_update(rdev);
9160
a680fe46 9161 rdev->radar_chandef = chandef;
30c63115
S
9162
9163 /* Propagate this notification to other radios as well */
9164 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
9165
9166 return 0;
9167}
9168
16ef1fe2
SW
9169static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
9170{
9171 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9172 struct net_device *dev = info->user_ptr[1];
9173 struct wireless_dev *wdev = dev->ieee80211_ptr;
9174 struct cfg80211_csa_settings params;
a05829a7 9175 struct nlattr **csa_attrs = NULL;
16ef1fe2 9176 int err;
ee4bc9e7 9177 bool need_new_beacon = false;
8d9de16f 9178 bool need_handle_dfs_flag = true;
9a774c78 9179 int len, i;
252e07ca 9180 u32 cs_count;
16ef1fe2
SW
9181
9182 if (!rdev->ops->channel_switch ||
9183 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
9184 return -EOPNOTSUPP;
9185
ee4bc9e7
SW
9186 switch (dev->ieee80211_ptr->iftype) {
9187 case NL80211_IFTYPE_AP:
9188 case NL80211_IFTYPE_P2P_GO:
9189 need_new_beacon = true;
8d9de16f
BB
9190 /* For all modes except AP the handle_dfs flag needs to be
9191 * supplied to tell the kernel that userspace will handle radar
9192 * events when they happen. Otherwise a switch to a channel
9193 * requiring DFS will be rejected.
9194 */
9195 need_handle_dfs_flag = false;
ee4bc9e7
SW
9196
9197 /* useless if AP is not running */
9198 if (!wdev->beacon_interval)
1ff79dfa 9199 return -ENOTCONN;
ee4bc9e7
SW
9200 break;
9201 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
9202 if (!wdev->ssid_len)
9203 return -ENOTCONN;
9204 break;
c6da674a 9205 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
9206 if (!wdev->mesh_id_len)
9207 return -ENOTCONN;
ee4bc9e7
SW
9208 break;
9209 default:
16ef1fe2 9210 return -EOPNOTSUPP;
ee4bc9e7 9211 }
16ef1fe2
SW
9212
9213 memset(&params, 0, sizeof(params));
c177db2d 9214 params.beacon_csa.ftm_responder = -1;
16ef1fe2
SW
9215
9216 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
9217 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
9218 return -EINVAL;
9219
9220 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 9221 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
9222 return -EINVAL;
9223
252e07ca
LC
9224 /* Even though the attribute is u32, the specification says
9225 * u8, so let's make sure we don't overflow.
9226 */
9227 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
9228 if (cs_count > 255)
9229 return -EINVAL;
9230
9231 params.count = cs_count;
16ef1fe2 9232
ee4bc9e7
SW
9233 if (!need_new_beacon)
9234 goto skip_beacons;
9235
81e54d08 9236 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
16ef1fe2
SW
9237 if (err)
9238 return err;
9239
a05829a7
JB
9240 csa_attrs = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*csa_attrs),
9241 GFP_KERNEL);
9242 if (!csa_attrs)
9243 return -ENOMEM;
9244
8cb08174
JB
9245 err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
9246 info->attrs[NL80211_ATTR_CSA_IES],
9247 nl80211_policy, info->extack);
16ef1fe2 9248 if (err)
a05829a7 9249 goto free;
16ef1fe2 9250
81e54d08 9251 err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
16ef1fe2 9252 if (err)
a05829a7 9253 goto free;
16ef1fe2 9254
a05829a7
JB
9255 if (!csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
9256 err = -EINVAL;
9257 goto free;
9258 }
16ef1fe2 9259
00c207ed 9260 len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
a05829a7
JB
9261 if (!len || (len % sizeof(u16))) {
9262 err = -EINVAL;
9263 goto free;
9264 }
16ef1fe2 9265
9a774c78
AO
9266 params.n_counter_offsets_beacon = len / sizeof(u16);
9267 if (rdev->wiphy.max_num_csa_counters &&
9268 (params.n_counter_offsets_beacon >
a05829a7
JB
9269 rdev->wiphy.max_num_csa_counters)) {
9270 err = -EINVAL;
9271 goto free;
9272 }
16ef1fe2 9273
9a774c78 9274 params.counter_offsets_beacon =
00c207ed 9275 nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
9a774c78
AO
9276
9277 /* sanity checks - counters should fit and be the same */
9278 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
9279 u16 offset = params.counter_offsets_beacon[i];
9280
a05829a7
JB
9281 if (offset >= params.beacon_csa.tail_len) {
9282 err = -EINVAL;
9283 goto free;
9284 }
9a774c78 9285
a05829a7
JB
9286 if (params.beacon_csa.tail[offset] != params.count) {
9287 err = -EINVAL;
9288 goto free;
9289 }
9a774c78
AO
9290 }
9291
00c207ed
JC
9292 if (csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
9293 len = nla_len(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
a05829a7
JB
9294 if (!len || (len % sizeof(u16))) {
9295 err = -EINVAL;
9296 goto free;
9297 }
16ef1fe2 9298
9a774c78
AO
9299 params.n_counter_offsets_presp = len / sizeof(u16);
9300 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 9301 (params.n_counter_offsets_presp >
a05829a7
JB
9302 rdev->wiphy.max_num_csa_counters)) {
9303 err = -EINVAL;
9304 goto free;
9305 }
9a774c78
AO
9306
9307 params.counter_offsets_presp =
00c207ed 9308 nla_data(csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
9a774c78
AO
9309
9310 /* sanity checks - counters should fit and be the same */
9311 for (i = 0; i < params.n_counter_offsets_presp; i++) {
9312 u16 offset = params.counter_offsets_presp[i];
9313
a05829a7
JB
9314 if (offset >= params.beacon_csa.probe_resp_len) {
9315 err = -EINVAL;
9316 goto free;
9317 }
9a774c78
AO
9318
9319 if (params.beacon_csa.probe_resp[offset] !=
a05829a7
JB
9320 params.count) {
9321 err = -EINVAL;
9322 goto free;
9323 }
9a774c78 9324 }
16ef1fe2
SW
9325 }
9326
ee4bc9e7 9327skip_beacons:
16ef1fe2
SW
9328 err = nl80211_parse_chandef(rdev, info, &params.chandef);
9329 if (err)
a05829a7 9330 goto free;
16ef1fe2 9331
923b352f 9332 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
a05829a7
JB
9333 wdev->iftype)) {
9334 err = -EINVAL;
9335 goto free;
9336 }
16ef1fe2 9337
2beb6dab
LC
9338 err = cfg80211_chandef_dfs_required(wdev->wiphy,
9339 &params.chandef,
9340 wdev->iftype);
9341 if (err < 0)
a05829a7 9342 goto free;
2beb6dab 9343
8d9de16f 9344 if (err > 0) {
2beb6dab 9345 params.radar_required = true;
8d9de16f
BB
9346 if (need_handle_dfs_flag &&
9347 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
a05829a7
JB
9348 err = -EINVAL;
9349 goto free;
8d9de16f
BB
9350 }
9351 }
16ef1fe2 9352
16ef1fe2
SW
9353 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
9354 params.block_tx = true;
9355
c56589ed
SW
9356 wdev_lock(wdev);
9357 err = rdev_channel_switch(rdev, dev, &params);
9358 wdev_unlock(wdev);
9359
a05829a7
JB
9360free:
9361 kfree(csa_attrs);
c56589ed 9362 return err;
16ef1fe2
SW
9363}
9364
9720bb3a
JB
9365static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
9366 u32 seq, int flags,
2a519311 9367 struct cfg80211_registered_device *rdev,
48ab905d
JB
9368 struct wireless_dev *wdev,
9369 struct cfg80211_internal_bss *intbss)
2a519311 9370{
48ab905d 9371 struct cfg80211_bss *res = &intbss->pub;
9caf0364 9372 const struct cfg80211_bss_ies *ies;
2a519311
JB
9373 void *hdr;
9374 struct nlattr *bss;
48ab905d
JB
9375
9376 ASSERT_WDEV_LOCK(wdev);
2a519311 9377
15e47304 9378 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
9379 NL80211_CMD_NEW_SCAN_RESULTS);
9380 if (!hdr)
9381 return -1;
9382
0a833c29 9383 genl_dump_check_consistent(cb, hdr);
9720bb3a 9384
97990a06
JB
9385 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
9386 goto nla_put_failure;
9387 if (wdev->netdev &&
9360ffd1
DM
9388 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
9389 goto nla_put_failure;
2dad624e
ND
9390 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
9391 NL80211_ATTR_PAD))
97990a06 9392 goto nla_put_failure;
2a519311 9393
ae0be8de 9394 bss = nla_nest_start_noflag(msg, NL80211_ATTR_BSS);
2a519311
JB
9395 if (!bss)
9396 goto nla_put_failure;
9360ffd1 9397 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 9398 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 9399 goto nla_put_failure;
9caf0364
JB
9400
9401 rcu_read_lock();
0e227084
JB
9402 /* indicate whether we have probe response data or not */
9403 if (rcu_access_pointer(res->proberesp_ies) &&
9404 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
9405 goto fail_unlock_rcu;
9406
9407 /* this pointer prefers to be pointed to probe response data
9408 * but is always valid
9409 */
9caf0364 9410 ies = rcu_dereference(res->ies);
8cef2c9d 9411 if (ies) {
2dad624e
ND
9412 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
9413 NL80211_BSS_PAD))
8cef2c9d 9414 goto fail_unlock_rcu;
8cef2c9d
JB
9415 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
9416 ies->len, ies->data))
9417 goto fail_unlock_rcu;
9caf0364 9418 }
0e227084
JB
9419
9420 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 9421 ies = rcu_dereference(res->beacon_ies);
0e227084 9422 if (ies && ies->from_beacon) {
2dad624e
ND
9423 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
9424 NL80211_BSS_PAD))
8cef2c9d
JB
9425 goto fail_unlock_rcu;
9426 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
9427 ies->len, ies->data))
9428 goto fail_unlock_rcu;
9caf0364
JB
9429 }
9430 rcu_read_unlock();
9431
9360ffd1
DM
9432 if (res->beacon_interval &&
9433 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
9434 goto nla_put_failure;
9435 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
9436 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
942ba88b
TP
9437 nla_put_u32(msg, NL80211_BSS_FREQUENCY_OFFSET,
9438 res->channel->freq_offset) ||
dcd6eac1 9439 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
9440 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
9441 jiffies_to_msecs(jiffies - intbss->ts)))
9442 goto nla_put_failure;
2a519311 9443
1d76250b
AS
9444 if (intbss->parent_tsf &&
9445 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
9446 intbss->parent_tsf, NL80211_BSS_PAD) ||
9447 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
9448 intbss->parent_bssid)))
9449 goto nla_put_failure;
9450
6e19bc4b 9451 if (intbss->ts_boottime &&
2dad624e
ND
9452 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
9453 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
9454 goto nla_put_failure;
9455
983dafaa
SD
9456 if (!nl80211_put_signal(msg, intbss->pub.chains,
9457 intbss->pub.chain_signal,
9458 NL80211_BSS_CHAIN_SIGNAL))
9459 goto nla_put_failure;
9460
77965c97 9461 switch (rdev->wiphy.signal_type) {
2a519311 9462 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
9463 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
9464 goto nla_put_failure;
2a519311
JB
9465 break;
9466 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
9467 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
9468 goto nla_put_failure;
2a519311
JB
9469 break;
9470 default:
9471 break;
9472 }
9473
48ab905d 9474 switch (wdev->iftype) {
074ac8df 9475 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 9476 case NL80211_IFTYPE_STATION:
9360ffd1
DM
9477 if (intbss == wdev->current_bss &&
9478 nla_put_u32(msg, NL80211_BSS_STATUS,
9479 NL80211_BSS_STATUS_ASSOCIATED))
9480 goto nla_put_failure;
48ab905d
JB
9481 break;
9482 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
9483 if (intbss == wdev->current_bss &&
9484 nla_put_u32(msg, NL80211_BSS_STATUS,
9485 NL80211_BSS_STATUS_IBSS_JOINED))
9486 goto nla_put_failure;
48ab905d
JB
9487 break;
9488 default:
9489 break;
9490 }
9491
2a519311
JB
9492 nla_nest_end(msg, bss);
9493
053c095a
JB
9494 genlmsg_end(msg, hdr);
9495 return 0;
2a519311 9496
8cef2c9d
JB
9497 fail_unlock_rcu:
9498 rcu_read_unlock();
2a519311
JB
9499 nla_put_failure:
9500 genlmsg_cancel(msg, hdr);
9501 return -EMSGSIZE;
9502}
9503
97990a06 9504static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 9505{
48ab905d 9506 struct cfg80211_registered_device *rdev;
2a519311 9507 struct cfg80211_internal_bss *scan;
48ab905d 9508 struct wireless_dev *wdev;
97990a06 9509 int start = cb->args[2], idx = 0;
2a519311
JB
9510 int err;
9511
5297c65c 9512 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
a05829a7 9513 if (err)
67748893 9514 return err;
a05829a7
JB
9515 /* nl80211_prepare_wdev_dump acquired it in the successful case */
9516 __acquire(&rdev->wiphy.mtx);
2a519311 9517
48ab905d
JB
9518 wdev_lock(wdev);
9519 spin_lock_bh(&rdev->bss_lock);
d1e23c94
DK
9520
9521 /*
9522 * dump_scan will be called multiple times to break up the scan results
9523 * into multiple messages. It is unlikely that any more bss-es will be
9524 * expired after the first call, so only call only call this on the
9525 * first dump_scan invocation.
9526 */
9527 if (start == 0)
9528 cfg80211_bss_expire(rdev);
48ab905d 9529
9720bb3a
JB
9530 cb->seq = rdev->bss_generation;
9531
48ab905d 9532 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
9533 if (++idx <= start)
9534 continue;
9720bb3a 9535 if (nl80211_send_bss(skb, cb,
2a519311 9536 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 9537 rdev, wdev, scan) < 0) {
2a519311 9538 idx--;
67748893 9539 break;
2a519311
JB
9540 }
9541 }
9542
48ab905d
JB
9543 spin_unlock_bh(&rdev->bss_lock);
9544 wdev_unlock(wdev);
2a519311 9545
97990a06 9546 cb->args[2] = idx;
a05829a7 9547 wiphy_unlock(&rdev->wiphy);
2a519311 9548
67748893 9549 return skb->len;
2a519311
JB
9550}
9551
15e47304 9552static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
9553 int flags, struct net_device *dev,
9554 bool allow_radio_stats,
9555 struct survey_info *survey)
61fa713c
HS
9556{
9557 void *hdr;
9558 struct nlattr *infoattr;
9559
11f78ac3
JB
9560 /* skip radio stats if userspace didn't request them */
9561 if (!survey->channel && !allow_radio_stats)
9562 return 0;
9563
15e47304 9564 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
9565 NL80211_CMD_NEW_SURVEY_RESULTS);
9566 if (!hdr)
9567 return -ENOMEM;
9568
9360ffd1
DM
9569 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9570 goto nla_put_failure;
61fa713c 9571
ae0be8de 9572 infoattr = nla_nest_start_noflag(msg, NL80211_ATTR_SURVEY_INFO);
61fa713c
HS
9573 if (!infoattr)
9574 goto nla_put_failure;
9575
11f78ac3
JB
9576 if (survey->channel &&
9577 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
9578 survey->channel->center_freq))
9579 goto nla_put_failure;
58ef7c1b
TP
9580
9581 if (survey->channel && survey->channel->freq_offset &&
9582 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY_OFFSET,
9583 survey->channel->freq_offset))
9584 goto nla_put_failure;
9360ffd1
DM
9585
9586 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
9587 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
9588 goto nla_put_failure;
9589 if ((survey->filled & SURVEY_INFO_IN_USE) &&
9590 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
9591 goto nla_put_failure;
4ed20beb 9592 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
9593 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
9594 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 9595 goto nla_put_failure;
4ed20beb 9596 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
9597 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
9598 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9599 goto nla_put_failure;
4ed20beb 9600 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
9601 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
9602 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 9603 goto nla_put_failure;
4ed20beb 9604 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
9605 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
9606 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9607 goto nla_put_failure;
4ed20beb 9608 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
9609 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
9610 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 9611 goto nla_put_failure;
052536ab 9612 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
9613 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
9614 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 9615 goto nla_put_failure;
c8cd6e7f
FF
9616 if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) &&
9617 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX,
9618 survey->time_bss_rx, NL80211_SURVEY_INFO_PAD))
9619 goto nla_put_failure;
61fa713c
HS
9620
9621 nla_nest_end(msg, infoattr);
9622
053c095a
JB
9623 genlmsg_end(msg, hdr);
9624 return 0;
61fa713c
HS
9625
9626 nla_put_failure:
9627 genlmsg_cancel(msg, hdr);
9628 return -EMSGSIZE;
9629}
9630
11f78ac3 9631static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 9632{
50508d94 9633 struct nlattr **attrbuf;
61fa713c 9634 struct survey_info survey;
1b8ec87a 9635 struct cfg80211_registered_device *rdev;
97990a06
JB
9636 struct wireless_dev *wdev;
9637 int survey_idx = cb->args[2];
61fa713c 9638 int res;
11f78ac3 9639 bool radio_stats;
61fa713c 9640
50508d94
JB
9641 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
9642 if (!attrbuf)
9643 return -ENOMEM;
9644
5297c65c 9645 res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
a05829a7
JB
9646 if (res) {
9647 kfree(attrbuf);
9648 return res;
9649 }
9650 /* nl80211_prepare_wdev_dump acquired it in the successful case */
9651 __acquire(&rdev->wiphy.mtx);
61fa713c 9652
11f78ac3 9653 /* prepare_wdev_dump parsed the attributes */
c90c39da 9654 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 9655
97990a06
JB
9656 if (!wdev->netdev) {
9657 res = -EINVAL;
9658 goto out_err;
9659 }
9660
1b8ec87a 9661 if (!rdev->ops->dump_survey) {
61fa713c
HS
9662 res = -EOPNOTSUPP;
9663 goto out_err;
9664 }
9665
9666 while (1) {
1b8ec87a 9667 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
9668 if (res == -ENOENT)
9669 break;
9670 if (res)
9671 goto out_err;
9672
11f78ac3
JB
9673 /* don't send disabled channels, but do send non-channel data */
9674 if (survey.channel &&
9675 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
9676 survey_idx++;
9677 continue;
9678 }
9679
61fa713c 9680 if (nl80211_send_survey(skb,
15e47304 9681 NETLINK_CB(cb->skb).portid,
61fa713c 9682 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 9683 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
9684 goto out;
9685 survey_idx++;
9686 }
9687
9688 out:
97990a06 9689 cb->args[2] = survey_idx;
61fa713c
HS
9690 res = skb->len;
9691 out_err:
50508d94 9692 kfree(attrbuf);
a05829a7 9693 wiphy_unlock(&rdev->wiphy);
61fa713c
HS
9694 return res;
9695}
9696
b23aa676
SO
9697static bool nl80211_valid_wpa_versions(u32 wpa_versions)
9698{
9699 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
cc3e14c2
CHH
9700 NL80211_WPA_VERSION_2 |
9701 NL80211_WPA_VERSION_3));
b23aa676
SO
9702}
9703
636a5d36
JM
9704static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
9705{
4c476991
JB
9706 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9707 struct net_device *dev = info->user_ptr[1];
19957bb3 9708 struct ieee80211_channel *chan;
11b6b5a4
JM
9709 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
9710 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 9711 enum nl80211_auth_type auth_type;
fffd0934 9712 struct key_parse key;
d5cdfacb 9713 bool local_state_change;
942ba88b 9714 u32 freq;
636a5d36 9715
f4a11bb0
JB
9716 if (!info->attrs[NL80211_ATTR_MAC])
9717 return -EINVAL;
9718
1778092e
JM
9719 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
9720 return -EINVAL;
9721
19957bb3
JB
9722 if (!info->attrs[NL80211_ATTR_SSID])
9723 return -EINVAL;
9724
9725 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
9726 return -EINVAL;
9727
fffd0934
JB
9728 err = nl80211_parse_key(info, &key);
9729 if (err)
9730 return err;
9731
9732 if (key.idx >= 0) {
e31b8213
JB
9733 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
9734 return -EINVAL;
fffd0934
JB
9735 if (!key.p.key || !key.p.key_len)
9736 return -EINVAL;
9737 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
9738 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
9739 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
9740 key.p.key_len != WLAN_KEY_LEN_WEP104))
9741 return -EINVAL;
b6b5555b 9742 if (key.idx > 3)
fffd0934
JB
9743 return -EINVAL;
9744 } else {
9745 key.p.key_len = 0;
9746 key.p.key = NULL;
9747 }
9748
afea0b7a
JB
9749 if (key.idx >= 0) {
9750 int i;
9751 bool ok = false;
7a087e74 9752
afea0b7a
JB
9753 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
9754 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
9755 ok = true;
9756 break;
9757 }
9758 }
4c476991
JB
9759 if (!ok)
9760 return -EINVAL;
afea0b7a
JB
9761 }
9762
4c476991
JB
9763 if (!rdev->ops->auth)
9764 return -EOPNOTSUPP;
636a5d36 9765
074ac8df 9766 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9767 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9768 return -EOPNOTSUPP;
eec60b03 9769
19957bb3 9770 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
942ba88b
TP
9771 freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
9772 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
9773 freq +=
9774 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
9775
9776 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
664834de 9777 if (!chan)
4c476991 9778 return -EINVAL;
636a5d36 9779
19957bb3
JB
9780 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9781 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
9782
9783 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
9784 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9785 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9786 }
9787
19957bb3 9788 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 9789 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 9790 return -EINVAL;
636a5d36 9791
63181060
JM
9792 if ((auth_type == NL80211_AUTHTYPE_SAE ||
9793 auth_type == NL80211_AUTHTYPE_FILS_SK ||
9794 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
9795 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 9796 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
9797 return -EINVAL;
9798
11b6b5a4 9799 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
9800 if (auth_type != NL80211_AUTHTYPE_SAE &&
9801 auth_type != NL80211_AUTHTYPE_FILS_SK &&
9802 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
9803 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 9804 return -EINVAL;
11b6b5a4
JM
9805 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
9806 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e
JM
9807 }
9808
d5cdfacb
JM
9809 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
9810
95de817b
JB
9811 /*
9812 * Since we no longer track auth state, ignore
9813 * requests to only change local state.
9814 */
9815 if (local_state_change)
9816 return 0;
9817
91bf9b26
JB
9818 wdev_lock(dev->ieee80211_ptr);
9819 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
9820 ssid, ssid_len, ie, ie_len,
9821 key.p.key, key.p.key_len, key.idx,
11b6b5a4 9822 auth_data, auth_data_len);
91bf9b26
JB
9823 wdev_unlock(dev->ieee80211_ptr);
9824 return err;
636a5d36
JM
9825}
9826
64bf3d4b
DK
9827static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
9828 struct genl_info *info)
9829{
9830 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9831 GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
9832 return -EINVAL;
9833 }
9834
9835 if (!rdev->ops->tx_control_port ||
9836 !wiphy_ext_feature_isset(&rdev->wiphy,
9837 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
9838 return -EOPNOTSUPP;
9839
9840 return 0;
9841}
9842
c0692b8f
JB
9843static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
9844 struct genl_info *info,
3dc27d25
JB
9845 struct cfg80211_crypto_settings *settings,
9846 int cipher_limit)
b23aa676 9847{
c0b2bbd8
JB
9848 memset(settings, 0, sizeof(*settings));
9849
b23aa676
SO
9850 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
9851
c0692b8f
JB
9852 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
9853 u16 proto;
7a087e74 9854
c0692b8f
JB
9855 proto = nla_get_u16(
9856 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
9857 settings->control_port_ethertype = cpu_to_be16(proto);
9858 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
9859 proto != ETH_P_PAE)
9860 return -EINVAL;
9861 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
9862 settings->control_port_no_encrypt = true;
9863 } else
9864 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
9865
64bf3d4b
DK
9866 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
9867 int r = validate_pae_over_nl80211(rdev, info);
9868
9869 if (r < 0)
9870 return r;
9871
9872 settings->control_port_over_nl80211 = true;
7f3f96ce
MT
9873
9874 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH])
9875 settings->control_port_no_preauth = true;
64bf3d4b
DK
9876 }
9877
b23aa676
SO
9878 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
9879 void *data;
9880 int len, i;
9881
9882 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
9883 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
9884 settings->n_ciphers_pairwise = len / sizeof(u32);
9885
9886 if (len % sizeof(u32))
9887 return -EINVAL;
9888
3dc27d25 9889 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
9890 return -EINVAL;
9891
9892 memcpy(settings->ciphers_pairwise, data, len);
9893
9894 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
9895 if (!cfg80211_supported_cipher_suite(
9896 &rdev->wiphy,
b23aa676
SO
9897 settings->ciphers_pairwise[i]))
9898 return -EINVAL;
9899 }
9900
9901 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
9902 settings->cipher_group =
9903 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
9904 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
9905 settings->cipher_group))
b23aa676
SO
9906 return -EINVAL;
9907 }
9908
9909 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
9910 settings->wpa_versions =
9911 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
9912 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
9913 return -EINVAL;
9914 }
9915
9916 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
9917 void *data;
6d30240e 9918 int len;
b23aa676
SO
9919
9920 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
9921 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
9922 settings->n_akm_suites = len / sizeof(u32);
9923
9924 if (len % sizeof(u32))
9925 return -EINVAL;
9926
1b9ca027
JM
9927 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
9928 return -EINVAL;
9929
b23aa676 9930 memcpy(settings->akm_suites, data, len);
b23aa676
SO
9931 }
9932
91b5ab62
EP
9933 if (info->attrs[NL80211_ATTR_PMK]) {
9934 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
9935 return -EINVAL;
9936 if (!wiphy_ext_feature_isset(&rdev->wiphy,
f9662274
CHH
9937 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) &&
9938 !wiphy_ext_feature_isset(&rdev->wiphy,
9939 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
91b5ab62
EP
9940 return -EINVAL;
9941 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
9942 }
9943
26f7044e
CHH
9944 if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
9945 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2831a631
CHH
9946 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
9947 !wiphy_ext_feature_isset(&rdev->wiphy,
9948 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP))
26f7044e
CHH
9949 return -EINVAL;
9950 settings->sae_pwd =
9951 nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
9952 settings->sae_pwd_len =
9953 nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
9954 }
9955
9f0ffa41
RD
9956 if (info->attrs[NL80211_ATTR_SAE_PWE])
9957 settings->sae_pwe =
9958 nla_get_u8(info->attrs[NL80211_ATTR_SAE_PWE]);
9959 else
9960 settings->sae_pwe = NL80211_SAE_PWE_UNSPECIFIED;
9961
b23aa676
SO
9962 return 0;
9963}
9964
636a5d36
JM
9965static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
9966{
4c476991
JB
9967 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9968 struct net_device *dev = info->user_ptr[1];
f444de05 9969 struct ieee80211_channel *chan;
f62fab73
JB
9970 struct cfg80211_assoc_request req = {};
9971 const u8 *bssid, *ssid;
9972 int err, ssid_len = 0;
942ba88b 9973 u32 freq;
636a5d36 9974
bad29297
AZ
9975 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9976 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9977 return -EPERM;
9978
f4a11bb0 9979 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
9980 !info->attrs[NL80211_ATTR_SSID] ||
9981 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
9982 return -EINVAL;
9983
4c476991
JB
9984 if (!rdev->ops->assoc)
9985 return -EOPNOTSUPP;
636a5d36 9986
074ac8df 9987 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9988 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9989 return -EOPNOTSUPP;
eec60b03 9990
19957bb3 9991 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 9992
942ba88b
TP
9993 freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
9994 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
9995 freq +=
9996 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
9997 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
664834de 9998 if (!chan)
4c476991 9999 return -EINVAL;
636a5d36 10000
19957bb3
JB
10001 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10002 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
10003
10004 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
10005 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10006 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10007 }
10008
dc6382ce 10009 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 10010 enum nl80211_mfp mfp =
dc6382ce 10011 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 10012 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 10013 req.use_mfp = true;
4c476991
JB
10014 else if (mfp != NL80211_MFP_NO)
10015 return -EINVAL;
dc6382ce
JM
10016 }
10017
3e5d7649 10018 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 10019 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 10020
7e7c8926 10021 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 10022 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
10023
10024 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
10025 memcpy(&req.ht_capa_mask,
10026 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10027 sizeof(req.ht_capa_mask));
7e7c8926
BG
10028
10029 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 10030 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 10031 return -EINVAL;
f62fab73
JB
10032 memcpy(&req.ht_capa,
10033 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10034 sizeof(req.ht_capa));
7e7c8926
BG
10035 }
10036
ee2aca34 10037 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 10038 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34 10039
b6db0f89
BG
10040 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
10041 req.flags |= ASSOC_REQ_DISABLE_HE;
10042
ee2aca34 10043 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
10044 memcpy(&req.vht_capa_mask,
10045 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
10046 sizeof(req.vht_capa_mask));
ee2aca34
JB
10047
10048 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 10049 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 10050 return -EINVAL;
f62fab73
JB
10051 memcpy(&req.vht_capa,
10052 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
10053 sizeof(req.vht_capa));
ee2aca34
JB
10054 }
10055
bab5ab7d 10056 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
10057 if (!((rdev->wiphy.features &
10058 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
10059 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
10060 !wiphy_ext_feature_isset(&rdev->wiphy,
10061 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
10062 return -EINVAL;
10063 req.flags |= ASSOC_REQ_USE_RRM;
10064 }
10065
348bd456
JM
10066 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
10067 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
10068 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
10069 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
10070 return -EINVAL;
10071 req.fils_nonces =
10072 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
10073 }
10074
d2b7588a
TP
10075 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]) {
10076 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY])
10077 return -EINVAL;
10078 memcpy(&req.s1g_capa_mask,
10079 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]),
10080 sizeof(req.s1g_capa_mask));
10081 }
10082
10083 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) {
10084 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK])
10085 return -EINVAL;
10086 memcpy(&req.s1g_capa,
10087 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]),
10088 sizeof(req.s1g_capa));
10089 }
10090
f62fab73 10091 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
10092 if (!err) {
10093 wdev_lock(dev->ieee80211_ptr);
bd2522b1 10094
f62fab73
JB
10095 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
10096 ssid, ssid_len, &req);
bd2522b1
AZ
10097
10098 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10099 dev->ieee80211_ptr->conn_owner_nlportid =
10100 info->snd_portid;
10101 memcpy(dev->ieee80211_ptr->disconnect_bssid,
10102 bssid, ETH_ALEN);
10103 }
10104
91bf9b26
JB
10105 wdev_unlock(dev->ieee80211_ptr);
10106 }
636a5d36 10107
636a5d36
JM
10108 return err;
10109}
10110
10111static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
10112{
4c476991
JB
10113 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10114 struct net_device *dev = info->user_ptr[1];
19957bb3 10115 const u8 *ie = NULL, *bssid;
91bf9b26 10116 int ie_len = 0, err;
19957bb3 10117 u16 reason_code;
d5cdfacb 10118 bool local_state_change;
636a5d36 10119
bad29297
AZ
10120 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10121 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10122 return -EPERM;
10123
f4a11bb0
JB
10124 if (!info->attrs[NL80211_ATTR_MAC])
10125 return -EINVAL;
10126
10127 if (!info->attrs[NL80211_ATTR_REASON_CODE])
10128 return -EINVAL;
10129
4c476991
JB
10130 if (!rdev->ops->deauth)
10131 return -EOPNOTSUPP;
636a5d36 10132
074ac8df 10133 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10134 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10135 return -EOPNOTSUPP;
eec60b03 10136
19957bb3 10137 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 10138
19957bb3
JB
10139 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
10140 if (reason_code == 0) {
f4a11bb0 10141 /* Reason Code 0 is reserved */
4c476991 10142 return -EINVAL;
255e737e 10143 }
636a5d36
JM
10144
10145 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
10146 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10147 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10148 }
10149
d5cdfacb
JM
10150 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10151
91bf9b26
JB
10152 wdev_lock(dev->ieee80211_ptr);
10153 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
10154 local_state_change);
10155 wdev_unlock(dev->ieee80211_ptr);
10156 return err;
636a5d36
JM
10157}
10158
10159static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
10160{
4c476991
JB
10161 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10162 struct net_device *dev = info->user_ptr[1];
19957bb3 10163 const u8 *ie = NULL, *bssid;
91bf9b26 10164 int ie_len = 0, err;
19957bb3 10165 u16 reason_code;
d5cdfacb 10166 bool local_state_change;
636a5d36 10167
bad29297
AZ
10168 if (dev->ieee80211_ptr->conn_owner_nlportid &&
10169 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
10170 return -EPERM;
10171
f4a11bb0
JB
10172 if (!info->attrs[NL80211_ATTR_MAC])
10173 return -EINVAL;
10174
10175 if (!info->attrs[NL80211_ATTR_REASON_CODE])
10176 return -EINVAL;
10177
4c476991
JB
10178 if (!rdev->ops->disassoc)
10179 return -EOPNOTSUPP;
636a5d36 10180
074ac8df 10181 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10182 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10183 return -EOPNOTSUPP;
eec60b03 10184
19957bb3 10185 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 10186
19957bb3
JB
10187 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
10188 if (reason_code == 0) {
f4a11bb0 10189 /* Reason Code 0 is reserved */
4c476991 10190 return -EINVAL;
255e737e 10191 }
636a5d36
JM
10192
10193 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
10194 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10195 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
10196 }
10197
d5cdfacb
JM
10198 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10199
91bf9b26
JB
10200 wdev_lock(dev->ieee80211_ptr);
10201 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
10202 local_state_change);
10203 wdev_unlock(dev->ieee80211_ptr);
10204 return err;
636a5d36
JM
10205}
10206
dd5b4cc7
FF
10207static bool
10208nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 10209 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
10210 int rateval)
10211{
10212 struct wiphy *wiphy = &rdev->wiphy;
10213 bool found = false;
10214 int band, i;
10215
57fbcce3 10216 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
10217 struct ieee80211_supported_band *sband;
10218
10219 sband = wiphy->bands[band];
10220 if (!sband)
10221 continue;
10222
10223 for (i = 0; i < sband->n_bitrates; i++) {
10224 if (sband->bitrates[i].bitrate == rateval) {
10225 mcast_rate[band] = i + 1;
10226 found = true;
10227 break;
10228 }
10229 }
10230 }
10231
10232 return found;
10233}
10234
04a773ad
JB
10235static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
10236{
4c476991
JB
10237 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10238 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
10239 struct cfg80211_ibss_params ibss;
10240 struct wiphy *wiphy;
fffd0934 10241 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
10242 int err;
10243
8e30bc55
JB
10244 memset(&ibss, 0, sizeof(ibss));
10245
683b6d3b 10246 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
10247 !nla_len(info->attrs[NL80211_ATTR_SSID]))
10248 return -EINVAL;
10249
8e30bc55
JB
10250 ibss.beacon_interval = 100;
10251
12d20fc9 10252 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
10253 ibss.beacon_interval =
10254 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 10255
0c317a02
PK
10256 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
10257 ibss.beacon_interval);
12d20fc9
PK
10258 if (err)
10259 return err;
8e30bc55 10260
4c476991
JB
10261 if (!rdev->ops->join_ibss)
10262 return -EOPNOTSUPP;
04a773ad 10263
4c476991
JB
10264 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
10265 return -EOPNOTSUPP;
04a773ad 10266
79c97e97 10267 wiphy = &rdev->wiphy;
04a773ad 10268
39193498 10269 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 10270 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
10271
10272 if (!is_valid_ether_addr(ibss.bssid))
10273 return -EINVAL;
10274 }
04a773ad
JB
10275 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10276 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10277
10278 if (info->attrs[NL80211_ATTR_IE]) {
10279 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10280 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10281 }
10282
683b6d3b
JB
10283 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
10284 if (err)
10285 return err;
04a773ad 10286
174e0cd2
IP
10287 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
10288 NL80211_IFTYPE_ADHOC))
54858ee5
AS
10289 return -EINVAL;
10290
2f301ab2 10291 switch (ibss.chandef.width) {
bf372645
SW
10292 case NL80211_CHAN_WIDTH_5:
10293 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
10294 case NL80211_CHAN_WIDTH_20_NOHT:
10295 break;
10296 case NL80211_CHAN_WIDTH_20:
10297 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
10298 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
10299 return -EINVAL;
10300 break;
10301 case NL80211_CHAN_WIDTH_80:
10302 case NL80211_CHAN_WIDTH_80P80:
10303 case NL80211_CHAN_WIDTH_160:
10304 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
10305 return -EINVAL;
10306 if (!wiphy_ext_feature_isset(&rdev->wiphy,
10307 NL80211_EXT_FEATURE_VHT_IBSS))
10308 return -EINVAL;
10309 break;
2f301ab2 10310 default:
c04d6150 10311 return -EINVAL;
2f301ab2 10312 }
db9c64cf 10313
04a773ad 10314 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
10315 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
10316
fbd2c8dc
TP
10317 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
10318 u8 *rates =
10319 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10320 int n_rates =
10321 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10322 struct ieee80211_supported_band *sband =
683b6d3b 10323 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 10324
34850ab2
JB
10325 err = ieee80211_get_ratemask(sband, rates, n_rates,
10326 &ibss.basic_rates);
10327 if (err)
10328 return err;
fbd2c8dc 10329 }
dd5b4cc7 10330
803768f5
SW
10331 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10332 memcpy(&ibss.ht_capa_mask,
10333 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10334 sizeof(ibss.ht_capa_mask));
10335
10336 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
10337 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10338 return -EINVAL;
10339 memcpy(&ibss.ht_capa,
10340 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10341 sizeof(ibss.ht_capa));
10342 }
10343
dd5b4cc7
FF
10344 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
10345 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
10346 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
10347 return -EINVAL;
fbd2c8dc 10348
4c476991 10349 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
10350 bool no_ht = false;
10351
768075eb 10352 connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
4c476991
JB
10353 if (IS_ERR(connkeys))
10354 return PTR_ERR(connkeys);
de7044ee 10355
3d9d1d66
JB
10356 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
10357 no_ht) {
453431a5 10358 kfree_sensitive(connkeys);
de7044ee
SM
10359 return -EINVAL;
10360 }
4c476991 10361 }
04a773ad 10362
267335d6
AQ
10363 ibss.control_port =
10364 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
10365
c3bfe1f6
DK
10366 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
10367 int r = validate_pae_over_nl80211(rdev, info);
10368
d350a0f4 10369 if (r < 0) {
453431a5 10370 kfree_sensitive(connkeys);
c3bfe1f6 10371 return r;
d350a0f4 10372 }
c3bfe1f6
DK
10373
10374 ibss.control_port_over_nl80211 = true;
10375 }
10376
5336fa88
SW
10377 ibss.userspace_handles_dfs =
10378 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
10379
f8d16d3e
DK
10380 wdev_lock(dev->ieee80211_ptr);
10381 err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 10382 if (err)
453431a5 10383 kfree_sensitive(connkeys);
f8d16d3e
DK
10384 else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
10385 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10386 wdev_unlock(dev->ieee80211_ptr);
10387
04a773ad
JB
10388 return err;
10389}
10390
10391static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
10392{
4c476991
JB
10393 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10394 struct net_device *dev = info->user_ptr[1];
04a773ad 10395
4c476991
JB
10396 if (!rdev->ops->leave_ibss)
10397 return -EOPNOTSUPP;
04a773ad 10398
4c476991
JB
10399 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
10400 return -EOPNOTSUPP;
04a773ad 10401
4c476991 10402 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
10403}
10404
f4e583c8
AQ
10405static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
10406{
10407 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10408 struct net_device *dev = info->user_ptr[1];
57fbcce3 10409 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
10410 u32 nla_rate;
10411 int err;
10412
10413 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
10414 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
10415 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
10416 return -EOPNOTSUPP;
10417
10418 if (!rdev->ops->set_mcast_rate)
10419 return -EOPNOTSUPP;
10420
10421 memset(mcast_rate, 0, sizeof(mcast_rate));
10422
10423 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
10424 return -EINVAL;
10425
10426 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
10427 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
10428 return -EINVAL;
10429
a1056b1b 10430 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
10431
10432 return err;
10433}
10434
ad7e718c
JB
10435static struct sk_buff *
10436__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
10437 struct wireless_dev *wdev, int approxlen,
10438 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
10439 enum nl80211_attrs attr,
10440 const struct nl80211_vendor_cmd_info *info,
10441 gfp_t gfp)
ad7e718c
JB
10442{
10443 struct sk_buff *skb;
10444 void *hdr;
10445 struct nlattr *data;
10446
10447 skb = nlmsg_new(approxlen + 100, gfp);
10448 if (!skb)
10449 return NULL;
10450
10451 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
10452 if (!hdr) {
10453 kfree_skb(skb);
10454 return NULL;
10455 }
10456
10457 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
10458 goto nla_put_failure;
567ffc35
JB
10459
10460 if (info) {
10461 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
10462 info->vendor_id))
10463 goto nla_put_failure;
10464 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
10465 info->subcmd))
10466 goto nla_put_failure;
10467 }
10468
6c09e791 10469 if (wdev) {
2dad624e
ND
10470 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
10471 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
10472 goto nla_put_failure;
10473 if (wdev->netdev &&
10474 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
10475 wdev->netdev->ifindex))
10476 goto nla_put_failure;
10477 }
10478
ae0be8de 10479 data = nla_nest_start_noflag(skb, attr);
76e1fb4b
JB
10480 if (!data)
10481 goto nla_put_failure;
ad7e718c
JB
10482
10483 ((void **)skb->cb)[0] = rdev;
10484 ((void **)skb->cb)[1] = hdr;
10485 ((void **)skb->cb)[2] = data;
10486
10487 return skb;
10488
10489 nla_put_failure:
10490 kfree_skb(skb);
10491 return NULL;
10492}
f4e583c8 10493
e03ad6ea 10494struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 10495 struct wireless_dev *wdev,
e03ad6ea
JB
10496 enum nl80211_commands cmd,
10497 enum nl80211_attrs attr,
55c1fdf0 10498 unsigned int portid,
e03ad6ea
JB
10499 int vendor_event_idx,
10500 int approxlen, gfp_t gfp)
10501{
f26cbf40 10502 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
10503 const struct nl80211_vendor_cmd_info *info;
10504
10505 switch (cmd) {
10506 case NL80211_CMD_TESTMODE:
10507 if (WARN_ON(vendor_event_idx != -1))
10508 return NULL;
10509 info = NULL;
10510 break;
10511 case NL80211_CMD_VENDOR:
10512 if (WARN_ON(vendor_event_idx < 0 ||
10513 vendor_event_idx >= wiphy->n_vendor_events))
10514 return NULL;
10515 info = &wiphy->vendor_events[vendor_event_idx];
10516 break;
10517 default:
10518 WARN_ON(1);
10519 return NULL;
10520 }
10521
55c1fdf0 10522 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0,
e03ad6ea
JB
10523 cmd, attr, info, gfp);
10524}
10525EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
10526
10527void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
10528{
10529 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
10530 void *hdr = ((void **)skb->cb)[1];
55c1fdf0 10531 struct nlmsghdr *nlhdr = nlmsg_hdr(skb);
e03ad6ea
JB
10532 struct nlattr *data = ((void **)skb->cb)[2];
10533 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
10534
bd8c78e7
JB
10535 /* clear CB data for netlink core to own from now on */
10536 memset(skb->cb, 0, sizeof(skb->cb));
10537
e03ad6ea
JB
10538 nla_nest_end(skb, data);
10539 genlmsg_end(skb, hdr);
10540
55c1fdf0
JB
10541 if (nlhdr->nlmsg_pid) {
10542 genlmsg_unicast(wiphy_net(&rdev->wiphy), skb,
10543 nlhdr->nlmsg_pid);
10544 } else {
10545 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
10546 mcgrp = NL80211_MCGRP_VENDOR;
e03ad6ea 10547
55c1fdf0
JB
10548 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
10549 skb, 0, mcgrp, gfp);
10550 }
e03ad6ea
JB
10551}
10552EXPORT_SYMBOL(__cfg80211_send_event_skb);
10553
aff89a9b 10554#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
10555static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
10556{
4c476991 10557 struct cfg80211_registered_device *rdev = info->user_ptr[0];
a05829a7 10558 struct wireless_dev *wdev;
aff89a9b
JB
10559 int err;
10560
a05829a7
JB
10561 lockdep_assert_held(&rdev->wiphy.mtx);
10562
10563 wdev = __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
10564 info->attrs);
10565
fc73f11f
DS
10566 if (!rdev->ops->testmode_cmd)
10567 return -EOPNOTSUPP;
10568
10569 if (IS_ERR(wdev)) {
10570 err = PTR_ERR(wdev);
10571 if (err != -EINVAL)
10572 return err;
10573 wdev = NULL;
10574 } else if (wdev->wiphy != &rdev->wiphy) {
10575 return -EINVAL;
10576 }
10577
aff89a9b
JB
10578 if (!info->attrs[NL80211_ATTR_TESTDATA])
10579 return -EINVAL;
10580
ad7e718c 10581 rdev->cur_cmd_info = info;
fc73f11f 10582 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
10583 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
10584 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 10585 rdev->cur_cmd_info = NULL;
aff89a9b 10586
aff89a9b
JB
10587 return err;
10588}
10589
71063f0e
WYG
10590static int nl80211_testmode_dump(struct sk_buff *skb,
10591 struct netlink_callback *cb)
10592{
00918d33 10593 struct cfg80211_registered_device *rdev;
50508d94 10594 struct nlattr **attrbuf = NULL;
71063f0e
WYG
10595 int err;
10596 long phy_idx;
10597 void *data = NULL;
10598 int data_len = 0;
10599
5fe231e8
JB
10600 rtnl_lock();
10601
71063f0e
WYG
10602 if (cb->args[0]) {
10603 /*
10604 * 0 is a valid index, but not valid for args[0],
10605 * so we need to offset by 1.
10606 */
10607 phy_idx = cb->args[0] - 1;
a4956dca
LC
10608
10609 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
10610 if (!rdev) {
10611 err = -ENOENT;
10612 goto out_err;
10613 }
71063f0e 10614 } else {
50508d94
JB
10615 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
10616 GFP_KERNEL);
10617 if (!attrbuf) {
10618 err = -ENOMEM;
10619 goto out_err;
10620 }
c90c39da 10621
8cb08174
JB
10622 err = nlmsg_parse_deprecated(cb->nlh,
10623 GENL_HDRLEN + nl80211_fam.hdrsize,
10624 attrbuf, nl80211_fam.maxattr,
10625 nl80211_policy, NULL);
71063f0e 10626 if (err)
5fe231e8 10627 goto out_err;
00918d33 10628
c90c39da 10629 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 10630 if (IS_ERR(rdev)) {
5fe231e8
JB
10631 err = PTR_ERR(rdev);
10632 goto out_err;
00918d33 10633 }
2bd7e35d 10634 phy_idx = rdev->wiphy_idx;
2bd7e35d 10635
c90c39da
JB
10636 if (attrbuf[NL80211_ATTR_TESTDATA])
10637 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
10638 }
10639
10640 if (cb->args[1]) {
10641 data = nla_data((void *)cb->args[1]);
10642 data_len = nla_len((void *)cb->args[1]);
10643 }
10644
00918d33 10645 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
10646 err = -EOPNOTSUPP;
10647 goto out_err;
10648 }
10649
10650 while (1) {
15e47304 10651 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
10652 cb->nlh->nlmsg_seq, NLM_F_MULTI,
10653 NL80211_CMD_TESTMODE);
10654 struct nlattr *tmdata;
10655
cb35fba3
DC
10656 if (!hdr)
10657 break;
10658
9360ffd1 10659 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
10660 genlmsg_cancel(skb, hdr);
10661 break;
10662 }
10663
ae0be8de 10664 tmdata = nla_nest_start_noflag(skb, NL80211_ATTR_TESTDATA);
71063f0e
WYG
10665 if (!tmdata) {
10666 genlmsg_cancel(skb, hdr);
10667 break;
10668 }
e35e4d28 10669 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
10670 nla_nest_end(skb, tmdata);
10671
10672 if (err == -ENOBUFS || err == -ENOENT) {
10673 genlmsg_cancel(skb, hdr);
10674 break;
10675 } else if (err) {
10676 genlmsg_cancel(skb, hdr);
10677 goto out_err;
10678 }
10679
10680 genlmsg_end(skb, hdr);
10681 }
10682
10683 err = skb->len;
10684 /* see above */
10685 cb->args[0] = phy_idx + 1;
10686 out_err:
50508d94 10687 kfree(attrbuf);
5fe231e8 10688 rtnl_unlock();
71063f0e
WYG
10689 return err;
10690}
aff89a9b
JB
10691#endif
10692
b23aa676
SO
10693static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
10694{
4c476991
JB
10695 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10696 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
10697 struct cfg80211_connect_params connect;
10698 struct wiphy *wiphy;
fffd0934 10699 struct cfg80211_cached_keys *connkeys = NULL;
942ba88b 10700 u32 freq = 0;
b23aa676
SO
10701 int err;
10702
10703 memset(&connect, 0, sizeof(connect));
10704
b23aa676
SO
10705 if (!info->attrs[NL80211_ATTR_SSID] ||
10706 !nla_len(info->attrs[NL80211_ATTR_SSID]))
10707 return -EINVAL;
10708
10709 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
10710 connect.auth_type =
10711 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
10712 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
10713 NL80211_CMD_CONNECT))
b23aa676
SO
10714 return -EINVAL;
10715 } else
10716 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
10717
10718 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
10719
3a00df57
AS
10720 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
10721 !wiphy_ext_feature_isset(&rdev->wiphy,
10722 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
10723 return -EINVAL;
10724 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
10725
c0692b8f 10726 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 10727 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
10728 if (err)
10729 return err;
b23aa676 10730
074ac8df 10731 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10732 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10733 return -EOPNOTSUPP;
b23aa676 10734
79c97e97 10735 wiphy = &rdev->wiphy;
b23aa676 10736
4486ea98
BS
10737 connect.bg_scan_period = -1;
10738 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
10739 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
10740 connect.bg_scan_period =
10741 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
10742 }
10743
b23aa676
SO
10744 if (info->attrs[NL80211_ATTR_MAC])
10745 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
10746 else if (info->attrs[NL80211_ATTR_MAC_HINT])
10747 connect.bssid_hint =
10748 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
10749 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10750 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10751
10752 if (info->attrs[NL80211_ATTR_IE]) {
10753 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10754 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10755 }
10756
cee00a95
JM
10757 if (info->attrs[NL80211_ATTR_USE_MFP]) {
10758 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
65026002
EG
10759 if (connect.mfp == NL80211_MFP_OPTIONAL &&
10760 !wiphy_ext_feature_isset(&rdev->wiphy,
10761 NL80211_EXT_FEATURE_MFP_OPTIONAL))
10762 return -EOPNOTSUPP;
cee00a95
JM
10763 } else {
10764 connect.mfp = NL80211_MFP_NO;
10765 }
10766
ba6fbacf
JM
10767 if (info->attrs[NL80211_ATTR_PREV_BSSID])
10768 connect.prev_bssid =
10769 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
10770
942ba88b
TP
10771 if (info->attrs[NL80211_ATTR_WIPHY_FREQ])
10772 freq = MHZ_TO_KHZ(nla_get_u32(
10773 info->attrs[NL80211_ATTR_WIPHY_FREQ]));
10774 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
10775 freq +=
10776 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
10777
10778 if (freq) {
10779 connect.channel = nl80211_get_valid_chan(wiphy, freq);
664834de 10780 if (!connect.channel)
1df4a510
JM
10781 return -EINVAL;
10782 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
942ba88b
TP
10783 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
10784 freq = MHZ_TO_KHZ(freq);
10785 connect.channel_hint = nl80211_get_valid_chan(wiphy, freq);
664834de 10786 if (!connect.channel_hint)
4c476991 10787 return -EINVAL;
b23aa676
SO
10788 }
10789
2a38075c
AAL
10790 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
10791 connect.edmg.channels =
10792 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
10793
10794 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
10795 connect.edmg.bw_config =
10796 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
10797 }
10798
fffd0934 10799 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
768075eb 10800 connkeys = nl80211_parse_connkeys(rdev, info, NULL);
4c476991
JB
10801 if (IS_ERR(connkeys))
10802 return PTR_ERR(connkeys);
fffd0934
JB
10803 }
10804
7e7c8926
BG
10805 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
10806 connect.flags |= ASSOC_REQ_DISABLE_HT;
10807
10808 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
10809 memcpy(&connect.ht_capa_mask,
10810 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
10811 sizeof(connect.ht_capa_mask));
10812
10813 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 10814 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
453431a5 10815 kfree_sensitive(connkeys);
7e7c8926 10816 return -EINVAL;
b4e4f47e 10817 }
7e7c8926
BG
10818 memcpy(&connect.ht_capa,
10819 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
10820 sizeof(connect.ht_capa));
10821 }
10822
ee2aca34
JB
10823 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
10824 connect.flags |= ASSOC_REQ_DISABLE_VHT;
10825
b6db0f89
BG
10826 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
10827 connect.flags |= ASSOC_REQ_DISABLE_HE;
10828
ee2aca34
JB
10829 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
10830 memcpy(&connect.vht_capa_mask,
10831 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
10832 sizeof(connect.vht_capa_mask));
10833
10834 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
10835 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
453431a5 10836 kfree_sensitive(connkeys);
ee2aca34
JB
10837 return -EINVAL;
10838 }
10839 memcpy(&connect.vht_capa,
10840 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
10841 sizeof(connect.vht_capa));
10842 }
10843
bab5ab7d 10844 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
10845 if (!((rdev->wiphy.features &
10846 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
10847 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
10848 !wiphy_ext_feature_isset(&rdev->wiphy,
10849 NL80211_EXT_FEATURE_RRM)) {
453431a5 10850 kfree_sensitive(connkeys);
bab5ab7d 10851 return -EINVAL;
707554b4 10852 }
bab5ab7d
AK
10853 connect.flags |= ASSOC_REQ_USE_RRM;
10854 }
10855
34d50519 10856 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 10857 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
453431a5 10858 kfree_sensitive(connkeys);
34d50519
LD
10859 return -EOPNOTSUPP;
10860 }
10861
38de03d2
AS
10862 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
10863 /* bss selection makes no sense if bssid is set */
10864 if (connect.bssid) {
453431a5 10865 kfree_sensitive(connkeys);
38de03d2
AS
10866 return -EINVAL;
10867 }
10868
10869 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
10870 wiphy, &connect.bss_select);
10871 if (err) {
453431a5 10872 kfree_sensitive(connkeys);
38de03d2
AS
10873 return err;
10874 }
10875 }
10876
a3caf744
VK
10877 if (wiphy_ext_feature_isset(&rdev->wiphy,
10878 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
10879 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
10880 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
10881 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
10882 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10883 connect.fils_erp_username =
10884 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10885 connect.fils_erp_username_len =
10886 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10887 connect.fils_erp_realm =
10888 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10889 connect.fils_erp_realm_len =
10890 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10891 connect.fils_erp_next_seq_num =
10892 nla_get_u16(
10893 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
10894 connect.fils_erp_rrk =
10895 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10896 connect.fils_erp_rrk_len =
10897 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10898 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
10899 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
10900 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
10901 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
453431a5 10902 kfree_sensitive(connkeys);
a3caf744
VK
10903 return -EINVAL;
10904 }
10905
40cbfa90
SD
10906 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
10907 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
453431a5 10908 kfree_sensitive(connkeys);
40cbfa90
SD
10909 GENL_SET_ERR_MSG(info,
10910 "external auth requires connection ownership");
10911 return -EINVAL;
10912 }
10913 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
10914 }
10915
83739b03 10916 wdev_lock(dev->ieee80211_ptr);
bd2522b1 10917
4ce2bd9c
JM
10918 err = cfg80211_connect(rdev, dev, &connect, connkeys,
10919 connect.prev_bssid);
fffd0934 10920 if (err)
453431a5 10921 kfree_sensitive(connkeys);
bd2522b1
AZ
10922
10923 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10924 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10925 if (connect.bssid)
10926 memcpy(dev->ieee80211_ptr->disconnect_bssid,
10927 connect.bssid, ETH_ALEN);
10928 else
3b1648f1 10929 eth_zero_addr(dev->ieee80211_ptr->disconnect_bssid);
bd2522b1
AZ
10930 }
10931
10932 wdev_unlock(dev->ieee80211_ptr);
10933
b23aa676
SO
10934 return err;
10935}
10936
088e8df8 10937static int nl80211_update_connect_params(struct sk_buff *skb,
10938 struct genl_info *info)
10939{
10940 struct cfg80211_connect_params connect = {};
10941 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10942 struct net_device *dev = info->user_ptr[1];
10943 struct wireless_dev *wdev = dev->ieee80211_ptr;
7f9a3e15
VK
10944 bool fils_sk_offload;
10945 u32 auth_type;
088e8df8 10946 u32 changed = 0;
10947 int ret;
10948
10949 if (!rdev->ops->update_connect_params)
10950 return -EOPNOTSUPP;
10951
10952 if (info->attrs[NL80211_ATTR_IE]) {
088e8df8 10953 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10954 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10955 changed |= UPDATE_ASSOC_IES;
10956 }
10957
7f9a3e15
VK
10958 fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
10959 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
10960
10961 /*
10962 * when driver supports fils-sk offload all attributes must be
10963 * provided. So the else covers "fils-sk-not-all" and
10964 * "no-fils-sk-any".
10965 */
10966 if (fils_sk_offload &&
10967 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
10968 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
10969 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
10970 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10971 connect.fils_erp_username =
10972 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10973 connect.fils_erp_username_len =
10974 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
10975 connect.fils_erp_realm =
10976 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10977 connect.fils_erp_realm_len =
10978 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
10979 connect.fils_erp_next_seq_num =
10980 nla_get_u16(
10981 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
10982 connect.fils_erp_rrk =
10983 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10984 connect.fils_erp_rrk_len =
10985 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
10986 changed |= UPDATE_FILS_ERP_INFO;
10987 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
10988 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
10989 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
10990 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
10991 return -EINVAL;
10992 }
10993
10994 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
10995 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
10996 if (!nl80211_valid_auth_type(rdev, auth_type,
10997 NL80211_CMD_CONNECT))
10998 return -EINVAL;
10999
11000 if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
11001 fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
11002 return -EINVAL;
11003
11004 connect.auth_type = auth_type;
11005 changed |= UPDATE_AUTH_TYPE;
11006 }
11007
088e8df8 11008 wdev_lock(dev->ieee80211_ptr);
11009 if (!wdev->current_bss)
11010 ret = -ENOLINK;
11011 else
11012 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
11013 wdev_unlock(dev->ieee80211_ptr);
11014
11015 return ret;
11016}
11017
b23aa676
SO
11018static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
11019{
4c476991
JB
11020 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11021 struct net_device *dev = info->user_ptr[1];
b23aa676 11022 u16 reason;
83739b03 11023 int ret;
b23aa676 11024
bad29297
AZ
11025 if (dev->ieee80211_ptr->conn_owner_nlportid &&
11026 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
11027 return -EPERM;
11028
b23aa676
SO
11029 if (!info->attrs[NL80211_ATTR_REASON_CODE])
11030 reason = WLAN_REASON_DEAUTH_LEAVING;
11031 else
11032 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
11033
11034 if (reason == 0)
11035 return -EINVAL;
11036
074ac8df 11037 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11038 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11039 return -EOPNOTSUPP;
b23aa676 11040
83739b03
JB
11041 wdev_lock(dev->ieee80211_ptr);
11042 ret = cfg80211_disconnect(rdev, dev, reason, true);
11043 wdev_unlock(dev->ieee80211_ptr);
11044 return ret;
b23aa676
SO
11045}
11046
463d0183
JB
11047static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
11048{
4c476991 11049 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
11050 struct net *net;
11051 int err;
463d0183 11052
4b681c82
VK
11053 if (info->attrs[NL80211_ATTR_PID]) {
11054 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
11055
11056 net = get_net_ns_by_pid(pid);
11057 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
11058 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 11059
4b681c82
VK
11060 net = get_net_ns_by_fd(fd);
11061 } else {
11062 return -EINVAL;
11063 }
463d0183 11064
4c476991
JB
11065 if (IS_ERR(net))
11066 return PTR_ERR(net);
463d0183
JB
11067
11068 err = 0;
11069
11070 /* check if anything to do */
4c476991
JB
11071 if (!net_eq(wiphy_net(&rdev->wiphy), net))
11072 err = cfg80211_switch_netns(rdev, net);
463d0183 11073
463d0183 11074 put_net(net);
463d0183
JB
11075 return err;
11076}
11077
67fbb16b
SO
11078static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
11079{
4c476991 11080 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
11081 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
11082 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 11083 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
11084 struct cfg80211_pmksa pmksa;
11085
11086 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
11087
67fbb16b
SO
11088 if (!info->attrs[NL80211_ATTR_PMKID])
11089 return -EINVAL;
11090
67fbb16b 11091 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
a3caf744
VK
11092
11093 if (info->attrs[NL80211_ATTR_MAC]) {
11094 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
11095 } else if (info->attrs[NL80211_ATTR_SSID] &&
11096 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
11097 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
11098 info->attrs[NL80211_ATTR_PMK])) {
11099 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
11100 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
11101 pmksa.cache_id =
11102 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
11103 } else {
11104 return -EINVAL;
11105 }
11106 if (info->attrs[NL80211_ATTR_PMK]) {
11107 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
11108 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
11109 }
67fbb16b 11110
7fc82af8
VJ
11111 if (info->attrs[NL80211_ATTR_PMK_LIFETIME])
11112 pmksa.pmk_lifetime =
11113 nla_get_u32(info->attrs[NL80211_ATTR_PMK_LIFETIME]);
11114
11115 if (info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD])
11116 pmksa.pmk_reauth_threshold =
11117 nla_get_u8(
11118 info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD]);
11119
074ac8df 11120 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
6c900360
LD
11121 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
11122 !(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP &&
11123 wiphy_ext_feature_isset(&rdev->wiphy,
11124 NL80211_EXT_FEATURE_AP_PMKSA_CACHING)))
4c476991 11125 return -EOPNOTSUPP;
67fbb16b
SO
11126
11127 switch (info->genlhdr->cmd) {
11128 case NL80211_CMD_SET_PMKSA:
11129 rdev_ops = rdev->ops->set_pmksa;
11130 break;
11131 case NL80211_CMD_DEL_PMKSA:
11132 rdev_ops = rdev->ops->del_pmksa;
11133 break;
11134 default:
11135 WARN_ON(1);
11136 break;
11137 }
11138
4c476991
JB
11139 if (!rdev_ops)
11140 return -EOPNOTSUPP;
67fbb16b 11141
4c476991 11142 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
11143}
11144
11145static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
11146{
4c476991
JB
11147 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11148 struct net_device *dev = info->user_ptr[1];
67fbb16b 11149
074ac8df 11150 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11151 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11152 return -EOPNOTSUPP;
67fbb16b 11153
4c476991
JB
11154 if (!rdev->ops->flush_pmksa)
11155 return -EOPNOTSUPP;
67fbb16b 11156
e35e4d28 11157 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
11158}
11159
109086ce
AN
11160static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
11161{
11162 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11163 struct net_device *dev = info->user_ptr[1];
11164 u8 action_code, dialog_token;
df942e7b 11165 u32 peer_capability = 0;
109086ce
AN
11166 u16 status_code;
11167 u8 *peer;
31fa97c5 11168 bool initiator;
109086ce
AN
11169
11170 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
11171 !rdev->ops->tdls_mgmt)
11172 return -EOPNOTSUPP;
11173
11174 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
11175 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
11176 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
11177 !info->attrs[NL80211_ATTR_IE] ||
11178 !info->attrs[NL80211_ATTR_MAC])
11179 return -EINVAL;
11180
11181 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11182 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
11183 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
11184 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 11185 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
11186 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
11187 peer_capability =
11188 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 11189
e35e4d28 11190 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 11191 dialog_token, status_code, peer_capability,
31fa97c5 11192 initiator,
e35e4d28
HG
11193 nla_data(info->attrs[NL80211_ATTR_IE]),
11194 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
11195}
11196
11197static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
11198{
11199 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11200 struct net_device *dev = info->user_ptr[1];
11201 enum nl80211_tdls_operation operation;
11202 u8 *peer;
11203
11204 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
11205 !rdev->ops->tdls_oper)
11206 return -EOPNOTSUPP;
11207
11208 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
11209 !info->attrs[NL80211_ATTR_MAC])
11210 return -EINVAL;
11211
11212 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
11213 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
11214
e35e4d28 11215 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
11216}
11217
9588bbd5
JM
11218static int nl80211_remain_on_channel(struct sk_buff *skb,
11219 struct genl_info *info)
11220{
4c476991 11221 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11222 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 11223 struct cfg80211_chan_def chandef;
34373d12 11224 const struct cfg80211_chan_def *compat_chandef;
9588bbd5
JM
11225 struct sk_buff *msg;
11226 void *hdr;
11227 u64 cookie;
683b6d3b 11228 u32 duration;
9588bbd5
JM
11229 int err;
11230
11231 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
11232 !info->attrs[NL80211_ATTR_DURATION])
11233 return -EINVAL;
11234
11235 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
11236
ebf348fc
JB
11237 if (!rdev->ops->remain_on_channel ||
11238 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
11239 return -EOPNOTSUPP;
11240
9588bbd5 11241 /*
ebf348fc
JB
11242 * We should be on that channel for at least a minimum amount of
11243 * time (10ms) but no longer than the driver supports.
9588bbd5 11244 */
ebf348fc 11245 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 11246 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
11247 return -EINVAL;
11248
683b6d3b
JB
11249 err = nl80211_parse_chandef(rdev, info, &chandef);
11250 if (err)
11251 return err;
9588bbd5 11252
34373d12
VT
11253 wdev_lock(wdev);
11254 if (!cfg80211_off_channel_oper_allowed(wdev) &&
11255 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
11256 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
11257 &chandef);
11258 if (compat_chandef != &chandef) {
11259 wdev_unlock(wdev);
11260 return -EBUSY;
11261 }
11262 }
11263 wdev_unlock(wdev);
11264
9588bbd5 11265 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
11266 if (!msg)
11267 return -ENOMEM;
9588bbd5 11268
15e47304 11269 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 11270 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
11271 if (!hdr) {
11272 err = -ENOBUFS;
9588bbd5
JM
11273 goto free_msg;
11274 }
11275
683b6d3b
JB
11276 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
11277 duration, &cookie);
9588bbd5
JM
11278
11279 if (err)
11280 goto free_msg;
11281
2dad624e
ND
11282 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11283 NL80211_ATTR_PAD))
9360ffd1 11284 goto nla_put_failure;
9588bbd5
JM
11285
11286 genlmsg_end(msg, hdr);
4c476991
JB
11287
11288 return genlmsg_reply(msg, info);
9588bbd5
JM
11289
11290 nla_put_failure:
11291 err = -ENOBUFS;
11292 free_msg:
11293 nlmsg_free(msg);
9588bbd5
JM
11294 return err;
11295}
11296
11297static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
11298 struct genl_info *info)
11299{
4c476991 11300 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11301 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 11302 u64 cookie;
9588bbd5
JM
11303
11304 if (!info->attrs[NL80211_ATTR_COOKIE])
11305 return -EINVAL;
11306
4c476991
JB
11307 if (!rdev->ops->cancel_remain_on_channel)
11308 return -EOPNOTSUPP;
9588bbd5 11309
9588bbd5
JM
11310 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11311
e35e4d28 11312 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
11313}
11314
13ae75b1
JM
11315static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
11316 struct genl_info *info)
11317{
13ae75b1 11318 struct cfg80211_bitrate_mask mask;
a7c7fbff 11319 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 11320 struct net_device *dev = info->user_ptr[1];
a7c7fbff 11321 int err;
13ae75b1 11322
4c476991
JB
11323 if (!rdev->ops->set_bitrate_mask)
11324 return -EOPNOTSUPP;
13ae75b1 11325
9a5f6488 11326 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
eb89a6a6 11327 NL80211_ATTR_TX_RATES, &mask,
857b34c4 11328 dev, true);
a7c7fbff
PK
11329 if (err)
11330 return err;
13ae75b1 11331
e35e4d28 11332 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
11333}
11334
2e161f78 11335static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 11336{
4c476991 11337 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11338 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 11339 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
11340
11341 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
11342 return -EINVAL;
11343
2e161f78
JB
11344 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
11345 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 11346
71bbc994
JB
11347 switch (wdev->iftype) {
11348 case NL80211_IFTYPE_STATION:
11349 case NL80211_IFTYPE_ADHOC:
11350 case NL80211_IFTYPE_P2P_CLIENT:
11351 case NL80211_IFTYPE_AP:
11352 case NL80211_IFTYPE_AP_VLAN:
11353 case NL80211_IFTYPE_MESH_POINT:
11354 case NL80211_IFTYPE_P2P_GO:
98104fde 11355 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 11356 break;
cb3b7d87 11357 case NL80211_IFTYPE_NAN:
71bbc994 11358 default:
4c476991 11359 return -EOPNOTSUPP;
71bbc994 11360 }
026331c4
JM
11361
11362 /* not much point in registering if we can't reply */
4c476991
JB
11363 if (!rdev->ops->mgmt_tx)
11364 return -EOPNOTSUPP;
026331c4 11365
9dba48a6
JB
11366 if (info->attrs[NL80211_ATTR_RECEIVE_MULTICAST] &&
11367 !wiphy_ext_feature_isset(&rdev->wiphy,
11368 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS)) {
11369 GENL_SET_ERR_MSG(info,
11370 "multicast RX registrations are not supported");
11371 return -EOPNOTSUPP;
11372 }
11373
15e47304 11374 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
ff74c51e
IP
11375 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
11376 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]),
9dba48a6 11377 info->attrs[NL80211_ATTR_RECEIVE_MULTICAST],
ff74c51e 11378 info->extack);
026331c4
JM
11379}
11380
2e161f78 11381static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 11382{
4c476991 11383 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11384 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 11385 struct cfg80211_chan_def chandef;
026331c4 11386 int err;
d64d373f 11387 void *hdr = NULL;
026331c4 11388 u64 cookie;
e247bd90 11389 struct sk_buff *msg = NULL;
b176e629
AO
11390 struct cfg80211_mgmt_tx_params params = {
11391 .dont_wait_for_ack =
11392 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
11393 };
026331c4 11394
683b6d3b 11395 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
11396 return -EINVAL;
11397
4c476991
JB
11398 if (!rdev->ops->mgmt_tx)
11399 return -EOPNOTSUPP;
026331c4 11400
71bbc994 11401 switch (wdev->iftype) {
ea141b75
AQ
11402 case NL80211_IFTYPE_P2P_DEVICE:
11403 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
11404 return -EINVAL;
d7832c71 11405 break;
71bbc994
JB
11406 case NL80211_IFTYPE_STATION:
11407 case NL80211_IFTYPE_ADHOC:
11408 case NL80211_IFTYPE_P2P_CLIENT:
11409 case NL80211_IFTYPE_AP:
11410 case NL80211_IFTYPE_AP_VLAN:
11411 case NL80211_IFTYPE_MESH_POINT:
11412 case NL80211_IFTYPE_P2P_GO:
11413 break;
cb3b7d87 11414 case NL80211_IFTYPE_NAN:
71bbc994 11415 default:
4c476991 11416 return -EOPNOTSUPP;
71bbc994 11417 }
026331c4 11418
f7ca38df 11419 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 11420 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 11421 return -EINVAL;
b176e629 11422 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
11423
11424 /*
11425 * We should wait on the channel for at least a minimum amount
11426 * of time (10ms) but no longer than the driver supports.
11427 */
b176e629
AO
11428 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
11429 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 11430 return -EINVAL;
f7ca38df
JB
11431 }
11432
b176e629 11433 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 11434
b176e629 11435 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
11436 return -EINVAL;
11437
b176e629 11438 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 11439
ea141b75
AQ
11440 /* get the channel if any has been specified, otherwise pass NULL to
11441 * the driver. The latter will use the current one
11442 */
11443 chandef.chan = NULL;
11444 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
11445 err = nl80211_parse_chandef(rdev, info, &chandef);
11446 if (err)
11447 return err;
11448 }
11449
b176e629 11450 if (!chandef.chan && params.offchan)
ea141b75 11451 return -EINVAL;
026331c4 11452
34373d12
VT
11453 wdev_lock(wdev);
11454 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
11455 wdev_unlock(wdev);
11456 return -EBUSY;
11457 }
11458 wdev_unlock(wdev);
11459
34d22ce2
AO
11460 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
11461 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
11462
11463 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
11464 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
11465 int i;
11466
11467 if (len % sizeof(u16))
11468 return -EINVAL;
11469
11470 params.n_csa_offsets = len / sizeof(u16);
11471 params.csa_offsets =
11472 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
11473
11474 /* check that all the offsets fit the frame */
11475 for (i = 0; i < params.n_csa_offsets; i++) {
11476 if (params.csa_offsets[i] >= params.len)
11477 return -EINVAL;
11478 }
11479 }
11480
b176e629 11481 if (!params.dont_wait_for_ack) {
e247bd90
JB
11482 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11483 if (!msg)
11484 return -ENOMEM;
026331c4 11485
15e47304 11486 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 11487 NL80211_CMD_FRAME);
cb35fba3
DC
11488 if (!hdr) {
11489 err = -ENOBUFS;
e247bd90
JB
11490 goto free_msg;
11491 }
026331c4 11492 }
e247bd90 11493
b176e629
AO
11494 params.chan = chandef.chan;
11495 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
11496 if (err)
11497 goto free_msg;
11498
e247bd90 11499 if (msg) {
2dad624e
ND
11500 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11501 NL80211_ATTR_PAD))
9360ffd1 11502 goto nla_put_failure;
026331c4 11503
e247bd90
JB
11504 genlmsg_end(msg, hdr);
11505 return genlmsg_reply(msg, info);
11506 }
11507
11508 return 0;
026331c4
JM
11509
11510 nla_put_failure:
11511 err = -ENOBUFS;
11512 free_msg:
11513 nlmsg_free(msg);
026331c4
JM
11514 return err;
11515}
11516
f7ca38df
JB
11517static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
11518{
11519 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 11520 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
11521 u64 cookie;
11522
11523 if (!info->attrs[NL80211_ATTR_COOKIE])
11524 return -EINVAL;
11525
11526 if (!rdev->ops->mgmt_tx_cancel_wait)
11527 return -EOPNOTSUPP;
11528
71bbc994
JB
11529 switch (wdev->iftype) {
11530 case NL80211_IFTYPE_STATION:
11531 case NL80211_IFTYPE_ADHOC:
11532 case NL80211_IFTYPE_P2P_CLIENT:
11533 case NL80211_IFTYPE_AP:
11534 case NL80211_IFTYPE_AP_VLAN:
11535 case NL80211_IFTYPE_P2P_GO:
98104fde 11536 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 11537 break;
cb3b7d87 11538 case NL80211_IFTYPE_NAN:
71bbc994 11539 default:
f7ca38df 11540 return -EOPNOTSUPP;
71bbc994 11541 }
f7ca38df
JB
11542
11543 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
11544
e35e4d28 11545 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
11546}
11547
ffb9eb3d
KV
11548static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
11549{
4c476991 11550 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 11551 struct wireless_dev *wdev;
4c476991 11552 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
11553 u8 ps_state;
11554 bool state;
11555 int err;
11556
4c476991
JB
11557 if (!info->attrs[NL80211_ATTR_PS_STATE])
11558 return -EINVAL;
ffb9eb3d
KV
11559
11560 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
11561
ffb9eb3d
KV
11562 wdev = dev->ieee80211_ptr;
11563
4c476991
JB
11564 if (!rdev->ops->set_power_mgmt)
11565 return -EOPNOTSUPP;
ffb9eb3d
KV
11566
11567 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
11568
11569 if (state == wdev->ps)
4c476991 11570 return 0;
ffb9eb3d 11571
e35e4d28 11572 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
11573 if (!err)
11574 wdev->ps = state;
ffb9eb3d
KV
11575 return err;
11576}
11577
11578static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
11579{
4c476991 11580 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
11581 enum nl80211_ps_state ps_state;
11582 struct wireless_dev *wdev;
4c476991 11583 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
11584 struct sk_buff *msg;
11585 void *hdr;
11586 int err;
11587
ffb9eb3d
KV
11588 wdev = dev->ieee80211_ptr;
11589
4c476991
JB
11590 if (!rdev->ops->set_power_mgmt)
11591 return -EOPNOTSUPP;
ffb9eb3d
KV
11592
11593 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
11594 if (!msg)
11595 return -ENOMEM;
ffb9eb3d 11596
15e47304 11597 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
11598 NL80211_CMD_GET_POWER_SAVE);
11599 if (!hdr) {
4c476991 11600 err = -ENOBUFS;
ffb9eb3d
KV
11601 goto free_msg;
11602 }
11603
11604 if (wdev->ps)
11605 ps_state = NL80211_PS_ENABLED;
11606 else
11607 ps_state = NL80211_PS_DISABLED;
11608
9360ffd1
DM
11609 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
11610 goto nla_put_failure;
ffb9eb3d
KV
11611
11612 genlmsg_end(msg, hdr);
4c476991 11613 return genlmsg_reply(msg, info);
ffb9eb3d 11614
4c476991 11615 nla_put_failure:
ffb9eb3d 11616 err = -ENOBUFS;
4c476991 11617 free_msg:
ffb9eb3d 11618 nlmsg_free(msg);
ffb9eb3d
KV
11619 return err;
11620}
11621
94e860f1
JB
11622static const struct nla_policy
11623nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
4a4b8169 11624 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
d6dc1a38
JO
11625 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
11626 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
11627 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
11628 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
11629 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
bee427b8 11630 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
d6dc1a38
JO
11631};
11632
84f10708 11633static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 11634 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
11635{
11636 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 11637 struct net_device *dev = info->user_ptr[1];
1da5fcc8 11638 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 11639
d9d8b019 11640 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
11641 return -EINVAL;
11642
84f10708
TP
11643 if (!rdev->ops->set_cqm_txe_config)
11644 return -EOPNOTSUPP;
11645
11646 if (wdev->iftype != NL80211_IFTYPE_STATION &&
11647 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
11648 return -EOPNOTSUPP;
11649
e35e4d28 11650 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
11651}
11652
4a4b8169
AZ
11653static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
11654 struct net_device *dev)
11655{
11656 struct wireless_dev *wdev = dev->ieee80211_ptr;
11657 s32 last, low, high;
11658 u32 hyst;
1222a160 11659 int i, n, low_index;
4a4b8169
AZ
11660 int err;
11661
11662 /* RSSI reporting disabled? */
11663 if (!wdev->cqm_config)
11664 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
11665
11666 /*
11667 * Obtain current RSSI value if possible, if not and no RSSI threshold
11668 * event has been received yet, we should receive an event after a
11669 * connection is established and enough beacons received to calculate
11670 * the average.
11671 */
11672 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
11673 rdev->ops->get_station) {
73887fd9 11674 struct station_info sinfo = {};
4a4b8169
AZ
11675 u8 *mac_addr;
11676
11677 mac_addr = wdev->current_bss->pub.bssid;
11678
73887fd9
JB
11679 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
11680 if (err)
4a4b8169
AZ
11681 return err;
11682
df16737d 11683 cfg80211_sinfo_release_content(&sinfo);
397c657a 11684 if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
4a4b8169 11685 wdev->cqm_config->last_rssi_event_value =
73887fd9 11686 (s8) sinfo.rx_beacon_signal_avg;
4a4b8169
AZ
11687 }
11688
11689 last = wdev->cqm_config->last_rssi_event_value;
11690 hyst = wdev->cqm_config->rssi_hyst;
11691 n = wdev->cqm_config->n_rssi_thresholds;
11692
4b2c5a14
MH
11693 for (i = 0; i < n; i++) {
11694 i = array_index_nospec(i, n);
4a4b8169
AZ
11695 if (last < wdev->cqm_config->rssi_thresholds[i])
11696 break;
4b2c5a14 11697 }
4a4b8169 11698
1222a160
MH
11699 low_index = i - 1;
11700 if (low_index >= 0) {
11701 low_index = array_index_nospec(low_index, n);
11702 low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
11703 } else {
11704 low = S32_MIN;
11705 }
11706 if (i < n) {
11707 i = array_index_nospec(i, n);
11708 high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
11709 } else {
11710 high = S32_MAX;
11711 }
4a4b8169
AZ
11712
11713 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
11714}
11715
d6dc1a38 11716static int nl80211_set_cqm_rssi(struct genl_info *info,
4a4b8169
AZ
11717 const s32 *thresholds, int n_thresholds,
11718 u32 hysteresis)
d6dc1a38 11719{
4c476991 11720 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 11721 struct net_device *dev = info->user_ptr[1];
1da5fcc8 11722 struct wireless_dev *wdev = dev->ieee80211_ptr;
4a4b8169
AZ
11723 int i, err;
11724 s32 prev = S32_MIN;
d6dc1a38 11725
4a4b8169
AZ
11726 /* Check all values negative and sorted */
11727 for (i = 0; i < n_thresholds; i++) {
11728 if (thresholds[i] > 0 || thresholds[i] <= prev)
11729 return -EINVAL;
d6dc1a38 11730
4a4b8169
AZ
11731 prev = thresholds[i];
11732 }
d6dc1a38 11733
074ac8df 11734 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
11735 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
11736 return -EOPNOTSUPP;
d6dc1a38 11737
4a4b8169
AZ
11738 wdev_lock(wdev);
11739 cfg80211_cqm_config_free(wdev);
11740 wdev_unlock(wdev);
11741
11742 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
11743 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
11744 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
11745
11746 return rdev_set_cqm_rssi_config(rdev, dev,
11747 thresholds[0], hysteresis);
11748 }
11749
11750 if (!wiphy_ext_feature_isset(&rdev->wiphy,
11751 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
11752 return -EOPNOTSUPP;
11753
11754 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
11755 n_thresholds = 0;
11756
11757 wdev_lock(wdev);
11758 if (n_thresholds) {
11759 struct cfg80211_cqm_config *cqm_config;
11760
11761 cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
11762 n_thresholds * sizeof(s32), GFP_KERNEL);
11763 if (!cqm_config) {
11764 err = -ENOMEM;
11765 goto unlock;
11766 }
11767
11768 cqm_config->rssi_hyst = hysteresis;
11769 cqm_config->n_rssi_thresholds = n_thresholds;
11770 memcpy(cqm_config->rssi_thresholds, thresholds,
11771 n_thresholds * sizeof(s32));
11772
11773 wdev->cqm_config = cqm_config;
11774 }
11775
11776 err = cfg80211_cqm_rssi_update(rdev, dev);
11777
11778unlock:
11779 wdev_unlock(wdev);
11780
11781 return err;
d6dc1a38
JO
11782}
11783
11784static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
11785{
11786 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
11787 struct nlattr *cqm;
11788 int err;
11789
11790 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
11791 if (!cqm)
11792 return -EINVAL;
d6dc1a38 11793
8cb08174
JB
11794 err = nla_parse_nested_deprecated(attrs, NL80211_ATTR_CQM_MAX, cqm,
11795 nl80211_attr_cqm_policy,
11796 info->extack);
d6dc1a38 11797 if (err)
1da5fcc8 11798 return err;
d6dc1a38
JO
11799
11800 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
11801 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4a4b8169
AZ
11802 const s32 *thresholds =
11803 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
11804 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
1da5fcc8 11805 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 11806
4a4b8169
AZ
11807 if (len % 4)
11808 return -EINVAL;
11809
11810 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
11811 hysteresis);
1da5fcc8
JB
11812 }
11813
11814 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
11815 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
11816 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
11817 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
11818 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
11819 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
11820
11821 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
11822 }
11823
11824 return -EINVAL;
d6dc1a38
JO
11825}
11826
6e0bd6c3
RL
11827static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
11828{
11829 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11830 struct net_device *dev = info->user_ptr[1];
11831 struct ocb_setup setup = {};
11832 int err;
11833
11834 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
11835 if (err)
11836 return err;
11837
11838 return cfg80211_join_ocb(rdev, dev, &setup);
11839}
11840
11841static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
11842{
11843 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11844 struct net_device *dev = info->user_ptr[1];
11845
11846 return cfg80211_leave_ocb(rdev, dev);
11847}
11848
29cbe68c
JB
11849static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
11850{
11851 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11852 struct net_device *dev = info->user_ptr[1];
11853 struct mesh_config cfg;
c80d545d 11854 struct mesh_setup setup;
29cbe68c
JB
11855 int err;
11856
11857 /* start with default */
11858 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 11859 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 11860
24bdd9f4 11861 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 11862 /* and parse parameters if given */
24bdd9f4 11863 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
11864 if (err)
11865 return err;
11866 }
11867
11868 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
11869 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
11870 return -EINVAL;
11871
c80d545d
JC
11872 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
11873 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
11874
4bb62344
CYY
11875 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
11876 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
11877 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
11878 return -EINVAL;
11879
9bdbf04d
MP
11880 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
11881 setup.beacon_interval =
11882 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 11883
0c317a02
PK
11884 err = cfg80211_validate_beacon_int(rdev,
11885 NL80211_IFTYPE_MESH_POINT,
11886 setup.beacon_interval);
12d20fc9
PK
11887 if (err)
11888 return err;
9bdbf04d
MP
11889 }
11890
11891 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
11892 setup.dtim_period =
11893 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
11894 if (setup.dtim_period < 1 || setup.dtim_period > 100)
11895 return -EINVAL;
11896 }
11897
c80d545d
JC
11898 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
11899 /* parse additional setup parameters if given */
11900 err = nl80211_parse_mesh_setup(info, &setup);
11901 if (err)
11902 return err;
11903 }
11904
d37bb18a
TP
11905 if (setup.user_mpm)
11906 cfg.auto_open_plinks = false;
11907
cc1d2806 11908 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
11909 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
11910 if (err)
11911 return err;
cc1d2806 11912 } else {
188c1b3c 11913 /* __cfg80211_join_mesh() will sort it out */
683b6d3b 11914 setup.chandef.chan = NULL;
cc1d2806
JB
11915 }
11916
ffb3cf30
AN
11917 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
11918 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11919 int n_rates =
11920 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11921 struct ieee80211_supported_band *sband;
11922
11923 if (!setup.chandef.chan)
11924 return -EINVAL;
11925
11926 sband = rdev->wiphy.bands[setup.chandef.chan->band];
11927
11928 err = ieee80211_get_ratemask(sband, rates, n_rates,
11929 &setup.basic_rates);
11930 if (err)
11931 return err;
11932 }
11933
8564e382 11934 if (info->attrs[NL80211_ATTR_TX_RATES]) {
9a5f6488
TC
11935 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
11936 NL80211_ATTR_TX_RATES,
eb89a6a6 11937 &setup.beacon_rate,
857b34c4 11938 dev, false);
8564e382
JB
11939 if (err)
11940 return err;
11941
265698d7
JB
11942 if (!setup.chandef.chan)
11943 return -EINVAL;
11944
8564e382
JB
11945 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
11946 &setup.beacon_rate);
11947 if (err)
11948 return err;
11949 }
11950
d37d49c2
BB
11951 setup.userspace_handles_dfs =
11952 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
11953
1224f583
DK
11954 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
11955 int r = validate_pae_over_nl80211(rdev, info);
11956
11957 if (r < 0)
11958 return r;
11959
11960 setup.control_port_over_nl80211 = true;
11961 }
11962
188c1b3c
DK
11963 wdev_lock(dev->ieee80211_ptr);
11964 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
11965 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
11966 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
11967 wdev_unlock(dev->ieee80211_ptr);
11968
11969 return err;
29cbe68c
JB
11970}
11971
11972static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
11973{
11974 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11975 struct net_device *dev = info->user_ptr[1];
11976
11977 return cfg80211_leave_mesh(rdev, dev);
11978}
11979
dfb89c56 11980#ifdef CONFIG_PM
bb92d199
AK
11981static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
11982 struct cfg80211_registered_device *rdev)
11983{
6abb9cb9 11984 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
11985 struct nlattr *nl_pats, *nl_pat;
11986 int i, pat_len;
11987
6abb9cb9 11988 if (!wowlan->n_patterns)
bb92d199
AK
11989 return 0;
11990
ae0be8de 11991 nl_pats = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
bb92d199
AK
11992 if (!nl_pats)
11993 return -ENOBUFS;
11994
6abb9cb9 11995 for (i = 0; i < wowlan->n_patterns; i++) {
ae0be8de 11996 nl_pat = nla_nest_start_noflag(msg, i + 1);
bb92d199
AK
11997 if (!nl_pat)
11998 return -ENOBUFS;
6abb9cb9 11999 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 12000 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 12001 wowlan->patterns[i].mask) ||
50ac6607
AK
12002 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
12003 wowlan->patterns[i].pattern) ||
12004 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 12005 wowlan->patterns[i].pkt_offset))
bb92d199
AK
12006 return -ENOBUFS;
12007 nla_nest_end(msg, nl_pat);
12008 }
12009 nla_nest_end(msg, nl_pats);
12010
12011 return 0;
12012}
12013
2a0e047e
JB
12014static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
12015 struct cfg80211_wowlan_tcp *tcp)
12016{
12017 struct nlattr *nl_tcp;
12018
12019 if (!tcp)
12020 return 0;
12021
ae0be8de
MK
12022 nl_tcp = nla_nest_start_noflag(msg,
12023 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
2a0e047e
JB
12024 if (!nl_tcp)
12025 return -ENOBUFS;
12026
930345ea
JB
12027 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
12028 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
12029 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
12030 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
12031 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
12032 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
12033 tcp->payload_len, tcp->payload) ||
12034 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
12035 tcp->data_interval) ||
12036 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
12037 tcp->wake_len, tcp->wake_data) ||
12038 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
12039 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
12040 return -ENOBUFS;
12041
12042 if (tcp->payload_seq.len &&
12043 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
12044 sizeof(tcp->payload_seq), &tcp->payload_seq))
12045 return -ENOBUFS;
12046
12047 if (tcp->payload_tok.len &&
12048 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
12049 sizeof(tcp->payload_tok) + tcp->tokens_size,
12050 &tcp->payload_tok))
12051 return -ENOBUFS;
12052
e248ad30
JB
12053 nla_nest_end(msg, nl_tcp);
12054
2a0e047e
JB
12055 return 0;
12056}
12057
75453ccb
LC
12058static int nl80211_send_wowlan_nd(struct sk_buff *msg,
12059 struct cfg80211_sched_scan_request *req)
12060{
3b06d277 12061 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
12062 int i;
12063
12064 if (!req)
12065 return 0;
12066
ae0be8de 12067 nd = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
75453ccb
LC
12068 if (!nd)
12069 return -ENOBUFS;
12070
3b06d277
AS
12071 if (req->n_scan_plans == 1 &&
12072 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
12073 req->scan_plans[0].interval * 1000))
75453ccb
LC
12074 return -ENOBUFS;
12075
21fea567
LC
12076 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
12077 return -ENOBUFS;
12078
bf95ecdb 12079 if (req->relative_rssi_set) {
12080 struct nl80211_bss_select_rssi_adjust rssi_adjust;
12081
12082 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
12083 req->relative_rssi))
12084 return -ENOBUFS;
12085
12086 rssi_adjust.band = req->rssi_adjust.band;
12087 rssi_adjust.delta = req->rssi_adjust.delta;
12088 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
12089 sizeof(rssi_adjust), &rssi_adjust))
12090 return -ENOBUFS;
12091 }
12092
ae0be8de 12093 freqs = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
75453ccb
LC
12094 if (!freqs)
12095 return -ENOBUFS;
12096
53b18980
JB
12097 for (i = 0; i < req->n_channels; i++) {
12098 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
12099 return -ENOBUFS;
12100 }
75453ccb
LC
12101
12102 nla_nest_end(msg, freqs);
12103
12104 if (req->n_match_sets) {
ae0be8de
MK
12105 matches = nla_nest_start_noflag(msg,
12106 NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
12107 if (!matches)
12108 return -ENOBUFS;
12109
75453ccb 12110 for (i = 0; i < req->n_match_sets; i++) {
ae0be8de 12111 match = nla_nest_start_noflag(msg, i);
76e1fb4b
JB
12112 if (!match)
12113 return -ENOBUFS;
12114
53b18980
JB
12115 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
12116 req->match_sets[i].ssid.ssid_len,
12117 req->match_sets[i].ssid.ssid))
12118 return -ENOBUFS;
75453ccb
LC
12119 nla_nest_end(msg, match);
12120 }
12121 nla_nest_end(msg, matches);
12122 }
12123
ae0be8de 12124 scan_plans = nla_nest_start_noflag(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
3b06d277
AS
12125 if (!scan_plans)
12126 return -ENOBUFS;
12127
12128 for (i = 0; i < req->n_scan_plans; i++) {
ae0be8de 12129 scan_plan = nla_nest_start_noflag(msg, i + 1);
76e1fb4b
JB
12130 if (!scan_plan)
12131 return -ENOBUFS;
12132
67626964 12133 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
3b06d277
AS
12134 req->scan_plans[i].interval) ||
12135 (req->scan_plans[i].iterations &&
12136 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
12137 req->scan_plans[i].iterations)))
12138 return -ENOBUFS;
12139 nla_nest_end(msg, scan_plan);
12140 }
12141 nla_nest_end(msg, scan_plans);
12142
75453ccb
LC
12143 nla_nest_end(msg, nd);
12144
12145 return 0;
12146}
12147
ff1b6e69
JB
12148static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
12149{
12150 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12151 struct sk_buff *msg;
12152 void *hdr;
2a0e047e 12153 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 12154
964dc9e2 12155 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
12156 return -EOPNOTSUPP;
12157
6abb9cb9 12158 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 12159 /* adjust size to have room for all the data */
6abb9cb9
JB
12160 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
12161 rdev->wiphy.wowlan_config->tcp->payload_len +
12162 rdev->wiphy.wowlan_config->tcp->wake_len +
12163 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
12164 }
12165
12166 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
12167 if (!msg)
12168 return -ENOMEM;
12169
15e47304 12170 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
12171 NL80211_CMD_GET_WOWLAN);
12172 if (!hdr)
12173 goto nla_put_failure;
12174
6abb9cb9 12175 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
12176 struct nlattr *nl_wowlan;
12177
ae0be8de
MK
12178 nl_wowlan = nla_nest_start_noflag(msg,
12179 NL80211_ATTR_WOWLAN_TRIGGERS);
ff1b6e69
JB
12180 if (!nl_wowlan)
12181 goto nla_put_failure;
12182
6abb9cb9 12183 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 12184 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 12185 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 12186 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 12187 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 12188 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 12189 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 12190 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 12191 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 12192 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 12193 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 12194 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 12195 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
12196 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
12197 goto nla_put_failure;
2a0e047e 12198
bb92d199
AK
12199 if (nl80211_send_wowlan_patterns(msg, rdev))
12200 goto nla_put_failure;
2a0e047e 12201
6abb9cb9
JB
12202 if (nl80211_send_wowlan_tcp(msg,
12203 rdev->wiphy.wowlan_config->tcp))
2a0e047e 12204 goto nla_put_failure;
75453ccb
LC
12205
12206 if (nl80211_send_wowlan_nd(
12207 msg,
12208 rdev->wiphy.wowlan_config->nd_config))
12209 goto nla_put_failure;
2a0e047e 12210
ff1b6e69
JB
12211 nla_nest_end(msg, nl_wowlan);
12212 }
12213
12214 genlmsg_end(msg, hdr);
12215 return genlmsg_reply(msg, info);
12216
12217nla_put_failure:
12218 nlmsg_free(msg);
12219 return -ENOBUFS;
12220}
12221
2a0e047e
JB
12222static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
12223 struct nlattr *attr,
12224 struct cfg80211_wowlan *trig)
12225{
12226 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
12227 struct cfg80211_wowlan_tcp *cfg;
12228 struct nl80211_wowlan_tcp_data_token *tok = NULL;
12229 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
12230 u32 size;
12231 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
12232 int err, port;
12233
964dc9e2 12234 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
12235 return -EINVAL;
12236
8cb08174
JB
12237 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TCP, attr,
12238 nl80211_wowlan_tcp_policy, NULL);
2a0e047e
JB
12239 if (err)
12240 return err;
12241
12242 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
12243 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
12244 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
12245 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
12246 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
12247 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
12248 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
12249 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
12250 return -EINVAL;
12251
12252 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 12253 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
12254 return -EINVAL;
12255
12256 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 12257 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 12258 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
12259 return -EINVAL;
12260
12261 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 12262 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
12263 return -EINVAL;
12264
12265 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
12266 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
12267 return -EINVAL;
12268
12269 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
12270 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
12271
12272 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
12273 tokens_size = tokln - sizeof(*tok);
12274
12275 if (!tok->len || tokens_size % tok->len)
12276 return -EINVAL;
964dc9e2 12277 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 12278 return -EINVAL;
964dc9e2 12279 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 12280 return -EINVAL;
964dc9e2 12281 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 12282 return -EINVAL;
964dc9e2 12283 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
12284 return -EINVAL;
12285 if (tok->offset + tok->len > data_size)
12286 return -EINVAL;
12287 }
12288
12289 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
12290 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 12291 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
12292 return -EINVAL;
12293 if (seq->len == 0 || seq->len > 4)
12294 return -EINVAL;
12295 if (seq->len + seq->offset > data_size)
12296 return -EINVAL;
12297 }
12298
12299 size = sizeof(*cfg);
12300 size += data_size;
12301 size += wake_size + wake_mask_size;
12302 size += tokens_size;
12303
12304 cfg = kzalloc(size, GFP_KERNEL);
12305 if (!cfg)
12306 return -ENOMEM;
67b61f6c
JB
12307 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
12308 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
12309 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
12310 ETH_ALEN);
12311 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
12312 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
12313 else
12314 port = 0;
12315#ifdef CONFIG_INET
12316 /* allocate a socket and port for it and use it */
12317 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
12318 IPPROTO_TCP, &cfg->sock, 1);
12319 if (err) {
12320 kfree(cfg);
12321 return err;
12322 }
12323 if (inet_csk_get_port(cfg->sock->sk, port)) {
12324 sock_release(cfg->sock);
12325 kfree(cfg);
12326 return -EADDRINUSE;
12327 }
12328 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
12329#else
12330 if (!port) {
12331 kfree(cfg);
12332 return -EINVAL;
12333 }
12334 cfg->src_port = port;
12335#endif
12336
12337 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
12338 cfg->payload_len = data_size;
12339 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
12340 memcpy((void *)cfg->payload,
12341 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
12342 data_size);
12343 if (seq)
12344 cfg->payload_seq = *seq;
12345 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
12346 cfg->wake_len = wake_size;
12347 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
12348 memcpy((void *)cfg->wake_data,
12349 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
12350 wake_size);
12351 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
12352 data_size + wake_size;
12353 memcpy((void *)cfg->wake_mask,
12354 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
12355 wake_mask_size);
12356 if (tok) {
12357 cfg->tokens_size = tokens_size;
12358 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
12359 }
12360
12361 trig->tcp = cfg;
12362
12363 return 0;
12364}
12365
8cd4d456
LC
12366static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
12367 const struct wiphy_wowlan_support *wowlan,
12368 struct nlattr *attr,
12369 struct cfg80211_wowlan *trig)
12370{
12371 struct nlattr **tb;
12372 int err;
12373
6396bb22 12374 tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
8cd4d456
LC
12375 if (!tb)
12376 return -ENOMEM;
12377
12378 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
12379 err = -EOPNOTSUPP;
12380 goto out;
12381 }
12382
8cb08174
JB
12383 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_MAX, attr,
12384 nl80211_policy, NULL);
8cd4d456
LC
12385 if (err)
12386 goto out;
12387
aad1e812
AVS
12388 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
12389 wowlan->max_nd_match_sets);
8cd4d456
LC
12390 err = PTR_ERR_OR_ZERO(trig->nd_config);
12391 if (err)
12392 trig->nd_config = NULL;
12393
12394out:
12395 kfree(tb);
12396 return err;
12397}
12398
ff1b6e69
JB
12399static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
12400{
12401 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12402 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 12403 struct cfg80211_wowlan new_triggers = {};
ae33bd81 12404 struct cfg80211_wowlan *ntrig;
964dc9e2 12405 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 12406 int err, i;
6abb9cb9 12407 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 12408 bool regular = false;
ff1b6e69 12409
964dc9e2 12410 if (!wowlan)
ff1b6e69
JB
12411 return -EOPNOTSUPP;
12412
ae33bd81
JB
12413 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
12414 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 12415 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
12416 goto set_wakeup;
12417 }
ff1b6e69 12418
8cb08174
JB
12419 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TRIG,
12420 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
12421 nl80211_wowlan_policy, info->extack);
ff1b6e69
JB
12422 if (err)
12423 return err;
12424
12425 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
12426 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
12427 return -EINVAL;
12428 new_triggers.any = true;
12429 }
12430
12431 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
12432 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
12433 return -EINVAL;
12434 new_triggers.disconnect = true;
98fc4386 12435 regular = true;
ff1b6e69
JB
12436 }
12437
12438 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
12439 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
12440 return -EINVAL;
12441 new_triggers.magic_pkt = true;
98fc4386 12442 regular = true;
ff1b6e69
JB
12443 }
12444
77dbbb13
JB
12445 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
12446 return -EINVAL;
12447
12448 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
12449 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
12450 return -EINVAL;
12451 new_triggers.gtk_rekey_failure = true;
98fc4386 12452 regular = true;
77dbbb13
JB
12453 }
12454
12455 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
12456 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
12457 return -EINVAL;
12458 new_triggers.eap_identity_req = true;
98fc4386 12459 regular = true;
77dbbb13
JB
12460 }
12461
12462 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
12463 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
12464 return -EINVAL;
12465 new_triggers.four_way_handshake = true;
98fc4386 12466 regular = true;
77dbbb13
JB
12467 }
12468
12469 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
12470 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
12471 return -EINVAL;
12472 new_triggers.rfkill_release = true;
98fc4386 12473 regular = true;
77dbbb13
JB
12474 }
12475
ff1b6e69
JB
12476 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
12477 struct nlattr *pat;
12478 int n_patterns = 0;
bb92d199 12479 int rem, pat_len, mask_len, pkt_offset;
50ac6607 12480 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 12481
98fc4386
JB
12482 regular = true;
12483
ff1b6e69
JB
12484 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
12485 rem)
12486 n_patterns++;
12487 if (n_patterns > wowlan->n_patterns)
12488 return -EINVAL;
12489
12490 new_triggers.patterns = kcalloc(n_patterns,
12491 sizeof(new_triggers.patterns[0]),
12492 GFP_KERNEL);
12493 if (!new_triggers.patterns)
12494 return -ENOMEM;
12495
12496 new_triggers.n_patterns = n_patterns;
12497 i = 0;
12498
12499 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
12500 rem) {
922bd80f
JB
12501 u8 *mask_pat;
12502
8cb08174
JB
12503 err = nla_parse_nested_deprecated(pat_tb,
12504 MAX_NL80211_PKTPAT,
12505 pat,
12506 nl80211_packet_pattern_policy,
12507 info->extack);
95bca62f
JB
12508 if (err)
12509 goto error;
12510
ff1b6e69 12511 err = -EINVAL;
50ac6607
AK
12512 if (!pat_tb[NL80211_PKTPAT_MASK] ||
12513 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 12514 goto error;
50ac6607 12515 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 12516 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 12517 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
12518 goto error;
12519 if (pat_len > wowlan->pattern_max_len ||
12520 pat_len < wowlan->pattern_min_len)
12521 goto error;
12522
50ac6607 12523 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
12524 pkt_offset = 0;
12525 else
12526 pkt_offset = nla_get_u32(
50ac6607 12527 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
12528 if (pkt_offset > wowlan->max_pkt_offset)
12529 goto error;
12530 new_triggers.patterns[i].pkt_offset = pkt_offset;
12531
922bd80f
JB
12532 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
12533 if (!mask_pat) {
ff1b6e69
JB
12534 err = -ENOMEM;
12535 goto error;
12536 }
922bd80f
JB
12537 new_triggers.patterns[i].mask = mask_pat;
12538 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 12539 mask_len);
922bd80f
JB
12540 mask_pat += mask_len;
12541 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 12542 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 12543 memcpy(mask_pat,
50ac6607 12544 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
12545 pat_len);
12546 i++;
12547 }
12548 }
12549
2a0e047e 12550 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 12551 regular = true;
2a0e047e
JB
12552 err = nl80211_parse_wowlan_tcp(
12553 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
12554 &new_triggers);
12555 if (err)
12556 goto error;
12557 }
12558
8cd4d456 12559 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 12560 regular = true;
8cd4d456
LC
12561 err = nl80211_parse_wowlan_nd(
12562 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
12563 &new_triggers);
12564 if (err)
12565 goto error;
12566 }
12567
98fc4386
JB
12568 /* The 'any' trigger means the device continues operating more or less
12569 * as in its normal operation mode and wakes up the host on most of the
12570 * normal interrupts (like packet RX, ...)
12571 * It therefore makes little sense to combine with the more constrained
12572 * wakeup trigger modes.
12573 */
12574 if (new_triggers.any && regular) {
12575 err = -EINVAL;
12576 goto error;
12577 }
12578
ae33bd81
JB
12579 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
12580 if (!ntrig) {
12581 err = -ENOMEM;
12582 goto error;
ff1b6e69 12583 }
ae33bd81 12584 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 12585 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 12586
ae33bd81 12587 set_wakeup:
6abb9cb9
JB
12588 if (rdev->ops->set_wakeup &&
12589 prev_enabled != !!rdev->wiphy.wowlan_config)
12590 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 12591
ff1b6e69
JB
12592 return 0;
12593 error:
12594 for (i = 0; i < new_triggers.n_patterns; i++)
12595 kfree(new_triggers.patterns[i].mask);
12596 kfree(new_triggers.patterns);
2a0e047e
JB
12597 if (new_triggers.tcp && new_triggers.tcp->sock)
12598 sock_release(new_triggers.tcp->sock);
12599 kfree(new_triggers.tcp);
e5dbe070 12600 kfree(new_triggers.nd_config);
ff1b6e69
JB
12601 return err;
12602}
dfb89c56 12603#endif
ff1b6e69 12604
be29b99a
AK
12605static int nl80211_send_coalesce_rules(struct sk_buff *msg,
12606 struct cfg80211_registered_device *rdev)
12607{
12608 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
12609 int i, j, pat_len;
12610 struct cfg80211_coalesce_rules *rule;
12611
12612 if (!rdev->coalesce->n_rules)
12613 return 0;
12614
ae0be8de 12615 nl_rules = nla_nest_start_noflag(msg, NL80211_ATTR_COALESCE_RULE);
be29b99a
AK
12616 if (!nl_rules)
12617 return -ENOBUFS;
12618
12619 for (i = 0; i < rdev->coalesce->n_rules; i++) {
ae0be8de 12620 nl_rule = nla_nest_start_noflag(msg, i + 1);
be29b99a
AK
12621 if (!nl_rule)
12622 return -ENOBUFS;
12623
12624 rule = &rdev->coalesce->rules[i];
12625 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
12626 rule->delay))
12627 return -ENOBUFS;
12628
12629 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
12630 rule->condition))
12631 return -ENOBUFS;
12632
ae0be8de
MK
12633 nl_pats = nla_nest_start_noflag(msg,
12634 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
be29b99a
AK
12635 if (!nl_pats)
12636 return -ENOBUFS;
12637
12638 for (j = 0; j < rule->n_patterns; j++) {
ae0be8de 12639 nl_pat = nla_nest_start_noflag(msg, j + 1);
be29b99a
AK
12640 if (!nl_pat)
12641 return -ENOBUFS;
12642 pat_len = rule->patterns[j].pattern_len;
12643 if (nla_put(msg, NL80211_PKTPAT_MASK,
12644 DIV_ROUND_UP(pat_len, 8),
12645 rule->patterns[j].mask) ||
12646 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
12647 rule->patterns[j].pattern) ||
12648 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
12649 rule->patterns[j].pkt_offset))
12650 return -ENOBUFS;
12651 nla_nest_end(msg, nl_pat);
12652 }
12653 nla_nest_end(msg, nl_pats);
12654 nla_nest_end(msg, nl_rule);
12655 }
12656 nla_nest_end(msg, nl_rules);
12657
12658 return 0;
12659}
12660
12661static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
12662{
12663 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12664 struct sk_buff *msg;
12665 void *hdr;
12666
12667 if (!rdev->wiphy.coalesce)
12668 return -EOPNOTSUPP;
12669
12670 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12671 if (!msg)
12672 return -ENOMEM;
12673
12674 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12675 NL80211_CMD_GET_COALESCE);
12676 if (!hdr)
12677 goto nla_put_failure;
12678
12679 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
12680 goto nla_put_failure;
12681
12682 genlmsg_end(msg, hdr);
12683 return genlmsg_reply(msg, info);
12684
12685nla_put_failure:
12686 nlmsg_free(msg);
12687 return -ENOBUFS;
12688}
12689
12690void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
12691{
12692 struct cfg80211_coalesce *coalesce = rdev->coalesce;
12693 int i, j;
12694 struct cfg80211_coalesce_rules *rule;
12695
12696 if (!coalesce)
12697 return;
12698
12699 for (i = 0; i < coalesce->n_rules; i++) {
12700 rule = &coalesce->rules[i];
12701 for (j = 0; j < rule->n_patterns; j++)
12702 kfree(rule->patterns[j].mask);
12703 kfree(rule->patterns);
12704 }
12705 kfree(coalesce->rules);
12706 kfree(coalesce);
12707 rdev->coalesce = NULL;
12708}
12709
12710static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
12711 struct nlattr *rule,
12712 struct cfg80211_coalesce_rules *new_rule)
12713{
12714 int err, i;
12715 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
12716 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
12717 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
12718 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
12719
8cb08174
JB
12720 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_COALESCE_RULE_MAX,
12721 rule, nl80211_coalesce_policy, NULL);
be29b99a
AK
12722 if (err)
12723 return err;
12724
12725 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
12726 new_rule->delay =
12727 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
12728 if (new_rule->delay > coalesce->max_delay)
12729 return -EINVAL;
12730
12731 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
12732 new_rule->condition =
12733 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
be29b99a
AK
12734
12735 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
12736 return -EINVAL;
12737
12738 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
12739 rem)
12740 n_patterns++;
12741 if (n_patterns > coalesce->n_patterns)
12742 return -EINVAL;
12743
12744 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
12745 GFP_KERNEL);
12746 if (!new_rule->patterns)
12747 return -ENOMEM;
12748
12749 new_rule->n_patterns = n_patterns;
12750 i = 0;
12751
12752 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
12753 rem) {
922bd80f
JB
12754 u8 *mask_pat;
12755
8cb08174
JB
12756 err = nla_parse_nested_deprecated(pat_tb, MAX_NL80211_PKTPAT,
12757 pat,
12758 nl80211_packet_pattern_policy,
12759 NULL);
95bca62f
JB
12760 if (err)
12761 return err;
12762
be29b99a
AK
12763 if (!pat_tb[NL80211_PKTPAT_MASK] ||
12764 !pat_tb[NL80211_PKTPAT_PATTERN])
12765 return -EINVAL;
12766 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
12767 mask_len = DIV_ROUND_UP(pat_len, 8);
12768 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
12769 return -EINVAL;
12770 if (pat_len > coalesce->pattern_max_len ||
12771 pat_len < coalesce->pattern_min_len)
12772 return -EINVAL;
12773
12774 if (!pat_tb[NL80211_PKTPAT_OFFSET])
12775 pkt_offset = 0;
12776 else
12777 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
12778 if (pkt_offset > coalesce->max_pkt_offset)
12779 return -EINVAL;
12780 new_rule->patterns[i].pkt_offset = pkt_offset;
12781
922bd80f
JB
12782 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
12783 if (!mask_pat)
be29b99a 12784 return -ENOMEM;
922bd80f
JB
12785
12786 new_rule->patterns[i].mask = mask_pat;
12787 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
12788 mask_len);
12789
12790 mask_pat += mask_len;
12791 new_rule->patterns[i].pattern = mask_pat;
be29b99a 12792 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
12793 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
12794 pat_len);
be29b99a
AK
12795 i++;
12796 }
12797
12798 return 0;
12799}
12800
12801static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
12802{
12803 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12804 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
12805 struct cfg80211_coalesce new_coalesce = {};
12806 struct cfg80211_coalesce *n_coalesce;
12807 int err, rem_rule, n_rules = 0, i, j;
12808 struct nlattr *rule;
12809 struct cfg80211_coalesce_rules *tmp_rule;
12810
12811 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
12812 return -EOPNOTSUPP;
12813
12814 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
12815 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 12816 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
12817 return 0;
12818 }
12819
12820 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
12821 rem_rule)
12822 n_rules++;
12823 if (n_rules > coalesce->n_rules)
12824 return -EINVAL;
12825
12826 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
12827 GFP_KERNEL);
12828 if (!new_coalesce.rules)
12829 return -ENOMEM;
12830
12831 new_coalesce.n_rules = n_rules;
12832 i = 0;
12833
12834 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
12835 rem_rule) {
12836 err = nl80211_parse_coalesce_rule(rdev, rule,
12837 &new_coalesce.rules[i]);
12838 if (err)
12839 goto error;
12840
12841 i++;
12842 }
12843
a1056b1b 12844 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
12845 if (err)
12846 goto error;
12847
12848 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
12849 if (!n_coalesce) {
12850 err = -ENOMEM;
12851 goto error;
12852 }
12853 cfg80211_rdev_free_coalesce(rdev);
12854 rdev->coalesce = n_coalesce;
12855
12856 return 0;
12857error:
12858 for (i = 0; i < new_coalesce.n_rules; i++) {
12859 tmp_rule = &new_coalesce.rules[i];
12860 for (j = 0; j < tmp_rule->n_patterns; j++)
12861 kfree(tmp_rule->patterns[j].mask);
12862 kfree(tmp_rule->patterns);
12863 }
12864 kfree(new_coalesce.rules);
12865
12866 return err;
12867}
12868
e5497d76
JB
12869static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
12870{
12871 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12872 struct net_device *dev = info->user_ptr[1];
12873 struct wireless_dev *wdev = dev->ieee80211_ptr;
12874 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
f495acd8 12875 struct cfg80211_gtk_rekey_data rekey_data = {};
e5497d76
JB
12876 int err;
12877
12878 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
12879 return -EINVAL;
12880
8cb08174
JB
12881 err = nla_parse_nested_deprecated(tb, MAX_NL80211_REKEY_DATA,
12882 info->attrs[NL80211_ATTR_REKEY_DATA],
12883 nl80211_rekey_policy, info->extack);
e5497d76
JB
12884 if (err)
12885 return err;
12886
e785fa0a
VD
12887 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
12888 !tb[NL80211_REKEY_DATA_KCK])
12889 return -EINVAL;
093a48d2
NE
12890 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
12891 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
12892 nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
e5497d76 12893 return -ERANGE;
093a48d2
NE
12894 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
12895 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
12896 nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KCK_EXT_LEN))
e5497d76
JB
12897 return -ERANGE;
12898
78f686ca
JB
12899 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
12900 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
12901 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
093a48d2
NE
12902 rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
12903 rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]);
12904 if (tb[NL80211_REKEY_DATA_AKM])
12905 rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
e5497d76
JB
12906
12907 wdev_lock(wdev);
12908 if (!wdev->current_bss) {
12909 err = -ENOTCONN;
12910 goto out;
12911 }
12912
12913 if (!rdev->ops->set_rekey_data) {
12914 err = -EOPNOTSUPP;
12915 goto out;
12916 }
12917
e35e4d28 12918 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
12919 out:
12920 wdev_unlock(wdev);
12921 return err;
12922}
12923
28946da7
JB
12924static int nl80211_register_unexpected_frame(struct sk_buff *skb,
12925 struct genl_info *info)
12926{
12927 struct net_device *dev = info->user_ptr[1];
12928 struct wireless_dev *wdev = dev->ieee80211_ptr;
12929
12930 if (wdev->iftype != NL80211_IFTYPE_AP &&
12931 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12932 return -EINVAL;
12933
15e47304 12934 if (wdev->ap_unexpected_nlportid)
28946da7
JB
12935 return -EBUSY;
12936
15e47304 12937 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
12938 return 0;
12939}
12940
7f6cf311
JB
12941static int nl80211_probe_client(struct sk_buff *skb,
12942 struct genl_info *info)
12943{
12944 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12945 struct net_device *dev = info->user_ptr[1];
12946 struct wireless_dev *wdev = dev->ieee80211_ptr;
12947 struct sk_buff *msg;
12948 void *hdr;
12949 const u8 *addr;
12950 u64 cookie;
12951 int err;
12952
12953 if (wdev->iftype != NL80211_IFTYPE_AP &&
12954 wdev->iftype != NL80211_IFTYPE_P2P_GO)
12955 return -EOPNOTSUPP;
12956
12957 if (!info->attrs[NL80211_ATTR_MAC])
12958 return -EINVAL;
12959
12960 if (!rdev->ops->probe_client)
12961 return -EOPNOTSUPP;
12962
12963 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12964 if (!msg)
12965 return -ENOMEM;
12966
15e47304 12967 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 12968 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
12969 if (!hdr) {
12970 err = -ENOBUFS;
7f6cf311
JB
12971 goto free_msg;
12972 }
12973
12974 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
12975
e35e4d28 12976 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
12977 if (err)
12978 goto free_msg;
12979
2dad624e
ND
12980 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12981 NL80211_ATTR_PAD))
9360ffd1 12982 goto nla_put_failure;
7f6cf311
JB
12983
12984 genlmsg_end(msg, hdr);
12985
12986 return genlmsg_reply(msg, info);
12987
12988 nla_put_failure:
12989 err = -ENOBUFS;
12990 free_msg:
12991 nlmsg_free(msg);
12992 return err;
12993}
12994
5e760230
JB
12995static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
12996{
12997 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
12998 struct cfg80211_beacon_registration *reg, *nreg;
12999 int rv;
5e760230
JB
13000
13001 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
13002 return -EOPNOTSUPP;
13003
37c73b5f
BG
13004 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
13005 if (!nreg)
13006 return -ENOMEM;
13007
13008 /* First, check if already registered. */
13009 spin_lock_bh(&rdev->beacon_registrations_lock);
13010 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
13011 if (reg->nlportid == info->snd_portid) {
13012 rv = -EALREADY;
13013 goto out_err;
13014 }
13015 }
13016 /* Add it to the list */
13017 nreg->nlportid = info->snd_portid;
13018 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 13019
37c73b5f 13020 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
13021
13022 return 0;
37c73b5f
BG
13023out_err:
13024 spin_unlock_bh(&rdev->beacon_registrations_lock);
13025 kfree(nreg);
13026 return rv;
5e760230
JB
13027}
13028
98104fde
JB
13029static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
13030{
13031 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13032 struct wireless_dev *wdev = info->user_ptr[1];
13033 int err;
13034
13035 if (!rdev->ops->start_p2p_device)
13036 return -EOPNOTSUPP;
13037
13038 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
13039 return -EOPNOTSUPP;
13040
73c7da3d 13041 if (wdev_running(wdev))
98104fde
JB
13042 return 0;
13043
358ae888 13044 if (rfkill_blocked(rdev->wiphy.rfkill))
b6a55015 13045 return -ERFKILL;
98104fde 13046
eeb126e9 13047 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
13048 if (err)
13049 return err;
13050
73c7da3d 13051 wdev->is_running = true;
98104fde 13052 rdev->opencount++;
98104fde
JB
13053
13054 return 0;
13055}
13056
13057static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
13058{
13059 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13060 struct wireless_dev *wdev = info->user_ptr[1];
13061
13062 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
13063 return -EOPNOTSUPP;
13064
13065 if (!rdev->ops->stop_p2p_device)
13066 return -EOPNOTSUPP;
13067
f9f47529 13068 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
13069
13070 return 0;
13071}
13072
cb3b7d87
AB
13073static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
13074{
13075 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13076 struct wireless_dev *wdev = info->user_ptr[1];
13077 struct cfg80211_nan_conf conf = {};
13078 int err;
13079
13080 if (wdev->iftype != NL80211_IFTYPE_NAN)
13081 return -EOPNOTSUPP;
13082
eeb04a96 13083 if (wdev_running(wdev))
cb3b7d87
AB
13084 return -EEXIST;
13085
358ae888 13086 if (rfkill_blocked(rdev->wiphy.rfkill))
cb3b7d87
AB
13087 return -ERFKILL;
13088
13089 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
13090 return -EINVAL;
13091
cb3b7d87
AB
13092 conf.master_pref =
13093 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
cb3b7d87 13094
8585989d
LC
13095 if (info->attrs[NL80211_ATTR_BANDS]) {
13096 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
13097
13098 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
13099 return -EOPNOTSUPP;
13100
13101 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
13102 return -EINVAL;
13103
13104 conf.bands = bands;
13105 }
cb3b7d87
AB
13106
13107 err = rdev_start_nan(rdev, wdev, &conf);
13108 if (err)
13109 return err;
13110
73c7da3d 13111 wdev->is_running = true;
cb3b7d87
AB
13112 rdev->opencount++;
13113
13114 return 0;
13115}
13116
13117static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
13118{
13119 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13120 struct wireless_dev *wdev = info->user_ptr[1];
13121
13122 if (wdev->iftype != NL80211_IFTYPE_NAN)
13123 return -EOPNOTSUPP;
13124
13125 cfg80211_stop_nan(rdev, wdev);
13126
13127 return 0;
13128}
13129
a442b761
AB
13130static int validate_nan_filter(struct nlattr *filter_attr)
13131{
13132 struct nlattr *attr;
13133 int len = 0, n_entries = 0, rem;
13134
13135 nla_for_each_nested(attr, filter_attr, rem) {
13136 len += nla_len(attr);
13137 n_entries++;
13138 }
13139
13140 if (len >= U8_MAX)
13141 return -EINVAL;
13142
13143 return n_entries;
13144}
13145
13146static int handle_nan_filter(struct nlattr *attr_filter,
13147 struct cfg80211_nan_func *func,
13148 bool tx)
13149{
13150 struct nlattr *attr;
13151 int n_entries, rem, i;
13152 struct cfg80211_nan_func_filter *filter;
13153
13154 n_entries = validate_nan_filter(attr_filter);
13155 if (n_entries < 0)
13156 return n_entries;
13157
13158 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
13159
13160 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
13161 if (!filter)
13162 return -ENOMEM;
13163
13164 i = 0;
13165 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 13166 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
a442b761
AB
13167 filter[i].len = nla_len(attr);
13168 i++;
13169 }
13170 if (tx) {
13171 func->num_tx_filters = n_entries;
13172 func->tx_filters = filter;
13173 } else {
13174 func->num_rx_filters = n_entries;
13175 func->rx_filters = filter;
13176 }
13177
13178 return 0;
13179}
13180
13181static int nl80211_nan_add_func(struct sk_buff *skb,
13182 struct genl_info *info)
13183{
13184 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13185 struct wireless_dev *wdev = info->user_ptr[1];
13186 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
13187 struct cfg80211_nan_func *func;
13188 struct sk_buff *msg = NULL;
13189 void *hdr = NULL;
13190 int err = 0;
13191
13192 if (wdev->iftype != NL80211_IFTYPE_NAN)
13193 return -EOPNOTSUPP;
13194
73c7da3d 13195 if (!wdev_running(wdev))
a442b761
AB
13196 return -ENOTCONN;
13197
13198 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
13199 return -EINVAL;
13200
8cb08174
JB
13201 err = nla_parse_nested_deprecated(tb, NL80211_NAN_FUNC_ATTR_MAX,
13202 info->attrs[NL80211_ATTR_NAN_FUNC],
13203 nl80211_nan_func_policy,
13204 info->extack);
a442b761
AB
13205 if (err)
13206 return err;
13207
13208 func = kzalloc(sizeof(*func), GFP_KERNEL);
13209 if (!func)
13210 return -ENOMEM;
13211
b60ad348 13212 func->cookie = cfg80211_assign_cookie(rdev);
a442b761 13213
cb9abd48 13214 if (!tb[NL80211_NAN_FUNC_TYPE]) {
a442b761
AB
13215 err = -EINVAL;
13216 goto out;
13217 }
13218
13219
13220 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
13221
13222 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
13223 err = -EINVAL;
13224 goto out;
13225 }
13226
13227 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
13228 sizeof(func->service_id));
13229
13230 func->close_range =
13231 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
13232
13233 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
13234 func->serv_spec_info_len =
13235 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
13236 func->serv_spec_info =
13237 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
13238 func->serv_spec_info_len,
13239 GFP_KERNEL);
13240 if (!func->serv_spec_info) {
13241 err = -ENOMEM;
13242 goto out;
13243 }
13244 }
13245
13246 if (tb[NL80211_NAN_FUNC_TTL])
13247 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
13248
13249 switch (func->type) {
13250 case NL80211_NAN_FUNC_PUBLISH:
13251 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
13252 err = -EINVAL;
13253 goto out;
13254 }
13255
13256 func->publish_type =
13257 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
13258 func->publish_bcast =
13259 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
13260
13261 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
13262 func->publish_bcast) {
13263 err = -EINVAL;
13264 goto out;
13265 }
13266 break;
13267 case NL80211_NAN_FUNC_SUBSCRIBE:
13268 func->subscribe_active =
13269 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
13270 break;
13271 case NL80211_NAN_FUNC_FOLLOW_UP:
13272 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
3ea15452
HC
13273 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
13274 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
a442b761
AB
13275 err = -EINVAL;
13276 goto out;
13277 }
13278
13279 func->followup_id =
13280 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
13281 func->followup_reqid =
13282 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
13283 memcpy(func->followup_dest.addr,
13284 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
13285 sizeof(func->followup_dest.addr));
13286 if (func->ttl) {
13287 err = -EINVAL;
13288 goto out;
13289 }
13290 break;
13291 default:
13292 err = -EINVAL;
13293 goto out;
13294 }
13295
13296 if (tb[NL80211_NAN_FUNC_SRF]) {
13297 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
13298
8cb08174
JB
13299 err = nla_parse_nested_deprecated(srf_tb,
13300 NL80211_NAN_SRF_ATTR_MAX,
13301 tb[NL80211_NAN_FUNC_SRF],
13302 nl80211_nan_srf_policy,
13303 info->extack);
a442b761
AB
13304 if (err)
13305 goto out;
13306
13307 func->srf_include =
13308 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
13309
13310 if (srf_tb[NL80211_NAN_SRF_BF]) {
13311 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
13312 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
13313 err = -EINVAL;
13314 goto out;
13315 }
13316
13317 func->srf_bf_len =
13318 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
13319 func->srf_bf =
13320 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
13321 func->srf_bf_len, GFP_KERNEL);
13322 if (!func->srf_bf) {
13323 err = -ENOMEM;
13324 goto out;
13325 }
13326
13327 func->srf_bf_idx =
13328 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
13329 } else {
13330 struct nlattr *attr, *mac_attr =
13331 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
13332 int n_entries, rem, i = 0;
13333
13334 if (!mac_attr) {
13335 err = -EINVAL;
13336 goto out;
13337 }
13338
13339 n_entries = validate_acl_mac_addrs(mac_attr);
13340 if (n_entries <= 0) {
13341 err = -EINVAL;
13342 goto out;
13343 }
13344
13345 func->srf_num_macs = n_entries;
13346 func->srf_macs =
6396bb22 13347 kcalloc(n_entries, sizeof(*func->srf_macs),
a442b761
AB
13348 GFP_KERNEL);
13349 if (!func->srf_macs) {
13350 err = -ENOMEM;
13351 goto out;
13352 }
13353
13354 nla_for_each_nested(attr, mac_attr, rem)
13355 memcpy(func->srf_macs[i++].addr, nla_data(attr),
13356 sizeof(*func->srf_macs));
13357 }
13358 }
13359
13360 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
13361 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
13362 func, true);
13363 if (err)
13364 goto out;
13365 }
13366
13367 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
13368 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
13369 func, false);
13370 if (err)
13371 goto out;
13372 }
13373
13374 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13375 if (!msg) {
13376 err = -ENOMEM;
13377 goto out;
13378 }
13379
13380 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13381 NL80211_CMD_ADD_NAN_FUNCTION);
13382 /* This can't really happen - we just allocated 4KB */
13383 if (WARN_ON(!hdr)) {
13384 err = -ENOMEM;
13385 goto out;
13386 }
13387
13388 err = rdev_add_nan_func(rdev, wdev, func);
13389out:
13390 if (err < 0) {
13391 cfg80211_free_nan_func(func);
13392 nlmsg_free(msg);
13393 return err;
13394 }
13395
13396 /* propagate the instance id and cookie to userspace */
13397 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
13398 NL80211_ATTR_PAD))
13399 goto nla_put_failure;
13400
ae0be8de 13401 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
a442b761
AB
13402 if (!func_attr)
13403 goto nla_put_failure;
13404
13405 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
13406 func->instance_id))
13407 goto nla_put_failure;
13408
13409 nla_nest_end(msg, func_attr);
13410
13411 genlmsg_end(msg, hdr);
13412 return genlmsg_reply(msg, info);
13413
13414nla_put_failure:
13415 nlmsg_free(msg);
13416 return -ENOBUFS;
13417}
13418
13419static int nl80211_nan_del_func(struct sk_buff *skb,
13420 struct genl_info *info)
13421{
13422 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13423 struct wireless_dev *wdev = info->user_ptr[1];
13424 u64 cookie;
13425
13426 if (wdev->iftype != NL80211_IFTYPE_NAN)
13427 return -EOPNOTSUPP;
13428
73c7da3d 13429 if (!wdev_running(wdev))
a442b761
AB
13430 return -ENOTCONN;
13431
13432 if (!info->attrs[NL80211_ATTR_COOKIE])
13433 return -EINVAL;
13434
a442b761
AB
13435 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
13436
13437 rdev_del_nan_func(rdev, wdev, cookie);
13438
13439 return 0;
13440}
13441
a5a9dcf2
AB
13442static int nl80211_nan_change_config(struct sk_buff *skb,
13443 struct genl_info *info)
13444{
13445 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13446 struct wireless_dev *wdev = info->user_ptr[1];
13447 struct cfg80211_nan_conf conf = {};
13448 u32 changed = 0;
13449
13450 if (wdev->iftype != NL80211_IFTYPE_NAN)
13451 return -EOPNOTSUPP;
13452
73c7da3d 13453 if (!wdev_running(wdev))
a5a9dcf2
AB
13454 return -ENOTCONN;
13455
13456 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
13457 conf.master_pref =
13458 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
13459 if (conf.master_pref <= 1 || conf.master_pref == 255)
13460 return -EINVAL;
13461
13462 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
13463 }
13464
8585989d
LC
13465 if (info->attrs[NL80211_ATTR_BANDS]) {
13466 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
13467
13468 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
13469 return -EOPNOTSUPP;
13470
13471 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
13472 return -EINVAL;
13473
13474 conf.bands = bands;
13475 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
13476 }
13477
13478 if (!changed)
13479 return -EINVAL;
13480
13481 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
13482}
13483
50bcd31d
AB
13484void cfg80211_nan_match(struct wireless_dev *wdev,
13485 struct cfg80211_nan_match_params *match, gfp_t gfp)
13486{
13487 struct wiphy *wiphy = wdev->wiphy;
13488 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13489 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
13490 struct sk_buff *msg;
13491 void *hdr;
13492
13493 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
13494 return;
13495
13496 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13497 if (!msg)
13498 return;
13499
13500 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
13501 if (!hdr) {
13502 nlmsg_free(msg);
13503 return;
13504 }
13505
13506 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13507 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13508 wdev->netdev->ifindex)) ||
13509 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13510 NL80211_ATTR_PAD))
13511 goto nla_put_failure;
13512
13513 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
13514 NL80211_ATTR_PAD) ||
13515 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
13516 goto nla_put_failure;
13517
ae0be8de 13518 match_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_MATCH);
50bcd31d
AB
13519 if (!match_attr)
13520 goto nla_put_failure;
13521
ae0be8de
MK
13522 local_func_attr = nla_nest_start_noflag(msg,
13523 NL80211_NAN_MATCH_FUNC_LOCAL);
50bcd31d
AB
13524 if (!local_func_attr)
13525 goto nla_put_failure;
13526
13527 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
13528 goto nla_put_failure;
13529
13530 nla_nest_end(msg, local_func_attr);
13531
ae0be8de
MK
13532 peer_func_attr = nla_nest_start_noflag(msg,
13533 NL80211_NAN_MATCH_FUNC_PEER);
50bcd31d
AB
13534 if (!peer_func_attr)
13535 goto nla_put_failure;
13536
13537 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
13538 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
13539 goto nla_put_failure;
13540
13541 if (match->info && match->info_len &&
13542 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
13543 match->info))
13544 goto nla_put_failure;
13545
13546 nla_nest_end(msg, peer_func_attr);
13547 nla_nest_end(msg, match_attr);
13548 genlmsg_end(msg, hdr);
13549
13550 if (!wdev->owner_nlportid)
13551 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
13552 msg, 0, NL80211_MCGRP_NAN, gfp);
13553 else
13554 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
13555 wdev->owner_nlportid);
13556
13557 return;
13558
13559nla_put_failure:
13560 nlmsg_free(msg);
13561}
13562EXPORT_SYMBOL(cfg80211_nan_match);
13563
368e5a7b
AB
13564void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
13565 u8 inst_id,
13566 enum nl80211_nan_func_term_reason reason,
13567 u64 cookie, gfp_t gfp)
13568{
13569 struct wiphy *wiphy = wdev->wiphy;
13570 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
13571 struct sk_buff *msg;
13572 struct nlattr *func_attr;
13573 void *hdr;
13574
13575 if (WARN_ON(!inst_id))
13576 return;
13577
13578 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
13579 if (!msg)
13580 return;
13581
13582 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
13583 if (!hdr) {
13584 nlmsg_free(msg);
13585 return;
13586 }
13587
13588 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
13589 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
13590 wdev->netdev->ifindex)) ||
13591 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
13592 NL80211_ATTR_PAD))
13593 goto nla_put_failure;
13594
13595 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
13596 NL80211_ATTR_PAD))
13597 goto nla_put_failure;
13598
ae0be8de 13599 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
368e5a7b
AB
13600 if (!func_attr)
13601 goto nla_put_failure;
13602
13603 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
13604 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
13605 goto nla_put_failure;
13606
13607 nla_nest_end(msg, func_attr);
13608 genlmsg_end(msg, hdr);
13609
13610 if (!wdev->owner_nlportid)
13611 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
13612 msg, 0, NL80211_MCGRP_NAN, gfp);
13613 else
13614 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
13615 wdev->owner_nlportid);
13616
13617 return;
13618
13619nla_put_failure:
13620 nlmsg_free(msg);
13621}
13622EXPORT_SYMBOL(cfg80211_nan_func_terminated);
13623
3713b4e3
JB
13624static int nl80211_get_protocol_features(struct sk_buff *skb,
13625 struct genl_info *info)
13626{
13627 void *hdr;
13628 struct sk_buff *msg;
13629
13630 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13631 if (!msg)
13632 return -ENOMEM;
13633
13634 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13635 NL80211_CMD_GET_PROTOCOL_FEATURES);
13636 if (!hdr)
13637 goto nla_put_failure;
13638
13639 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
13640 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
13641 goto nla_put_failure;
13642
13643 genlmsg_end(msg, hdr);
13644 return genlmsg_reply(msg, info);
13645
13646 nla_put_failure:
13647 kfree_skb(msg);
13648 return -ENOBUFS;
13649}
13650
355199e0
JM
13651static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
13652{
13653 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13654 struct cfg80211_update_ft_ies_params ft_params;
13655 struct net_device *dev = info->user_ptr[1];
13656
13657 if (!rdev->ops->update_ft_ies)
13658 return -EOPNOTSUPP;
13659
13660 if (!info->attrs[NL80211_ATTR_MDID] ||
3d7af878 13661 !info->attrs[NL80211_ATTR_IE])
355199e0
JM
13662 return -EINVAL;
13663
13664 memset(&ft_params, 0, sizeof(ft_params));
13665 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
13666 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
13667 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
13668
13669 return rdev_update_ft_ies(rdev, dev, &ft_params);
13670}
13671
5de17984
AS
13672static int nl80211_crit_protocol_start(struct sk_buff *skb,
13673 struct genl_info *info)
13674{
13675 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13676 struct wireless_dev *wdev = info->user_ptr[1];
13677 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
13678 u16 duration;
13679 int ret;
13680
13681 if (!rdev->ops->crit_proto_start)
13682 return -EOPNOTSUPP;
13683
13684 if (WARN_ON(!rdev->ops->crit_proto_stop))
13685 return -EINVAL;
13686
13687 if (rdev->crit_proto_nlportid)
13688 return -EBUSY;
13689
13690 /* determine protocol if provided */
13691 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
13692 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
13693
13694 if (proto >= NUM_NL80211_CRIT_PROTO)
13695 return -EINVAL;
13696
13697 /* timeout must be provided */
13698 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
13699 return -EINVAL;
13700
13701 duration =
13702 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
13703
5de17984
AS
13704 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
13705 if (!ret)
13706 rdev->crit_proto_nlportid = info->snd_portid;
13707
13708 return ret;
13709}
13710
13711static int nl80211_crit_protocol_stop(struct sk_buff *skb,
13712 struct genl_info *info)
13713{
13714 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13715 struct wireless_dev *wdev = info->user_ptr[1];
13716
13717 if (!rdev->ops->crit_proto_stop)
13718 return -EOPNOTSUPP;
13719
13720 if (rdev->crit_proto_nlportid) {
13721 rdev->crit_proto_nlportid = 0;
13722 rdev_crit_proto_stop(rdev, wdev);
13723 }
13724 return 0;
13725}
13726
901bb989
JB
13727static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
13728 struct nlattr *attr,
13729 struct netlink_ext_ack *extack)
13730{
13731 if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
13732 if (attr->nla_type & NLA_F_NESTED) {
13733 NL_SET_ERR_MSG_ATTR(extack, attr,
13734 "unexpected nested data");
13735 return -EINVAL;
13736 }
13737
13738 return 0;
13739 }
13740
13741 if (!(attr->nla_type & NLA_F_NESTED)) {
13742 NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
13743 return -EINVAL;
13744 }
13745
32d5109a 13746 return nla_validate_nested(attr, vcmd->maxattr, vcmd->policy, extack);
901bb989
JB
13747}
13748
ad7e718c
JB
13749static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
13750{
13751 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13752 struct wireless_dev *wdev =
a05829a7
JB
13753 __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
13754 info->attrs);
ad7e718c
JB
13755 int i, err;
13756 u32 vid, subcmd;
13757
13758 if (!rdev->wiphy.vendor_commands)
13759 return -EOPNOTSUPP;
13760
13761 if (IS_ERR(wdev)) {
13762 err = PTR_ERR(wdev);
13763 if (err != -EINVAL)
13764 return err;
13765 wdev = NULL;
13766 } else if (wdev->wiphy != &rdev->wiphy) {
13767 return -EINVAL;
13768 }
13769
13770 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
13771 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
13772 return -EINVAL;
13773
13774 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
13775 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
13776 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
13777 const struct wiphy_vendor_command *vcmd;
13778 void *data = NULL;
13779 int len = 0;
13780
13781 vcmd = &rdev->wiphy.vendor_commands[i];
13782
13783 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
13784 continue;
13785
13786 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
13787 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
13788 if (!wdev)
13789 return -EINVAL;
13790 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
13791 !wdev->netdev)
13792 return -EINVAL;
13793
13794 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 13795 if (!wdev_running(wdev))
ad7e718c
JB
13796 return -ENETDOWN;
13797 }
13798 } else {
13799 wdev = NULL;
13800 }
13801
4052d3d2
JS
13802 if (!vcmd->doit)
13803 return -EOPNOTSUPP;
13804
ad7e718c
JB
13805 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
13806 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
13807 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
13808
13809 err = nl80211_vendor_check_policy(vcmd,
13810 info->attrs[NL80211_ATTR_VENDOR_DATA],
13811 info->extack);
13812 if (err)
13813 return err;
ad7e718c
JB
13814 }
13815
13816 rdev->cur_cmd_info = info;
901bb989 13817 err = vcmd->doit(&rdev->wiphy, wdev, data, len);
ad7e718c
JB
13818 rdev->cur_cmd_info = NULL;
13819 return err;
13820 }
13821
13822 return -EOPNOTSUPP;
13823}
13824
7bdbe400
JB
13825static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
13826 struct netlink_callback *cb,
13827 struct cfg80211_registered_device **rdev,
13828 struct wireless_dev **wdev)
13829{
50508d94 13830 struct nlattr **attrbuf;
7bdbe400
JB
13831 u32 vid, subcmd;
13832 unsigned int i;
13833 int vcmd_idx = -1;
13834 int err;
13835 void *data = NULL;
13836 unsigned int data_len = 0;
13837
7bdbe400
JB
13838 if (cb->args[0]) {
13839 /* subtract the 1 again here */
13840 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
13841 struct wireless_dev *tmp;
13842
ea90e0dc
JB
13843 if (!wiphy)
13844 return -ENODEV;
7bdbe400
JB
13845 *rdev = wiphy_to_rdev(wiphy);
13846 *wdev = NULL;
13847
13848 if (cb->args[1]) {
53873f13 13849 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
13850 if (tmp->identifier == cb->args[1] - 1) {
13851 *wdev = tmp;
13852 break;
13853 }
13854 }
13855 }
13856
13857 /* keep rtnl locked in successful case */
13858 return 0;
13859 }
13860
50508d94
JB
13861 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
13862 if (!attrbuf)
13863 return -ENOMEM;
13864
8cb08174
JB
13865 err = nlmsg_parse_deprecated(cb->nlh,
13866 GENL_HDRLEN + nl80211_fam.hdrsize,
13867 attrbuf, nl80211_fam.maxattr,
13868 nl80211_policy, NULL);
7bdbe400 13869 if (err)
50508d94 13870 goto out;
7bdbe400 13871
c90c39da 13872 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
50508d94
JB
13873 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
13874 err = -EINVAL;
13875 goto out;
13876 }
7bdbe400 13877
a05829a7 13878 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(skb->sk), attrbuf);
7bdbe400
JB
13879 if (IS_ERR(*wdev))
13880 *wdev = NULL;
13881
c90c39da 13882 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
50508d94
JB
13883 if (IS_ERR(*rdev)) {
13884 err = PTR_ERR(*rdev);
13885 goto out;
13886 }
7bdbe400 13887
c90c39da
JB
13888 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
13889 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
13890
13891 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
13892 const struct wiphy_vendor_command *vcmd;
13893
13894 vcmd = &(*rdev)->wiphy.vendor_commands[i];
13895
13896 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
13897 continue;
13898
50508d94
JB
13899 if (!vcmd->dumpit) {
13900 err = -EOPNOTSUPP;
13901 goto out;
13902 }
7bdbe400
JB
13903
13904 vcmd_idx = i;
13905 break;
13906 }
13907
50508d94
JB
13908 if (vcmd_idx < 0) {
13909 err = -EOPNOTSUPP;
13910 goto out;
13911 }
7bdbe400 13912
c90c39da
JB
13913 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
13914 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
13915 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
901bb989
JB
13916
13917 err = nl80211_vendor_check_policy(
13918 &(*rdev)->wiphy.vendor_commands[vcmd_idx],
13919 attrbuf[NL80211_ATTR_VENDOR_DATA],
13920 cb->extack);
13921 if (err)
50508d94 13922 goto out;
7bdbe400
JB
13923 }
13924
13925 /* 0 is the first index - add 1 to parse only once */
13926 cb->args[0] = (*rdev)->wiphy_idx + 1;
13927 /* add 1 to know if it was NULL */
13928 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
13929 cb->args[2] = vcmd_idx;
13930 cb->args[3] = (unsigned long)data;
13931 cb->args[4] = data_len;
13932
13933 /* keep rtnl locked in successful case */
50508d94
JB
13934 err = 0;
13935out:
13936 kfree(attrbuf);
13937 return err;
7bdbe400
JB
13938}
13939
13940static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
13941 struct netlink_callback *cb)
13942{
13943 struct cfg80211_registered_device *rdev;
13944 struct wireless_dev *wdev;
13945 unsigned int vcmd_idx;
13946 const struct wiphy_vendor_command *vcmd;
13947 void *data;
13948 int data_len;
13949 int err;
13950 struct nlattr *vendor_data;
13951
ea90e0dc 13952 rtnl_lock();
7bdbe400
JB
13953 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
13954 if (err)
ea90e0dc 13955 goto out;
7bdbe400
JB
13956
13957 vcmd_idx = cb->args[2];
13958 data = (void *)cb->args[3];
13959 data_len = cb->args[4];
13960 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
13961
13962 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
13963 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
13964 if (!wdev) {
13965 err = -EINVAL;
13966 goto out;
13967 }
7bdbe400 13968 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
13969 !wdev->netdev) {
13970 err = -EINVAL;
13971 goto out;
13972 }
7bdbe400
JB
13973
13974 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
13975 if (!wdev_running(wdev)) {
13976 err = -ENETDOWN;
13977 goto out;
13978 }
7bdbe400
JB
13979 }
13980 }
13981
13982 while (1) {
13983 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
13984 cb->nlh->nlmsg_seq, NLM_F_MULTI,
13985 NL80211_CMD_VENDOR);
13986 if (!hdr)
13987 break;
13988
13989 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
13990 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
13991 wdev_id(wdev),
13992 NL80211_ATTR_PAD))) {
7bdbe400
JB
13993 genlmsg_cancel(skb, hdr);
13994 break;
13995 }
13996
ae0be8de
MK
13997 vendor_data = nla_nest_start_noflag(skb,
13998 NL80211_ATTR_VENDOR_DATA);
7bdbe400
JB
13999 if (!vendor_data) {
14000 genlmsg_cancel(skb, hdr);
14001 break;
14002 }
14003
14004 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
14005 (unsigned long *)&cb->args[5]);
14006 nla_nest_end(skb, vendor_data);
14007
14008 if (err == -ENOBUFS || err == -ENOENT) {
14009 genlmsg_cancel(skb, hdr);
14010 break;
9c167b2d 14011 } else if (err <= 0) {
7bdbe400
JB
14012 genlmsg_cancel(skb, hdr);
14013 goto out;
14014 }
14015
14016 genlmsg_end(skb, hdr);
14017 }
14018
14019 err = skb->len;
14020 out:
14021 rtnl_unlock();
14022 return err;
14023}
14024
ad7e718c
JB
14025struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
14026 enum nl80211_commands cmd,
14027 enum nl80211_attrs attr,
14028 int approxlen)
14029{
f26cbf40 14030 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
14031
14032 if (WARN_ON(!rdev->cur_cmd_info))
14033 return NULL;
14034
6c09e791 14035 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
14036 rdev->cur_cmd_info->snd_portid,
14037 rdev->cur_cmd_info->snd_seq,
567ffc35 14038 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
14039}
14040EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
14041
14042int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
14043{
14044 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
14045 void *hdr = ((void **)skb->cb)[1];
14046 struct nlattr *data = ((void **)skb->cb)[2];
14047
bd8c78e7
JB
14048 /* clear CB data for netlink core to own from now on */
14049 memset(skb->cb, 0, sizeof(skb->cb));
14050
ad7e718c
JB
14051 if (WARN_ON(!rdev->cur_cmd_info)) {
14052 kfree_skb(skb);
14053 return -EINVAL;
14054 }
14055
14056 nla_nest_end(skb, data);
14057 genlmsg_end(skb, hdr);
14058 return genlmsg_reply(skb, rdev->cur_cmd_info);
14059}
14060EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
14061
55c1fdf0
JB
14062unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy)
14063{
14064 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14065
14066 if (WARN_ON(!rdev->cur_cmd_info))
14067 return 0;
14068
14069 return rdev->cur_cmd_info->snd_portid;
14070}
14071EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender);
14072
fa9ffc74
KP
14073static int nl80211_set_qos_map(struct sk_buff *skb,
14074 struct genl_info *info)
14075{
14076 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14077 struct cfg80211_qos_map *qos_map = NULL;
14078 struct net_device *dev = info->user_ptr[1];
14079 u8 *pos, len, num_des, des_len, des;
14080 int ret;
14081
14082 if (!rdev->ops->set_qos_map)
14083 return -EOPNOTSUPP;
14084
14085 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
14086 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
14087 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
14088
c8b82802 14089 if (len % 2)
fa9ffc74
KP
14090 return -EINVAL;
14091
14092 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
14093 if (!qos_map)
14094 return -ENOMEM;
14095
14096 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
14097 if (num_des) {
14098 des_len = num_des *
14099 sizeof(struct cfg80211_dscp_exception);
14100 memcpy(qos_map->dscp_exception, pos, des_len);
14101 qos_map->num_des = num_des;
14102 for (des = 0; des < num_des; des++) {
14103 if (qos_map->dscp_exception[des].up > 7) {
14104 kfree(qos_map);
14105 return -EINVAL;
14106 }
14107 }
14108 pos += des_len;
14109 }
14110 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
14111 }
14112
14113 wdev_lock(dev->ieee80211_ptr);
14114 ret = nl80211_key_allowed(dev->ieee80211_ptr);
14115 if (!ret)
14116 ret = rdev_set_qos_map(rdev, dev, qos_map);
14117 wdev_unlock(dev->ieee80211_ptr);
14118
14119 kfree(qos_map);
14120 return ret;
14121}
14122
960d01ac
JB
14123static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
14124{
14125 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14126 struct net_device *dev = info->user_ptr[1];
14127 struct wireless_dev *wdev = dev->ieee80211_ptr;
14128 const u8 *peer;
14129 u8 tsid, up;
14130 u16 admitted_time = 0;
14131 int err;
14132
723e73ac 14133 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
14134 return -EOPNOTSUPP;
14135
14136 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
14137 !info->attrs[NL80211_ATTR_USER_PRIO])
14138 return -EINVAL;
14139
14140 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
960d01ac 14141 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
960d01ac
JB
14142
14143 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 14144 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 14145 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
14146 * need more attributes for that (e.g. BA session requirement);
14147 * change the WMM adminssion test above to allow both then
960d01ac
JB
14148 */
14149 return -EINVAL;
14150 }
14151
14152 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14153
14154 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
14155 admitted_time =
14156 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
14157 if (!admitted_time)
14158 return -EINVAL;
14159 }
14160
14161 wdev_lock(wdev);
14162 switch (wdev->iftype) {
14163 case NL80211_IFTYPE_STATION:
14164 case NL80211_IFTYPE_P2P_CLIENT:
14165 if (wdev->current_bss)
14166 break;
14167 err = -ENOTCONN;
14168 goto out;
14169 default:
14170 err = -EOPNOTSUPP;
14171 goto out;
14172 }
14173
14174 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
14175
14176 out:
14177 wdev_unlock(wdev);
14178 return err;
14179}
14180
14181static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
14182{
14183 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14184 struct net_device *dev = info->user_ptr[1];
14185 struct wireless_dev *wdev = dev->ieee80211_ptr;
14186 const u8 *peer;
14187 u8 tsid;
14188 int err;
14189
14190 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
14191 return -EINVAL;
14192
14193 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
14194 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14195
14196 wdev_lock(wdev);
14197 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
14198 wdev_unlock(wdev);
14199
14200 return err;
14201}
14202
1057d35e
AN
14203static int nl80211_tdls_channel_switch(struct sk_buff *skb,
14204 struct genl_info *info)
14205{
14206 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14207 struct net_device *dev = info->user_ptr[1];
14208 struct wireless_dev *wdev = dev->ieee80211_ptr;
14209 struct cfg80211_chan_def chandef = {};
14210 const u8 *addr;
14211 u8 oper_class;
14212 int err;
14213
14214 if (!rdev->ops->tdls_channel_switch ||
14215 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
14216 return -EOPNOTSUPP;
14217
14218 switch (dev->ieee80211_ptr->iftype) {
14219 case NL80211_IFTYPE_STATION:
14220 case NL80211_IFTYPE_P2P_CLIENT:
14221 break;
14222 default:
14223 return -EOPNOTSUPP;
14224 }
14225
14226 if (!info->attrs[NL80211_ATTR_MAC] ||
14227 !info->attrs[NL80211_ATTR_OPER_CLASS])
14228 return -EINVAL;
14229
14230 err = nl80211_parse_chandef(rdev, info, &chandef);
14231 if (err)
14232 return err;
14233
14234 /*
14235 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
14236 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
14237 * specification is not defined for them.
14238 */
57fbcce3 14239 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
14240 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
14241 chandef.width != NL80211_CHAN_WIDTH_20)
14242 return -EINVAL;
14243
14244 /* we will be active on the TDLS link */
923b352f
AN
14245 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
14246 wdev->iftype))
1057d35e
AN
14247 return -EINVAL;
14248
14249 /* don't allow switching to DFS channels */
14250 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
14251 return -EINVAL;
14252
14253 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
14254 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
14255
14256 wdev_lock(wdev);
14257 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
14258 wdev_unlock(wdev);
14259
14260 return err;
14261}
14262
14263static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
14264 struct genl_info *info)
14265{
14266 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14267 struct net_device *dev = info->user_ptr[1];
14268 struct wireless_dev *wdev = dev->ieee80211_ptr;
14269 const u8 *addr;
14270
14271 if (!rdev->ops->tdls_channel_switch ||
14272 !rdev->ops->tdls_cancel_channel_switch ||
14273 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
14274 return -EOPNOTSUPP;
14275
14276 switch (dev->ieee80211_ptr->iftype) {
14277 case NL80211_IFTYPE_STATION:
14278 case NL80211_IFTYPE_P2P_CLIENT:
14279 break;
14280 default:
14281 return -EOPNOTSUPP;
14282 }
14283
14284 if (!info->attrs[NL80211_ATTR_MAC])
14285 return -EINVAL;
14286
14287 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
14288
14289 wdev_lock(wdev);
14290 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
14291 wdev_unlock(wdev);
14292
14293 return 0;
14294}
14295
ce0ce13a
MB
14296static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
14297 struct genl_info *info)
14298{
14299 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14300 struct net_device *dev = info->user_ptr[1];
14301 struct wireless_dev *wdev = dev->ieee80211_ptr;
14302 const struct nlattr *nla;
14303 bool enabled;
14304
ce0ce13a
MB
14305 if (!rdev->ops->set_multicast_to_unicast)
14306 return -EOPNOTSUPP;
14307
14308 if (wdev->iftype != NL80211_IFTYPE_AP &&
14309 wdev->iftype != NL80211_IFTYPE_P2P_GO)
14310 return -EOPNOTSUPP;
14311
14312 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
14313 enabled = nla_get_flag(nla);
14314
14315 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
14316}
14317
3a00df57
AS
14318static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
14319{
14320 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14321 struct net_device *dev = info->user_ptr[1];
14322 struct wireless_dev *wdev = dev->ieee80211_ptr;
14323 struct cfg80211_pmk_conf pmk_conf = {};
14324 int ret;
14325
14326 if (wdev->iftype != NL80211_IFTYPE_STATION &&
14327 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
14328 return -EOPNOTSUPP;
14329
14330 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14331 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
14332 return -EOPNOTSUPP;
14333
14334 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
14335 return -EINVAL;
14336
14337 wdev_lock(wdev);
14338 if (!wdev->current_bss) {
14339 ret = -ENOTCONN;
14340 goto out;
14341 }
14342
14343 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
14344 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
14345 ret = -EINVAL;
14346 goto out;
14347 }
14348
14349 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
14350 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
14351 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
14352 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
14353 ret = -EINVAL;
14354 goto out;
14355 }
14356
cb9abd48 14357 if (info->attrs[NL80211_ATTR_PMKR0_NAME])
3a00df57
AS
14358 pmk_conf.pmk_r0_name =
14359 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
3a00df57
AS
14360
14361 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
14362out:
14363 wdev_unlock(wdev);
14364 return ret;
14365}
14366
14367static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
14368{
14369 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14370 struct net_device *dev = info->user_ptr[1];
14371 struct wireless_dev *wdev = dev->ieee80211_ptr;
14372 const u8 *aa;
14373 int ret;
14374
14375 if (wdev->iftype != NL80211_IFTYPE_STATION &&
14376 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
14377 return -EOPNOTSUPP;
14378
14379 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14380 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
14381 return -EOPNOTSUPP;
14382
14383 if (!info->attrs[NL80211_ATTR_MAC])
14384 return -EINVAL;
14385
14386 wdev_lock(wdev);
14387 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
14388 ret = rdev_del_pmk(rdev, dev, aa);
14389 wdev_unlock(wdev);
14390
14391 return ret;
14392}
14393
40cbfa90
SD
14394static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
14395{
14396 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14397 struct net_device *dev = info->user_ptr[1];
14398 struct cfg80211_external_auth_params params;
14399
db8d93a7 14400 if (!rdev->ops->external_auth)
40cbfa90
SD
14401 return -EOPNOTSUPP;
14402
fe494370
SD
14403 if (!info->attrs[NL80211_ATTR_SSID] &&
14404 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
14405 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
40cbfa90
SD
14406 return -EINVAL;
14407
14408 if (!info->attrs[NL80211_ATTR_BSSID])
14409 return -EINVAL;
14410
14411 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
14412 return -EINVAL;
14413
14414 memset(&params, 0, sizeof(params));
14415
fe494370
SD
14416 if (info->attrs[NL80211_ATTR_SSID]) {
14417 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
cb9abd48 14418 if (params.ssid.ssid_len == 0)
fe494370
SD
14419 return -EINVAL;
14420 memcpy(params.ssid.ssid,
14421 nla_data(info->attrs[NL80211_ATTR_SSID]),
14422 params.ssid.ssid_len);
14423 }
40cbfa90
SD
14424
14425 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
14426 ETH_ALEN);
14427
14428 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
14429
fe494370
SD
14430 if (info->attrs[NL80211_ATTR_PMKID])
14431 params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
14432
40cbfa90
SD
14433 return rdev_external_auth(rdev, dev, &params);
14434}
14435
2576a9ac
DK
14436static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
14437{
dca9ca2d 14438 bool dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
2576a9ac
DK
14439 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14440 struct net_device *dev = info->user_ptr[1];
14441 struct wireless_dev *wdev = dev->ieee80211_ptr;
14442 const u8 *buf;
14443 size_t len;
14444 u8 *dest;
14445 u16 proto;
14446 bool noencrypt;
dca9ca2d 14447 u64 cookie = 0;
2576a9ac
DK
14448 int err;
14449
14450 if (!wiphy_ext_feature_isset(&rdev->wiphy,
14451 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
14452 return -EOPNOTSUPP;
14453
14454 if (!rdev->ops->tx_control_port)
14455 return -EOPNOTSUPP;
14456
14457 if (!info->attrs[NL80211_ATTR_FRAME] ||
14458 !info->attrs[NL80211_ATTR_MAC] ||
14459 !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
14460 GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
14461 return -EINVAL;
14462 }
14463
14464 wdev_lock(wdev);
14465
14466 switch (wdev->iftype) {
14467 case NL80211_IFTYPE_AP:
14468 case NL80211_IFTYPE_P2P_GO:
14469 case NL80211_IFTYPE_MESH_POINT:
14470 break;
14471 case NL80211_IFTYPE_ADHOC:
14472 case NL80211_IFTYPE_STATION:
14473 case NL80211_IFTYPE_P2P_CLIENT:
14474 if (wdev->current_bss)
14475 break;
14476 err = -ENOTCONN;
14477 goto out;
14478 default:
14479 err = -EOPNOTSUPP;
14480 goto out;
14481 }
14482
14483 wdev_unlock(wdev);
14484
14485 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
14486 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
14487 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
14488 proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
14489 noencrypt =
14490 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
14491
dca9ca2d
MT
14492 err = rdev_tx_control_port(rdev, dev, buf, len,
14493 dest, cpu_to_be16(proto), noencrypt,
14494 dont_wait_for_ack ? NULL : &cookie);
14495 if (!err && !dont_wait_for_ack)
14496 nl_set_extack_cookie_u64(info->extack, cookie);
14497 return err;
2576a9ac
DK
14498 out:
14499 wdev_unlock(wdev);
14500 return err;
14501}
14502
81e54d08
PKC
14503static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
14504 struct genl_info *info)
14505{
14506 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14507 struct net_device *dev = info->user_ptr[1];
14508 struct wireless_dev *wdev = dev->ieee80211_ptr;
14509 struct cfg80211_ftm_responder_stats ftm_stats = {};
14510 struct sk_buff *msg;
14511 void *hdr;
14512 struct nlattr *ftm_stats_attr;
14513 int err;
14514
14515 if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval)
14516 return -EOPNOTSUPP;
14517
14518 err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
14519 if (err)
14520 return err;
14521
14522 if (!ftm_stats.filled)
14523 return -ENODATA;
14524
14525 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14526 if (!msg)
14527 return -ENOMEM;
14528
14529 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
14530 NL80211_CMD_GET_FTM_RESPONDER_STATS);
14531 if (!hdr)
1399c59f 14532 goto nla_put_failure;
81e54d08
PKC
14533
14534 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
14535 goto nla_put_failure;
14536
ae0be8de
MK
14537 ftm_stats_attr = nla_nest_start_noflag(msg,
14538 NL80211_ATTR_FTM_RESPONDER_STATS);
81e54d08
PKC
14539 if (!ftm_stats_attr)
14540 goto nla_put_failure;
14541
14542#define SET_FTM(field, name, type) \
14543 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
14544 nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name, \
14545 ftm_stats.field)) \
14546 goto nla_put_failure; } while (0)
14547#define SET_FTM_U64(field, name) \
14548 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
14549 nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name, \
14550 ftm_stats.field, NL80211_FTM_STATS_PAD)) \
14551 goto nla_put_failure; } while (0)
14552
14553 SET_FTM(success_num, SUCCESS_NUM, u32);
14554 SET_FTM(partial_num, PARTIAL_NUM, u32);
14555 SET_FTM(failed_num, FAILED_NUM, u32);
14556 SET_FTM(asap_num, ASAP_NUM, u32);
14557 SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
14558 SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
14559 SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
14560 SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
14561 SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
14562#undef SET_FTM
14563
14564 nla_nest_end(msg, ftm_stats_attr);
14565
14566 genlmsg_end(msg, hdr);
14567 return genlmsg_reply(msg, info);
14568
14569nla_put_failure:
14570 nlmsg_free(msg);
14571 return -ENOBUFS;
14572}
14573
cb74e977
SD
14574static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
14575{
14576 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14577 struct cfg80211_update_owe_info owe_info;
14578 struct net_device *dev = info->user_ptr[1];
14579
14580 if (!rdev->ops->update_owe_info)
14581 return -EOPNOTSUPP;
14582
14583 if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
14584 !info->attrs[NL80211_ATTR_MAC])
14585 return -EINVAL;
14586
14587 memset(&owe_info, 0, sizeof(owe_info));
14588 owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
14589 nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
14590
14591 if (info->attrs[NL80211_ATTR_IE]) {
14592 owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
14593 owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
14594 }
14595
14596 return rdev_update_owe_info(rdev, dev, &owe_info);
14597}
14598
5ab92e7f
RM
14599static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
14600{
14601 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14602 struct net_device *dev = info->user_ptr[1];
14603 struct wireless_dev *wdev = dev->ieee80211_ptr;
14604 struct station_info sinfo = {};
14605 const u8 *buf;
14606 size_t len;
14607 u8 *dest;
14608 int err;
14609
14610 if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
14611 return -EOPNOTSUPP;
14612
14613 if (!info->attrs[NL80211_ATTR_MAC] ||
14614 !info->attrs[NL80211_ATTR_FRAME]) {
14615 GENL_SET_ERR_MSG(info, "Frame or MAC missing");
14616 return -EINVAL;
14617 }
14618
14619 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
14620 return -EOPNOTSUPP;
14621
14622 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
14623 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
14624 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
14625
14626 if (len < sizeof(struct ethhdr))
14627 return -EINVAL;
14628
14629 if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
14630 !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
14631 return -EINVAL;
14632
14633 err = rdev_get_station(rdev, dev, dest, &sinfo);
14634 if (err)
14635 return err;
14636
2a279b34
FF
14637 cfg80211_sinfo_release_content(&sinfo);
14638
5ab92e7f
RM
14639 return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
14640}
14641
77f576de
T
14642static int parse_tid_conf(struct cfg80211_registered_device *rdev,
14643 struct nlattr *attrs[], struct net_device *dev,
3710a8a6 14644 struct cfg80211_tid_cfg *tid_conf,
77f576de
T
14645 struct genl_info *info, const u8 *peer)
14646{
14647 struct netlink_ext_ack *extack = info->extack;
3710a8a6 14648 u64 mask;
77f576de
T
14649 int err;
14650
14651 if (!attrs[NL80211_TID_CONFIG_ATTR_TIDS])
14652 return -EINVAL;
14653
14654 tid_conf->config_override =
14655 nla_get_flag(attrs[NL80211_TID_CONFIG_ATTR_OVERRIDE]);
3710a8a6 14656 tid_conf->tids = nla_get_u16(attrs[NL80211_TID_CONFIG_ATTR_TIDS]);
77f576de
T
14657
14658 if (tid_conf->config_override) {
14659 if (rdev->ops->reset_tid_config) {
14660 err = rdev_reset_tid_config(rdev, dev, peer,
3710a8a6 14661 tid_conf->tids);
c0336955 14662 if (err)
77f576de
T
14663 return err;
14664 } else {
14665 return -EINVAL;
14666 }
14667 }
14668
14669 if (attrs[NL80211_TID_CONFIG_ATTR_NOACK]) {
3710a8a6 14670 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_NOACK);
77f576de
T
14671 tid_conf->noack =
14672 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_NOACK]);
14673 }
14674
6a21d16c
T
14675 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]) {
14676 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT);
14677 tid_conf->retry_short =
14678 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]);
14679
14680 if (tid_conf->retry_short > rdev->wiphy.max_data_retry_count)
14681 return -EINVAL;
14682 }
14683
14684 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]) {
14685 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
14686 tid_conf->retry_long =
14687 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]);
14688
14689 if (tid_conf->retry_long > rdev->wiphy.max_data_retry_count)
14690 return -EINVAL;
14691 }
14692
ade274b2
T
14693 if (attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]) {
14694 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
14695 tid_conf->ampdu =
14696 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]);
14697 }
14698
04f7d142
T
14699 if (attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]) {
14700 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
14701 tid_conf->rtscts =
14702 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]);
14703 }
14704
33462e68
SM
14705 if (attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]) {
14706 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL);
14707 tid_conf->amsdu =
14708 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]);
14709 }
14710
9a5f6488
TC
14711 if (attrs[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE]) {
14712 u32 idx = NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, attr;
14713
14714 tid_conf->txrate_type = nla_get_u8(attrs[idx]);
14715
14716 if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) {
14717 attr = NL80211_TID_CONFIG_ATTR_TX_RATE;
14718 err = nl80211_parse_tx_bitrate_mask(info, attrs, attr,
857b34c4
RM
14719 &tid_conf->txrate_mask, dev,
14720 true);
9a5f6488
TC
14721 if (err)
14722 return err;
14723
14724 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE);
14725 }
14726 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);
14727 }
14728
3710a8a6
JB
14729 if (peer)
14730 mask = rdev->wiphy.tid_config_support.peer;
14731 else
14732 mask = rdev->wiphy.tid_config_support.vif;
14733
14734 if (tid_conf->mask & ~mask) {
14735 NL_SET_ERR_MSG(extack, "unsupported TID configuration");
14736 return -ENOTSUPP;
14737 }
14738
77f576de
T
14739 return 0;
14740}
14741
14742static int nl80211_set_tid_config(struct sk_buff *skb,
14743 struct genl_info *info)
14744{
14745 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14746 struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1];
14747 struct net_device *dev = info->user_ptr[1];
3710a8a6 14748 struct cfg80211_tid_config *tid_config;
77f576de
T
14749 struct nlattr *tid;
14750 int conf_idx = 0, rem_conf;
14751 int ret = -EINVAL;
14752 u32 num_conf = 0;
14753
14754 if (!info->attrs[NL80211_ATTR_TID_CONFIG])
14755 return -EINVAL;
14756
14757 if (!rdev->ops->set_tid_config)
14758 return -EOPNOTSUPP;
14759
14760 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
14761 rem_conf)
14762 num_conf++;
14763
14764 tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf),
14765 GFP_KERNEL);
14766 if (!tid_config)
14767 return -ENOMEM;
14768
14769 tid_config->n_tid_conf = num_conf;
14770
14771 if (info->attrs[NL80211_ATTR_MAC])
14772 tid_config->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
14773
14774 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
14775 rem_conf) {
14776 ret = nla_parse_nested(attrs, NL80211_TID_CONFIG_ATTR_MAX,
14777 tid, NULL, NULL);
14778
14779 if (ret)
14780 goto bad_tid_conf;
14781
14782 ret = parse_tid_conf(rdev, attrs, dev,
14783 &tid_config->tid_conf[conf_idx],
14784 info, tid_config->peer);
14785 if (ret)
14786 goto bad_tid_conf;
14787
14788 conf_idx++;
14789 }
14790
14791 ret = rdev_set_tid_config(rdev, dev, tid_config);
14792
14793bad_tid_conf:
14794 kfree(tid_config);
14795 return ret;
14796}
14797
4c476991
JB
14798#define NL80211_FLAG_NEED_WIPHY 0x01
14799#define NL80211_FLAG_NEED_NETDEV 0x02
14800#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
14801#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
14802#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
14803 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 14804#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 14805/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
14806#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
14807 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 14808#define NL80211_FLAG_CLEAR_SKB 0x20
77cbf790 14809#define NL80211_FLAG_NO_WIPHY_MTX 0x40
4c476991 14810
f84f771d 14811static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
14812 struct genl_info *info)
14813{
a05829a7 14814 struct cfg80211_registered_device *rdev = NULL;
89a54e48 14815 struct wireless_dev *wdev;
4c476991 14816 struct net_device *dev;
4c476991 14817
a05829a7 14818 rtnl_lock();
4c476991 14819 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 14820 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991 14821 if (IS_ERR(rdev)) {
a05829a7 14822 rtnl_unlock();
4c476991
JB
14823 return PTR_ERR(rdev);
14824 }
14825 info->user_ptr[0] = rdev;
1bf614ef
JB
14826 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
14827 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
a05829a7 14828 wdev = __cfg80211_wdev_from_attrs(NULL, genl_info_net(info),
89a54e48
JB
14829 info->attrs);
14830 if (IS_ERR(wdev)) {
a05829a7 14831 rtnl_unlock();
89a54e48 14832 return PTR_ERR(wdev);
4c476991 14833 }
89a54e48 14834
89a54e48 14835 dev = wdev->netdev;
f26cbf40 14836 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 14837
1bf614ef
JB
14838 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
14839 if (!dev) {
a05829a7 14840 rtnl_unlock();
1bf614ef
JB
14841 return -EINVAL;
14842 }
14843
14844 info->user_ptr[1] = dev;
14845 } else {
14846 info->user_ptr[1] = wdev;
41265714 14847 }
1bf614ef 14848
73c7da3d
AVS
14849 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
14850 !wdev_running(wdev)) {
a05829a7 14851 rtnl_unlock();
73c7da3d
AVS
14852 return -ENETDOWN;
14853 }
1bf614ef 14854
73c7da3d 14855 if (dev)
1bf614ef 14856 dev_hold(dev);
89a54e48 14857
4c476991 14858 info->user_ptr[0] = rdev;
4c476991
JB
14859 }
14860
77cbf790 14861 if (rdev && !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
a05829a7
JB
14862 wiphy_lock(&rdev->wiphy);
14863 /* we keep the mutex locked until post_doit */
14864 __release(&rdev->wiphy.mtx);
14865 }
14866 if (!(ops->internal_flags & NL80211_FLAG_NEED_RTNL))
14867 rtnl_unlock();
14868
4c476991
JB
14869 return 0;
14870}
14871
f84f771d 14872static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
14873 struct genl_info *info)
14874{
1bf614ef
JB
14875 if (info->user_ptr[1]) {
14876 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
14877 struct wireless_dev *wdev = info->user_ptr[1];
14878
14879 if (wdev->netdev)
14880 dev_put(wdev->netdev);
14881 } else {
14882 dev_put(info->user_ptr[1]);
14883 }
14884 }
5393b917 14885
77cbf790
JB
14886 if (info->user_ptr[0] &&
14887 !(ops->internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
a05829a7
JB
14888 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14889
14890 /* we kept the mutex locked since pre_doit */
14891 __acquire(&rdev->wiphy.mtx);
14892 wiphy_unlock(&rdev->wiphy);
14893 }
14894
4c476991
JB
14895 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
14896 rtnl_unlock();
5393b917
JB
14897
14898 /* If needed, clear the netlink message payload from the SKB
14899 * as it might contain key data that shouldn't stick around on
14900 * the heap after the SKB is freed. The netlink message header
14901 * is still needed for further processing, so leave it intact.
14902 */
14903 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
14904 struct nlmsghdr *nlh = nlmsg_hdr(skb);
14905
14906 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
14907 }
4c476991
JB
14908}
14909
6bdb68ce
CH
14910static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
14911 struct cfg80211_sar_specs *sar_specs,
14912 struct nlattr *spec[], int index)
14913{
14914 u32 range_index, i;
14915
14916 if (!sar_specs || !spec)
14917 return -EINVAL;
14918
14919 if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
14920 !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
14921 return -EINVAL;
14922
14923 range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
14924
14925 /* check if range_index exceeds num_freq_ranges */
14926 if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
14927 return -EINVAL;
14928
14929 /* check if range_index duplicates */
14930 for (i = 0; i < index; i++) {
14931 if (sar_specs->sub_specs[i].freq_range_index == range_index)
14932 return -EINVAL;
14933 }
14934
14935 sar_specs->sub_specs[index].power =
14936 nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
14937
14938 sar_specs->sub_specs[index].freq_range_index = range_index;
14939
14940 return 0;
14941}
14942
14943static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
14944{
14945 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14946 struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
14947 struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
14948 struct cfg80211_sar_specs *sar_spec;
14949 enum nl80211_sar_type type;
14950 struct nlattr *spec_list;
14951 u32 specs;
14952 int rem, err;
14953
14954 if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
14955 return -EOPNOTSUPP;
14956
14957 if (!info->attrs[NL80211_ATTR_SAR_SPEC])
14958 return -EINVAL;
14959
14960 nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
14961 info->attrs[NL80211_ATTR_SAR_SPEC],
14962 NULL, NULL);
14963
14964 if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
14965 return -EINVAL;
14966
14967 type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
14968 if (type != rdev->wiphy.sar_capa->type)
14969 return -EINVAL;
14970
14971 specs = 0;
14972 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
14973 specs++;
14974
14975 if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
14976 return -EINVAL;
14977
14978 sar_spec = kzalloc(sizeof(*sar_spec) +
14979 specs * sizeof(struct cfg80211_sar_sub_specs),
14980 GFP_KERNEL);
14981 if (!sar_spec)
14982 return -ENOMEM;
14983
14984 sar_spec->type = type;
14985 specs = 0;
14986 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
14987 nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
14988 spec_list, NULL, NULL);
14989
14990 switch (type) {
14991 case NL80211_SAR_TYPE_POWER:
14992 if (nl80211_set_sar_sub_specs(rdev, sar_spec,
14993 spec, specs)) {
14994 err = -EINVAL;
14995 goto error;
14996 }
14997 break;
14998 default:
14999 err = -EINVAL;
15000 goto error;
15001 }
15002 specs++;
15003 }
15004
15005 sar_spec->num_sub_specs = specs;
15006
15007 rdev->cur_cmd_info = info;
15008 err = rdev_set_sar_specs(rdev, sar_spec);
15009 rdev->cur_cmd_info = NULL;
15010error:
15011 kfree(sar_spec);
15012 return err;
15013}
15014
4534de83 15015static const struct genl_ops nl80211_ops[] = {
55682965
JB
15016 {
15017 .cmd = NL80211_CMD_GET_WIPHY,
ef6243ac 15018 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
15019 .doit = nl80211_get_wiphy,
15020 .dumpit = nl80211_dump_wiphy,
86e8cf98 15021 .done = nl80211_dump_wiphy_done,
55682965 15022 /* can be retrieved by unprivileged users */
a05829a7 15023 .internal_flags = NL80211_FLAG_NEED_WIPHY,
55682965 15024 },
66a9b928
JK
15025};
15026
15027static const struct genl_small_ops nl80211_small_ops[] = {
55682965
JB
15028 {
15029 .cmd = NL80211_CMD_SET_WIPHY,
ef6243ac 15030 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15031 .doit = nl80211_set_wiphy,
5617c6cd 15032 .flags = GENL_UNS_ADMIN_PERM,
55682965
JB
15033 },
15034 {
15035 .cmd = NL80211_CMD_GET_INTERFACE,
ef6243ac 15036 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
15037 .doit = nl80211_get_interface,
15038 .dumpit = nl80211_dump_interface,
55682965 15039 /* can be retrieved by unprivileged users */
a05829a7 15040 .internal_flags = NL80211_FLAG_NEED_WDEV,
55682965
JB
15041 },
15042 {
15043 .cmd = NL80211_CMD_SET_INTERFACE,
ef6243ac 15044 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15045 .doit = nl80211_set_interface,
5617c6cd 15046 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
15047 .internal_flags = NL80211_FLAG_NEED_NETDEV |
15048 NL80211_FLAG_NEED_RTNL,
55682965
JB
15049 },
15050 {
15051 .cmd = NL80211_CMD_NEW_INTERFACE,
ef6243ac 15052 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15053 .doit = nl80211_new_interface,
5617c6cd 15054 .flags = GENL_UNS_ADMIN_PERM,
4c476991 15055 .internal_flags = NL80211_FLAG_NEED_WIPHY |
ea6b2098
JB
15056 NL80211_FLAG_NEED_RTNL |
15057 /* we take the wiphy mutex later ourselves */
15058 NL80211_FLAG_NO_WIPHY_MTX,
55682965
JB
15059 },
15060 {
15061 .cmd = NL80211_CMD_DEL_INTERFACE,
ef6243ac 15062 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 15063 .doit = nl80211_del_interface,
5617c6cd 15064 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 15065 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 15066 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
15067 },
15068 {
15069 .cmd = NL80211_CMD_GET_KEY,
ef6243ac 15070 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15071 .doit = nl80211_get_key,
5617c6cd 15072 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15073 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
41ade00f
JB
15074 },
15075 {
15076 .cmd = NL80211_CMD_SET_KEY,
ef6243ac 15077 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15078 .doit = nl80211_set_key,
5617c6cd 15079 .flags = GENL_UNS_ADMIN_PERM,
41265714 15080 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917 15081 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
15082 },
15083 {
15084 .cmd = NL80211_CMD_NEW_KEY,
ef6243ac 15085 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15086 .doit = nl80211_new_key,
5617c6cd 15087 .flags = GENL_UNS_ADMIN_PERM,
41265714 15088 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917 15089 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
15090 },
15091 {
15092 .cmd = NL80211_CMD_DEL_KEY,
ef6243ac 15093 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 15094 .doit = nl80211_del_key,
5617c6cd 15095 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15096 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
55682965 15097 },
ed1b6cc7
JB
15098 {
15099 .cmd = NL80211_CMD_SET_BEACON,
ef6243ac 15100 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15101 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15102 .doit = nl80211_set_beacon,
a05829a7 15103 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7
JB
15104 },
15105 {
8860020e 15106 .cmd = NL80211_CMD_START_AP,
ef6243ac 15107 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15108 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15109 .doit = nl80211_start_ap,
a05829a7 15110 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7
JB
15111 },
15112 {
8860020e 15113 .cmd = NL80211_CMD_STOP_AP,
ef6243ac 15114 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 15115 .flags = GENL_UNS_ADMIN_PERM,
8860020e 15116 .doit = nl80211_stop_ap,
a05829a7 15117 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
ed1b6cc7 15118 },
5727ef1b
JB
15119 {
15120 .cmd = NL80211_CMD_GET_STATION,
ef6243ac 15121 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15122 .doit = nl80211_get_station,
2ec600d6 15123 .dumpit = nl80211_dump_station,
a05829a7 15124 .internal_flags = NL80211_FLAG_NEED_NETDEV,
5727ef1b
JB
15125 },
15126 {
15127 .cmd = NL80211_CMD_SET_STATION,
ef6243ac 15128 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15129 .doit = nl80211_set_station,
5617c6cd 15130 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15131 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5727ef1b
JB
15132 },
15133 {
15134 .cmd = NL80211_CMD_NEW_STATION,
ef6243ac 15135 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15136 .doit = nl80211_new_station,
5617c6cd 15137 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15138 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5727ef1b
JB
15139 },
15140 {
15141 .cmd = NL80211_CMD_DEL_STATION,
ef6243ac 15142 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 15143 .doit = nl80211_del_station,
5617c6cd 15144 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15145 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15146 },
15147 {
15148 .cmd = NL80211_CMD_GET_MPATH,
ef6243ac 15149 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6
LCC
15150 .doit = nl80211_get_mpath,
15151 .dumpit = nl80211_dump_mpath,
5617c6cd 15152 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15153 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6 15154 },
66be7d2b
HR
15155 {
15156 .cmd = NL80211_CMD_GET_MPP,
ef6243ac 15157 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
66be7d2b
HR
15158 .doit = nl80211_get_mpp,
15159 .dumpit = nl80211_dump_mpp,
5617c6cd 15160 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15161 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
66be7d2b 15162 },
2ec600d6
LCC
15163 {
15164 .cmd = NL80211_CMD_SET_MPATH,
ef6243ac 15165 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15166 .doit = nl80211_set_mpath,
5617c6cd 15167 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15168 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15169 },
15170 {
15171 .cmd = NL80211_CMD_NEW_MPATH,
ef6243ac 15172 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15173 .doit = nl80211_new_mpath,
5617c6cd 15174 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15175 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2ec600d6
LCC
15176 },
15177 {
15178 .cmd = NL80211_CMD_DEL_MPATH,
ef6243ac 15179 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 15180 .doit = nl80211_del_mpath,
5617c6cd 15181 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15182 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
9f1ba906
JM
15183 },
15184 {
15185 .cmd = NL80211_CMD_SET_BSS,
ef6243ac 15186 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9f1ba906 15187 .doit = nl80211_set_bss,
5617c6cd 15188 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15189 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
b2e1b302 15190 },
f130347c
LR
15191 {
15192 .cmd = NL80211_CMD_GET_REG,
ef6243ac 15193 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad30ca2c
AN
15194 .doit = nl80211_get_reg_do,
15195 .dumpit = nl80211_get_reg_dump,
a05829a7 15196 .internal_flags = 0,
f130347c
LR
15197 /* can be retrieved by unprivileged users */
15198 },
b6863036 15199#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
15200 {
15201 .cmd = NL80211_CMD_SET_REG,
ef6243ac 15202 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 15203 .doit = nl80211_set_reg,
b2e1b302 15204 .flags = GENL_ADMIN_PERM,
a05829a7 15205 .internal_flags = 0,
b2e1b302 15206 },
b6863036 15207#endif
b2e1b302
LR
15208 {
15209 .cmd = NL80211_CMD_REQ_SET_REG,
ef6243ac 15210 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 15211 .doit = nl80211_req_set_reg,
93da9cc1 15212 .flags = GENL_ADMIN_PERM,
15213 },
1ea4ff3e
JB
15214 {
15215 .cmd = NL80211_CMD_RELOAD_REGDB,
ef6243ac 15216 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1ea4ff3e 15217 .doit = nl80211_reload_regdb,
1ea4ff3e
JB
15218 .flags = GENL_ADMIN_PERM,
15219 },
93da9cc1 15220 {
24bdd9f4 15221 .cmd = NL80211_CMD_GET_MESH_CONFIG,
ef6243ac 15222 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 15223 .doit = nl80211_get_mesh_config,
93da9cc1 15224 /* can be retrieved by unprivileged users */
a05829a7 15225 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
93da9cc1 15226 },
15227 {
24bdd9f4 15228 .cmd = NL80211_CMD_SET_MESH_CONFIG,
ef6243ac 15229 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 15230 .doit = nl80211_update_mesh_config,
5617c6cd 15231 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15232 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
9aed3cc1 15233 },
2a519311
JB
15234 {
15235 .cmd = NL80211_CMD_TRIGGER_SCAN,
ef6243ac 15236 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311 15237 .doit = nl80211_trigger_scan,
5617c6cd 15238 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15239 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
2a519311 15240 },
91d3ab46
VK
15241 {
15242 .cmd = NL80211_CMD_ABORT_SCAN,
ef6243ac 15243 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
91d3ab46 15244 .doit = nl80211_abort_scan,
5617c6cd 15245 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15246 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
91d3ab46 15247 },
2a519311
JB
15248 {
15249 .cmd = NL80211_CMD_GET_SCAN,
ef6243ac 15250 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311
JB
15251 .dumpit = nl80211_dump_scan,
15252 },
807f8a8c
LC
15253 {
15254 .cmd = NL80211_CMD_START_SCHED_SCAN,
ef6243ac 15255 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 15256 .doit = nl80211_start_sched_scan,
5617c6cd 15257 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15258 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
807f8a8c
LC
15259 },
15260 {
15261 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
ef6243ac 15262 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 15263 .doit = nl80211_stop_sched_scan,
5617c6cd 15264 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15265 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
807f8a8c 15266 },
636a5d36
JM
15267 {
15268 .cmd = NL80211_CMD_AUTHENTICATE,
ef6243ac 15269 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15270 .doit = nl80211_authenticate,
5617c6cd 15271 .flags = GENL_UNS_ADMIN_PERM,
41265714 15272 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15273 0 |
5393b917 15274 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
15275 },
15276 {
15277 .cmd = NL80211_CMD_ASSOCIATE,
ef6243ac 15278 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15279 .doit = nl80211_associate,
5617c6cd 15280 .flags = GENL_UNS_ADMIN_PERM,
41265714 15281 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15282 0 |
d6db02a8 15283 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
15284 },
15285 {
15286 .cmd = NL80211_CMD_DEAUTHENTICATE,
ef6243ac 15287 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15288 .doit = nl80211_deauthenticate,
5617c6cd 15289 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15290 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
636a5d36
JM
15291 },
15292 {
15293 .cmd = NL80211_CMD_DISASSOCIATE,
ef6243ac 15294 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 15295 .doit = nl80211_disassociate,
5617c6cd 15296 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15297 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
636a5d36 15298 },
04a773ad
JB
15299 {
15300 .cmd = NL80211_CMD_JOIN_IBSS,
ef6243ac 15301 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 15302 .doit = nl80211_join_ibss,
5617c6cd 15303 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15304 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04a773ad
JB
15305 },
15306 {
15307 .cmd = NL80211_CMD_LEAVE_IBSS,
ef6243ac 15308 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 15309 .doit = nl80211_leave_ibss,
5617c6cd 15310 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15311 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04a773ad 15312 },
aff89a9b
JB
15313#ifdef CONFIG_NL80211_TESTMODE
15314 {
15315 .cmd = NL80211_CMD_TESTMODE,
ef6243ac 15316 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
aff89a9b 15317 .doit = nl80211_testmode_do,
71063f0e 15318 .dumpit = nl80211_testmode_dump,
5617c6cd 15319 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15320 .internal_flags = NL80211_FLAG_NEED_WIPHY,
aff89a9b
JB
15321 },
15322#endif
b23aa676
SO
15323 {
15324 .cmd = NL80211_CMD_CONNECT,
ef6243ac 15325 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 15326 .doit = nl80211_connect,
5617c6cd 15327 .flags = GENL_UNS_ADMIN_PERM,
41265714 15328 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15329 0 |
d6db02a8 15330 NL80211_FLAG_CLEAR_SKB,
b23aa676 15331 },
088e8df8 15332 {
15333 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
ef6243ac 15334 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
088e8df8 15335 .doit = nl80211_update_connect_params,
088e8df8 15336 .flags = GENL_ADMIN_PERM,
15337 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15338 0 |
d6db02a8 15339 NL80211_FLAG_CLEAR_SKB,
088e8df8 15340 },
b23aa676
SO
15341 {
15342 .cmd = NL80211_CMD_DISCONNECT,
ef6243ac 15343 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 15344 .doit = nl80211_disconnect,
5617c6cd 15345 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15346 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
b23aa676 15347 },
463d0183
JB
15348 {
15349 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
ef6243ac 15350 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
463d0183 15351 .doit = nl80211_wiphy_netns,
5617c6cd 15352 .flags = GENL_UNS_ADMIN_PERM,
77cbf790
JB
15353 .internal_flags = NL80211_FLAG_NEED_WIPHY |
15354 NL80211_FLAG_NEED_RTNL |
15355 NL80211_FLAG_NO_WIPHY_MTX,
463d0183 15356 },
61fa713c
HS
15357 {
15358 .cmd = NL80211_CMD_GET_SURVEY,
ef6243ac 15359 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
61fa713c
HS
15360 .dumpit = nl80211_dump_survey,
15361 },
67fbb16b
SO
15362 {
15363 .cmd = NL80211_CMD_SET_PMKSA,
ef6243ac 15364 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15365 .doit = nl80211_setdel_pmksa,
5617c6cd 15366 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 15367 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15368 0 |
d6db02a8 15369 NL80211_FLAG_CLEAR_SKB,
67fbb16b
SO
15370 },
15371 {
15372 .cmd = NL80211_CMD_DEL_PMKSA,
ef6243ac 15373 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15374 .doit = nl80211_setdel_pmksa,
5617c6cd 15375 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15376 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
67fbb16b
SO
15377 },
15378 {
15379 .cmd = NL80211_CMD_FLUSH_PMKSA,
ef6243ac 15380 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 15381 .doit = nl80211_flush_pmksa,
5617c6cd 15382 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15383 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
67fbb16b 15384 },
9588bbd5
JM
15385 {
15386 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
ef6243ac 15387 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 15388 .doit = nl80211_remain_on_channel,
5617c6cd 15389 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15390 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9588bbd5
JM
15391 },
15392 {
15393 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
ef6243ac 15394 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 15395 .doit = nl80211_cancel_remain_on_channel,
5617c6cd 15396 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15397 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9588bbd5 15398 },
13ae75b1
JM
15399 {
15400 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
ef6243ac 15401 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
13ae75b1 15402 .doit = nl80211_set_tx_bitrate_mask,
5617c6cd 15403 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15404 .internal_flags = NL80211_FLAG_NEED_NETDEV,
13ae75b1 15405 },
026331c4 15406 {
2e161f78 15407 .cmd = NL80211_CMD_REGISTER_FRAME,
ef6243ac 15408 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 15409 .doit = nl80211_register_mgmt,
5617c6cd 15410 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15411 .internal_flags = NL80211_FLAG_NEED_WDEV,
026331c4
JM
15412 },
15413 {
2e161f78 15414 .cmd = NL80211_CMD_FRAME,
ef6243ac 15415 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 15416 .doit = nl80211_tx_mgmt,
5617c6cd 15417 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15418 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
f7ca38df
JB
15419 },
15420 {
15421 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
ef6243ac 15422 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f7ca38df 15423 .doit = nl80211_tx_mgmt_cancel_wait,
5617c6cd 15424 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15425 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
026331c4 15426 },
ffb9eb3d
KV
15427 {
15428 .cmd = NL80211_CMD_SET_POWER_SAVE,
ef6243ac 15429 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 15430 .doit = nl80211_set_power_save,
5617c6cd 15431 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15432 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ffb9eb3d
KV
15433 },
15434 {
15435 .cmd = NL80211_CMD_GET_POWER_SAVE,
ef6243ac 15436 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 15437 .doit = nl80211_get_power_save,
ffb9eb3d 15438 /* can be retrieved by unprivileged users */
a05829a7 15439 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ffb9eb3d 15440 },
d6dc1a38
JO
15441 {
15442 .cmd = NL80211_CMD_SET_CQM,
ef6243ac 15443 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
d6dc1a38 15444 .doit = nl80211_set_cqm,
5617c6cd 15445 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15446 .internal_flags = NL80211_FLAG_NEED_NETDEV,
d6dc1a38 15447 },
f444de05
JB
15448 {
15449 .cmd = NL80211_CMD_SET_CHANNEL,
ef6243ac 15450 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f444de05 15451 .doit = nl80211_set_channel,
5617c6cd 15452 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15453 .internal_flags = NL80211_FLAG_NEED_NETDEV,
f444de05 15454 },
29cbe68c
JB
15455 {
15456 .cmd = NL80211_CMD_JOIN_MESH,
ef6243ac 15457 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 15458 .doit = nl80211_join_mesh,
5617c6cd 15459 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15460 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
29cbe68c
JB
15461 },
15462 {
15463 .cmd = NL80211_CMD_LEAVE_MESH,
ef6243ac 15464 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 15465 .doit = nl80211_leave_mesh,
5617c6cd 15466 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15467 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
29cbe68c 15468 },
6e0bd6c3
RL
15469 {
15470 .cmd = NL80211_CMD_JOIN_OCB,
ef6243ac 15471 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 15472 .doit = nl80211_join_ocb,
5617c6cd 15473 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15474 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
6e0bd6c3
RL
15475 },
15476 {
15477 .cmd = NL80211_CMD_LEAVE_OCB,
ef6243ac 15478 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 15479 .doit = nl80211_leave_ocb,
5617c6cd 15480 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15481 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
6e0bd6c3 15482 },
dfb89c56 15483#ifdef CONFIG_PM
ff1b6e69
JB
15484 {
15485 .cmd = NL80211_CMD_GET_WOWLAN,
ef6243ac 15486 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 15487 .doit = nl80211_get_wowlan,
ff1b6e69 15488 /* can be retrieved by unprivileged users */
a05829a7 15489 .internal_flags = NL80211_FLAG_NEED_WIPHY,
ff1b6e69
JB
15490 },
15491 {
15492 .cmd = NL80211_CMD_SET_WOWLAN,
ef6243ac 15493 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 15494 .doit = nl80211_set_wowlan,
5617c6cd 15495 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15496 .internal_flags = NL80211_FLAG_NEED_WIPHY,
ff1b6e69 15497 },
dfb89c56 15498#endif
e5497d76
JB
15499 {
15500 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
ef6243ac 15501 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
e5497d76 15502 .doit = nl80211_set_rekey_data,
5617c6cd 15503 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 15504 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15505 0 |
5393b917 15506 NL80211_FLAG_CLEAR_SKB,
e5497d76 15507 },
109086ce
AN
15508 {
15509 .cmd = NL80211_CMD_TDLS_MGMT,
ef6243ac 15510 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 15511 .doit = nl80211_tdls_mgmt,
5617c6cd 15512 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15513 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
109086ce
AN
15514 },
15515 {
15516 .cmd = NL80211_CMD_TDLS_OPER,
ef6243ac 15517 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 15518 .doit = nl80211_tdls_oper,
5617c6cd 15519 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15520 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
109086ce 15521 },
28946da7
JB
15522 {
15523 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
ef6243ac 15524 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
28946da7 15525 .doit = nl80211_register_unexpected_frame,
5617c6cd 15526 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15527 .internal_flags = NL80211_FLAG_NEED_NETDEV,
28946da7 15528 },
7f6cf311
JB
15529 {
15530 .cmd = NL80211_CMD_PROBE_CLIENT,
ef6243ac 15531 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7f6cf311 15532 .doit = nl80211_probe_client,
5617c6cd 15533 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15534 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
7f6cf311 15535 },
5e760230
JB
15536 {
15537 .cmd = NL80211_CMD_REGISTER_BEACONS,
ef6243ac 15538 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5e760230 15539 .doit = nl80211_register_beacons,
5617c6cd 15540 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15541 .internal_flags = NL80211_FLAG_NEED_WIPHY,
5e760230 15542 },
1d9d9213
SW
15543 {
15544 .cmd = NL80211_CMD_SET_NOACK_MAP,
ef6243ac 15545 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1d9d9213 15546 .doit = nl80211_set_noack_map,
5617c6cd 15547 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15548 .internal_flags = NL80211_FLAG_NEED_NETDEV,
1d9d9213 15549 },
98104fde
JB
15550 {
15551 .cmd = NL80211_CMD_START_P2P_DEVICE,
ef6243ac 15552 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 15553 .doit = nl80211_start_p2p_device,
5617c6cd 15554 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
15555 .internal_flags = NL80211_FLAG_NEED_WDEV |
15556 NL80211_FLAG_NEED_RTNL,
15557 },
15558 {
15559 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
ef6243ac 15560 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 15561 .doit = nl80211_stop_p2p_device,
5617c6cd 15562 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
15563 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
15564 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
15565 },
15566 {
15567 .cmd = NL80211_CMD_START_NAN,
ef6243ac 15568 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 15569 .doit = nl80211_start_nan,
cb3b7d87
AB
15570 .flags = GENL_ADMIN_PERM,
15571 .internal_flags = NL80211_FLAG_NEED_WDEV |
15572 NL80211_FLAG_NEED_RTNL,
15573 },
15574 {
15575 .cmd = NL80211_CMD_STOP_NAN,
ef6243ac 15576 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 15577 .doit = nl80211_stop_nan,
cb3b7d87
AB
15578 .flags = GENL_ADMIN_PERM,
15579 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
15580 NL80211_FLAG_NEED_RTNL,
a442b761
AB
15581 },
15582 {
15583 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
ef6243ac 15584 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 15585 .doit = nl80211_nan_add_func,
a442b761 15586 .flags = GENL_ADMIN_PERM,
a05829a7 15587 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
a442b761
AB
15588 },
15589 {
15590 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
ef6243ac 15591 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 15592 .doit = nl80211_nan_del_func,
a442b761 15593 .flags = GENL_ADMIN_PERM,
a05829a7 15594 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
a5a9dcf2
AB
15595 },
15596 {
15597 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
ef6243ac 15598 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a5a9dcf2 15599 .doit = nl80211_nan_change_config,
a5a9dcf2 15600 .flags = GENL_ADMIN_PERM,
a05829a7 15601 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
98104fde 15602 },
f4e583c8
AQ
15603 {
15604 .cmd = NL80211_CMD_SET_MCAST_RATE,
ef6243ac 15605 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f4e583c8 15606 .doit = nl80211_set_mcast_rate,
5617c6cd 15607 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15608 .internal_flags = NL80211_FLAG_NEED_NETDEV,
77765eaf
VT
15609 },
15610 {
15611 .cmd = NL80211_CMD_SET_MAC_ACL,
ef6243ac 15612 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
77765eaf 15613 .doit = nl80211_set_mac_acl,
5617c6cd 15614 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15615 .internal_flags = NL80211_FLAG_NEED_NETDEV,
f4e583c8 15616 },
04f39047
SW
15617 {
15618 .cmd = NL80211_CMD_RADAR_DETECT,
ef6243ac 15619 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04f39047 15620 .doit = nl80211_start_radar_detection,
5617c6cd 15621 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15622 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
04f39047 15623 },
3713b4e3
JB
15624 {
15625 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
ef6243ac 15626 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3713b4e3 15627 .doit = nl80211_get_protocol_features,
3713b4e3 15628 },
355199e0
JM
15629 {
15630 .cmd = NL80211_CMD_UPDATE_FT_IES,
ef6243ac 15631 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
355199e0 15632 .doit = nl80211_update_ft_ies,
5617c6cd 15633 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15634 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
355199e0 15635 },
5de17984
AS
15636 {
15637 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
ef6243ac 15638 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 15639 .doit = nl80211_crit_protocol_start,
5617c6cd 15640 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15641 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
5de17984
AS
15642 },
15643 {
15644 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
ef6243ac 15645 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 15646 .doit = nl80211_crit_protocol_stop,
5617c6cd 15647 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15648 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
be29b99a
AK
15649 },
15650 {
15651 .cmd = NL80211_CMD_GET_COALESCE,
ef6243ac 15652 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 15653 .doit = nl80211_get_coalesce,
a05829a7 15654 .internal_flags = NL80211_FLAG_NEED_WIPHY,
be29b99a
AK
15655 },
15656 {
15657 .cmd = NL80211_CMD_SET_COALESCE,
ef6243ac 15658 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 15659 .doit = nl80211_set_coalesce,
5617c6cd 15660 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15661 .internal_flags = NL80211_FLAG_NEED_WIPHY,
16ef1fe2
SW
15662 },
15663 {
15664 .cmd = NL80211_CMD_CHANNEL_SWITCH,
ef6243ac 15665 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16ef1fe2 15666 .doit = nl80211_channel_switch,
5617c6cd 15667 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15668 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
16ef1fe2 15669 },
ad7e718c
JB
15670 {
15671 .cmd = NL80211_CMD_VENDOR,
ef6243ac 15672 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad7e718c 15673 .doit = nl80211_vendor_cmd,
7bdbe400 15674 .dumpit = nl80211_vendor_cmd_dump,
5617c6cd 15675 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c 15676 .internal_flags = NL80211_FLAG_NEED_WIPHY |
a05829a7 15677 0 |
d6db02a8 15678 NL80211_FLAG_CLEAR_SKB,
ad7e718c 15679 },
fa9ffc74
KP
15680 {
15681 .cmd = NL80211_CMD_SET_QOS_MAP,
ef6243ac 15682 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
fa9ffc74 15683 .doit = nl80211_set_qos_map,
5617c6cd 15684 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15685 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
fa9ffc74 15686 },
960d01ac
JB
15687 {
15688 .cmd = NL80211_CMD_ADD_TX_TS,
ef6243ac 15689 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 15690 .doit = nl80211_add_tx_ts,
5617c6cd 15691 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15692 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
960d01ac
JB
15693 },
15694 {
15695 .cmd = NL80211_CMD_DEL_TX_TS,
ef6243ac 15696 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 15697 .doit = nl80211_del_tx_ts,
5617c6cd 15698 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15699 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
960d01ac 15700 },
1057d35e
AN
15701 {
15702 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
ef6243ac 15703 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 15704 .doit = nl80211_tdls_channel_switch,
5617c6cd 15705 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15706 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
1057d35e
AN
15707 },
15708 {
15709 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
ef6243ac 15710 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 15711 .doit = nl80211_tdls_cancel_channel_switch,
5617c6cd 15712 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15713 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
1057d35e 15714 },
ce0ce13a
MB
15715 {
15716 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
ef6243ac 15717 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ce0ce13a 15718 .doit = nl80211_set_multicast_to_unicast,
ce0ce13a 15719 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15720 .internal_flags = NL80211_FLAG_NEED_NETDEV,
ce0ce13a 15721 },
3a00df57
AS
15722 {
15723 .cmd = NL80211_CMD_SET_PMK,
ef6243ac 15724 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 15725 .doit = nl80211_set_pmk,
3a00df57 15726 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
a05829a7 15727 0 |
d6db02a8 15728 NL80211_FLAG_CLEAR_SKB,
3a00df57
AS
15729 },
15730 {
15731 .cmd = NL80211_CMD_DEL_PMK,
ef6243ac 15732 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 15733 .doit = nl80211_del_pmk,
a05829a7 15734 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
3a00df57 15735 },
40cbfa90
SD
15736 {
15737 .cmd = NL80211_CMD_EXTERNAL_AUTH,
ef6243ac 15738 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
40cbfa90 15739 .doit = nl80211_external_auth,
40cbfa90 15740 .flags = GENL_ADMIN_PERM,
a05829a7 15741 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
40cbfa90 15742 },
2576a9ac
DK
15743 {
15744 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
ef6243ac 15745 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2576a9ac 15746 .doit = nl80211_tx_control_port,
2576a9ac 15747 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15748 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
2576a9ac 15749 },
81e54d08
PKC
15750 {
15751 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
ef6243ac 15752 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
81e54d08 15753 .doit = nl80211_get_ftm_responder_stats,
a05829a7 15754 .internal_flags = NL80211_FLAG_NEED_NETDEV,
81e54d08 15755 },
9bb7e0f2
JB
15756 {
15757 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
ef6243ac 15758 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9bb7e0f2 15759 .doit = nl80211_pmsr_start,
9bb7e0f2 15760 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15761 .internal_flags = NL80211_FLAG_NEED_WDEV_UP,
9bb7e0f2 15762 },
30c63115
S
15763 {
15764 .cmd = NL80211_CMD_NOTIFY_RADAR,
ef6243ac 15765 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
30c63115 15766 .doit = nl80211_notify_radar_detection,
30c63115 15767 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15768 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
30c63115 15769 },
cb74e977
SD
15770 {
15771 .cmd = NL80211_CMD_UPDATE_OWE_INFO,
15772 .doit = nl80211_update_owe_info,
15773 .flags = GENL_ADMIN_PERM,
a05829a7 15774 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
5ab92e7f
RM
15775 },
15776 {
15777 .cmd = NL80211_CMD_PROBE_MESH_LINK,
15778 .doit = nl80211_probe_mesh_link,
15779 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15780 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP,
cb74e977 15781 },
77f576de
T
15782 {
15783 .cmd = NL80211_CMD_SET_TID_CONFIG,
15784 .doit = nl80211_set_tid_config,
15785 .flags = GENL_UNS_ADMIN_PERM,
a05829a7 15786 .internal_flags = NL80211_FLAG_NEED_NETDEV,
77f576de 15787 },
6bdb68ce
CH
15788 {
15789 .cmd = NL80211_CMD_SET_SAR_SPECS,
15790 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
15791 .doit = nl80211_set_sar_specs,
15792 .flags = GENL_UNS_ADMIN_PERM,
15793 .internal_flags = NL80211_FLAG_NEED_WIPHY |
15794 NL80211_FLAG_NEED_RTNL,
15795 },
55682965 15796};
9588bbd5 15797
56989f6d 15798static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
15799 .name = NL80211_GENL_NAME, /* have users key off the name instead */
15800 .hdrsize = 0, /* no private header */
15801 .version = 1, /* no particular meaning now */
15802 .maxattr = NL80211_ATTR_MAX,
3b0f31f2 15803 .policy = nl80211_policy,
489111e5
JB
15804 .netnsok = true,
15805 .pre_doit = nl80211_pre_doit,
15806 .post_doit = nl80211_post_doit,
15807 .module = THIS_MODULE,
15808 .ops = nl80211_ops,
15809 .n_ops = ARRAY_SIZE(nl80211_ops),
66a9b928
JK
15810 .small_ops = nl80211_small_ops,
15811 .n_small_ops = ARRAY_SIZE(nl80211_small_ops),
489111e5
JB
15812 .mcgrps = nl80211_mcgrps,
15813 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
50508d94 15814 .parallel_ops = true,
489111e5
JB
15815};
15816
55682965
JB
15817/* notification functions */
15818
3bb20556
JB
15819void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
15820 enum nl80211_commands cmd)
55682965
JB
15821{
15822 struct sk_buff *msg;
86e8cf98 15823 struct nl80211_dump_wiphy_state state = {};
55682965 15824
3bb20556
JB
15825 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
15826 cmd != NL80211_CMD_DEL_WIPHY);
15827
fd2120ca 15828 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
15829 if (!msg)
15830 return;
15831
3bb20556 15832 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
15833 nlmsg_free(msg);
15834 return;
15835 }
15836
68eb5503 15837 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15838 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
15839}
15840
896ff063
DK
15841void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
15842 struct wireless_dev *wdev,
15843 enum nl80211_commands cmd)
15844{
15845 struct sk_buff *msg;
15846
896ff063
DK
15847 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15848 if (!msg)
15849 return;
15850
3d1a5bbf 15851 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
896ff063
DK
15852 nlmsg_free(msg);
15853 return;
15854 }
15855
15856 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
15857 NL80211_MCGRP_CONFIG, GFP_KERNEL);
15858}
15859
362a415d
JB
15860static int nl80211_add_scan_req(struct sk_buff *msg,
15861 struct cfg80211_registered_device *rdev)
15862{
15863 struct cfg80211_scan_request *req = rdev->scan_req;
15864 struct nlattr *nest;
15865 int i;
c8cb5b85 15866 struct cfg80211_scan_info *info;
362a415d
JB
15867
15868 if (WARN_ON(!req))
15869 return 0;
15870
ae0be8de 15871 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_SSIDS);
362a415d
JB
15872 if (!nest)
15873 goto nla_put_failure;
9360ffd1
DM
15874 for (i = 0; i < req->n_ssids; i++) {
15875 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
15876 goto nla_put_failure;
15877 }
362a415d
JB
15878 nla_nest_end(msg, nest);
15879
2032f3b2
TP
15880 if (req->flags & NL80211_SCAN_FLAG_FREQ_KHZ) {
15881 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQ_KHZ);
15882 if (!nest)
15883 goto nla_put_failure;
15884 for (i = 0; i < req->n_channels; i++) {
15885 if (nla_put_u32(msg, i,
15886 ieee80211_channel_to_khz(req->channels[i])))
15887 goto nla_put_failure;
15888 }
15889 nla_nest_end(msg, nest);
15890 } else {
15891 nest = nla_nest_start_noflag(msg,
15892 NL80211_ATTR_SCAN_FREQUENCIES);
15893 if (!nest)
9360ffd1 15894 goto nla_put_failure;
2032f3b2
TP
15895 for (i = 0; i < req->n_channels; i++) {
15896 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
15897 goto nla_put_failure;
15898 }
15899 nla_nest_end(msg, nest);
9360ffd1 15900 }
362a415d 15901
9360ffd1
DM
15902 if (req->ie &&
15903 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
15904 goto nla_put_failure;
362a415d 15905
ae917c9f
JB
15906 if (req->flags &&
15907 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
15908 goto nla_put_failure;
ed473771 15909
c8cb5b85
TM
15910 info = rdev->int_scan_req ? &rdev->int_scan_req->info :
15911 &rdev->scan_req->info;
15912 if (info->scan_start_tsf &&
1d76250b 15913 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
c8cb5b85 15914 info->scan_start_tsf, NL80211_BSS_PAD) ||
1d76250b 15915 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
c8cb5b85 15916 info->tsf_bssid)))
1d76250b
AS
15917 goto nla_put_failure;
15918
362a415d
JB
15919 return 0;
15920 nla_put_failure:
15921 return -ENOBUFS;
15922}
15923
505a2e88 15924static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 15925 struct cfg80211_registered_device *rdev,
fd014284 15926 struct wireless_dev *wdev,
15e47304 15927 u32 portid, u32 seq, int flags,
a538e2d5 15928 u32 cmd)
2a519311
JB
15929{
15930 void *hdr;
15931
15e47304 15932 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
15933 if (!hdr)
15934 return -1;
15935
9360ffd1 15936 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
15937 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15938 wdev->netdev->ifindex)) ||
2dad624e
ND
15939 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15940 NL80211_ATTR_PAD))
9360ffd1 15941 goto nla_put_failure;
2a519311 15942
362a415d
JB
15943 /* ignore errors and send incomplete event anyway */
15944 nl80211_add_scan_req(msg, rdev);
2a519311 15945
053c095a
JB
15946 genlmsg_end(msg, hdr);
15947 return 0;
2a519311
JB
15948
15949 nla_put_failure:
15950 genlmsg_cancel(msg, hdr);
15951 return -EMSGSIZE;
15952}
15953
807f8a8c 15954static int
505a2e88 15955nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 15956 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
15957{
15958 void *hdr;
15959
96b08fd6 15960 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
15961 if (!hdr)
15962 return -1;
15963
96b08fd6
AVS
15964 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
15965 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
15966 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
15967 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
15968 NL80211_ATTR_PAD))
9360ffd1 15969 goto nla_put_failure;
807f8a8c 15970
053c095a
JB
15971 genlmsg_end(msg, hdr);
15972 return 0;
807f8a8c
LC
15973
15974 nla_put_failure:
15975 genlmsg_cancel(msg, hdr);
15976 return -EMSGSIZE;
15977}
15978
a538e2d5 15979void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 15980 struct wireless_dev *wdev)
a538e2d5
JB
15981{
15982 struct sk_buff *msg;
15983
58050fce 15984 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
15985 if (!msg)
15986 return;
15987
505a2e88 15988 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
15989 NL80211_CMD_TRIGGER_SCAN) < 0) {
15990 nlmsg_free(msg);
15991 return;
15992 }
15993
68eb5503 15994 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15995 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
15996}
15997
f9d15d16
JB
15998struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
15999 struct wireless_dev *wdev, bool aborted)
2a519311
JB
16000{
16001 struct sk_buff *msg;
16002
fd2120ca 16003 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 16004 if (!msg)
f9d15d16 16005 return NULL;
2a519311 16006
505a2e88 16007 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
16008 aborted ? NL80211_CMD_SCAN_ABORTED :
16009 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 16010 nlmsg_free(msg);
f9d15d16 16011 return NULL;
2a519311
JB
16012 }
16013
f9d15d16 16014 return msg;
2a519311
JB
16015}
16016
505a2e88
AVS
16017/* send message created by nl80211_build_scan_msg() */
16018void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
16019 struct sk_buff *msg)
807f8a8c 16020{
807f8a8c
LC
16021 if (!msg)
16022 return;
16023
68eb5503 16024 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16025 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
16026}
16027
96b08fd6 16028void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
16029{
16030 struct sk_buff *msg;
16031
58050fce 16032 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
16033 if (!msg)
16034 return;
16035
96b08fd6 16036 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
16037 nlmsg_free(msg);
16038 return;
16039 }
16040
96b08fd6 16041 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 16042 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
16043}
16044
b0d7aa59
JD
16045static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
16046 struct regulatory_request *request)
73d54c9e 16047{
73d54c9e 16048 /* Userspace can always count this one always being set */
9360ffd1
DM
16049 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
16050 goto nla_put_failure;
16051
16052 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
16053 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16054 NL80211_REGDOM_TYPE_WORLD))
16055 goto nla_put_failure;
16056 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
16057 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16058 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
16059 goto nla_put_failure;
16060 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
16061 request->intersect) {
16062 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16063 NL80211_REGDOM_TYPE_INTERSECTION))
16064 goto nla_put_failure;
16065 } else {
16066 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
16067 NL80211_REGDOM_TYPE_COUNTRY) ||
16068 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
16069 request->alpha2))
16070 goto nla_put_failure;
16071 }
16072
ad30ca2c
AN
16073 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
16074 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
16075
16076 if (wiphy &&
16077 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
16078 goto nla_put_failure;
1bdd716c
AN
16079
16080 if (wiphy &&
16081 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
16082 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
16083 goto nla_put_failure;
ad30ca2c 16084 }
73d54c9e 16085
b0d7aa59
JD
16086 return true;
16087
16088nla_put_failure:
16089 return false;
16090}
16091
16092/*
16093 * This can happen on global regulatory changes or device specific settings
16094 * based on custom regulatory domains.
16095 */
16096void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
16097 struct regulatory_request *request)
16098{
16099 struct sk_buff *msg;
16100 void *hdr;
16101
16102 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16103 if (!msg)
16104 return;
16105
16106 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
24f6d765 16107 if (!hdr)
16108 goto nla_put_failure;
b0d7aa59 16109
24f6d765 16110 if (!nl80211_reg_change_event_fill(msg, request))
b0d7aa59
JD
16111 goto nla_put_failure;
16112
3b7b72ee 16113 genlmsg_end(msg, hdr);
73d54c9e 16114
bc43b28c 16115 rcu_read_lock();
68eb5503 16116 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 16117 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 16118 rcu_read_unlock();
73d54c9e
LR
16119
16120 return;
16121
16122nla_put_failure:
73d54c9e
LR
16123 nlmsg_free(msg);
16124}
16125
6039f6d2
JM
16126static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
16127 struct net_device *netdev,
16128 const u8 *buf, size_t len,
b0b6aa2c 16129 enum nl80211_commands cmd, gfp_t gfp,
4d9ec73d 16130 int uapsd_queues, const u8 *req_ies,
3bb02143 16131 size_t req_ies_len, bool reconnect)
6039f6d2
JM
16132{
16133 struct sk_buff *msg;
16134 void *hdr;
16135
4d9ec73d 16136 msg = nlmsg_new(100 + len + req_ies_len, gfp);
6039f6d2
JM
16137 if (!msg)
16138 return;
16139
16140 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16141 if (!hdr) {
16142 nlmsg_free(msg);
16143 return;
16144 }
16145
9360ffd1
DM
16146 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16147 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
4d9ec73d
JM
16148 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
16149 (req_ies &&
16150 nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
9360ffd1 16151 goto nla_put_failure;
6039f6d2 16152
3bb02143
JB
16153 if (reconnect && nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
16154 goto nla_put_failure;
16155
b0b6aa2c
EP
16156 if (uapsd_queues >= 0) {
16157 struct nlattr *nla_wmm =
ae0be8de 16158 nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
b0b6aa2c
EP
16159 if (!nla_wmm)
16160 goto nla_put_failure;
16161
16162 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
16163 uapsd_queues))
16164 goto nla_put_failure;
16165
16166 nla_nest_end(msg, nla_wmm);
16167 }
16168
3b7b72ee 16169 genlmsg_end(msg, hdr);
6039f6d2 16170
68eb5503 16171 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16172 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
16173 return;
16174
16175 nla_put_failure:
6039f6d2
JM
16176 nlmsg_free(msg);
16177}
16178
16179void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16180 struct net_device *netdev, const u8 *buf,
16181 size_t len, gfp_t gfp)
6039f6d2
JM
16182{
16183 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16184 NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0,
16185 false);
6039f6d2
JM
16186}
16187
16188void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
16189 struct net_device *netdev, const u8 *buf,
4d9ec73d
JM
16190 size_t len, gfp_t gfp, int uapsd_queues,
16191 const u8 *req_ies, size_t req_ies_len)
6039f6d2 16192{
e6d6e342 16193 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 16194 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
3bb02143 16195 req_ies, req_ies_len, false);
6039f6d2
JM
16196}
16197
53b46b84 16198void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342 16199 struct net_device *netdev, const u8 *buf,
3bb02143 16200 size_t len, bool reconnect, gfp_t gfp)
6039f6d2
JM
16201{
16202 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16203 NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0,
16204 reconnect);
6039f6d2
JM
16205}
16206
53b46b84
JM
16207void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
16208 struct net_device *netdev, const u8 *buf,
3bb02143 16209 size_t len, bool reconnect, gfp_t gfp)
6039f6d2
JM
16210{
16211 nl80211_send_mlme_event(rdev, netdev, buf, len,
3bb02143
JB
16212 NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0,
16213 reconnect);
6039f6d2
JM
16214}
16215
6ff57cf8
JB
16216void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
16217 size_t len)
cf4e594e 16218{
947add36
JB
16219 struct wireless_dev *wdev = dev->ieee80211_ptr;
16220 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16221 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
16222 const struct ieee80211_mgmt *mgmt = (void *)buf;
16223 u32 cmd;
947add36 16224
6ff57cf8
JB
16225 if (WARN_ON(len < 2))
16226 return;
cf4e594e 16227
4d797fce 16228 if (ieee80211_is_deauth(mgmt->frame_control)) {
6ff57cf8 16229 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
4d797fce 16230 } else if (ieee80211_is_disassoc(mgmt->frame_control)) {
6ff57cf8 16231 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
4d797fce
JM
16232 } else if (ieee80211_is_beacon(mgmt->frame_control)) {
16233 if (wdev->unprot_beacon_reported &&
16234 elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
16235 return;
16236 cmd = NL80211_CMD_UNPROT_BEACON;
16237 wdev->unprot_beacon_reported = jiffies;
16238 } else {
16239 return;
16240 }
947add36 16241
6ff57cf8 16242 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
4d9ec73d 16243 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
3bb02143 16244 NULL, 0, false);
cf4e594e 16245}
6ff57cf8 16246EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 16247
1b06bb40
LR
16248static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
16249 struct net_device *netdev, int cmd,
e6d6e342 16250 const u8 *addr, gfp_t gfp)
1965c853
JM
16251{
16252 struct sk_buff *msg;
16253 void *hdr;
16254
e6d6e342 16255 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
16256 if (!msg)
16257 return;
16258
16259 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16260 if (!hdr) {
16261 nlmsg_free(msg);
16262 return;
16263 }
16264
9360ffd1
DM
16265 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16266 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16267 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
16268 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
16269 goto nla_put_failure;
1965c853 16270
3b7b72ee 16271 genlmsg_end(msg, hdr);
1965c853 16272
68eb5503 16273 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16274 NL80211_MCGRP_MLME, gfp);
1965c853
JM
16275 return;
16276
16277 nla_put_failure:
1965c853
JM
16278 nlmsg_free(msg);
16279}
16280
16281void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16282 struct net_device *netdev, const u8 *addr,
16283 gfp_t gfp)
1965c853
JM
16284{
16285 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 16286 addr, gfp);
1965c853
JM
16287}
16288
16289void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
16290 struct net_device *netdev, const u8 *addr,
16291 gfp_t gfp)
1965c853 16292{
e6d6e342
JB
16293 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
16294 addr, gfp);
1965c853
JM
16295}
16296
b23aa676 16297void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
16298 struct net_device *netdev,
16299 struct cfg80211_connect_resp_params *cr,
3093ebbe 16300 gfp_t gfp)
b23aa676
SO
16301{
16302 struct sk_buff *msg;
16303 void *hdr;
16304
a3caf744 16305 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
76804d28
AVS
16306 cr->fils.kek_len + cr->fils.pmk_len +
16307 (cr->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
16308 if (!msg)
16309 return;
16310
16311 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
16312 if (!hdr) {
16313 nlmsg_free(msg);
16314 return;
16315 }
16316
9360ffd1
DM
16317 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16318 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
16319 (cr->bssid &&
16320 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 16321 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
16322 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
16323 cr->status) ||
16324 (cr->status < 0 &&
3093ebbe 16325 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
16326 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
16327 cr->timeout_reason))) ||
16328 (cr->req_ie &&
16329 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
16330 (cr->resp_ie &&
16331 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744 16332 cr->resp_ie)) ||
76804d28 16333 (cr->fils.update_erp_next_seq_num &&
a3caf744 16334 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
76804d28 16335 cr->fils.erp_next_seq_num)) ||
a3caf744 16336 (cr->status == WLAN_STATUS_SUCCESS &&
76804d28
AVS
16337 ((cr->fils.kek &&
16338 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
16339 cr->fils.kek)) ||
16340 (cr->fils.pmk &&
16341 nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
16342 (cr->fils.pmkid &&
16343 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
9360ffd1 16344 goto nla_put_failure;
b23aa676 16345
3b7b72ee 16346 genlmsg_end(msg, hdr);
b23aa676 16347
68eb5503 16348 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16349 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
16350 return;
16351
16352 nla_put_failure:
b23aa676 16353 nlmsg_free(msg);
b23aa676
SO
16354}
16355
16356void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
16357 struct net_device *netdev,
16358 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
16359{
16360 struct sk_buff *msg;
16361 void *hdr;
29ce6ecb 16362 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 16363
e841b7b1
AVS
16364 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
16365 info->fils.kek_len + info->fils.pmk_len +
16366 (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
16367 if (!msg)
16368 return;
16369
16370 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
16371 if (!hdr) {
16372 nlmsg_free(msg);
16373 return;
16374 }
16375
9360ffd1
DM
16376 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16377 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16378 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
16379 (info->req_ie &&
16380 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
16381 info->req_ie)) ||
16382 (info->resp_ie &&
16383 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
e841b7b1
AVS
16384 info->resp_ie)) ||
16385 (info->fils.update_erp_next_seq_num &&
16386 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
16387 info->fils.erp_next_seq_num)) ||
16388 (info->fils.kek &&
16389 nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
16390 info->fils.kek)) ||
16391 (info->fils.pmk &&
16392 nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
16393 (info->fils.pmkid &&
16394 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
9360ffd1 16395 goto nla_put_failure;
b23aa676 16396
3b7b72ee 16397 genlmsg_end(msg, hdr);
b23aa676 16398
68eb5503 16399 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16400 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
16401 return;
16402
503c1fb9 16403 nla_put_failure:
503c1fb9
AS
16404 nlmsg_free(msg);
16405}
16406
16407void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
16408 struct net_device *netdev, const u8 *bssid)
16409{
16410 struct sk_buff *msg;
16411 void *hdr;
16412
16413 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16414 if (!msg)
16415 return;
16416
16417 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
16418 if (!hdr) {
16419 nlmsg_free(msg);
16420 return;
16421 }
16422
f4d75993
CHH
16423 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16424 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16425 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
503c1fb9
AS
16426 goto nla_put_failure;
16427
16428 genlmsg_end(msg, hdr);
16429
16430 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16431 NL80211_MCGRP_MLME, GFP_KERNEL);
16432 return;
16433
b23aa676 16434 nla_put_failure:
b23aa676 16435 nlmsg_free(msg);
b23aa676
SO
16436}
16437
16438void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
16439 struct net_device *netdev, u16 reason,
667503dd 16440 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
16441{
16442 struct sk_buff *msg;
16443 void *hdr;
16444
4ef8c1c9 16445 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
16446 if (!msg)
16447 return;
16448
16449 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
16450 if (!hdr) {
16451 nlmsg_free(msg);
16452 return;
16453 }
16454
9360ffd1
DM
16455 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16456 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
86b6c465 16457 (reason &&
9360ffd1
DM
16458 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
16459 (from_ap &&
16460 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
16461 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
16462 goto nla_put_failure;
b23aa676 16463
3b7b72ee 16464 genlmsg_end(msg, hdr);
b23aa676 16465
68eb5503 16466 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16467 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
16468 return;
16469
16470 nla_put_failure:
b23aa676 16471 nlmsg_free(msg);
b23aa676
SO
16472}
16473
04a773ad
JB
16474void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
16475 struct net_device *netdev, const u8 *bssid,
16476 gfp_t gfp)
16477{
16478 struct sk_buff *msg;
16479 void *hdr;
16480
fd2120ca 16481 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
16482 if (!msg)
16483 return;
16484
16485 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
16486 if (!hdr) {
16487 nlmsg_free(msg);
16488 return;
16489 }
16490
9360ffd1
DM
16491 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16492 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16493 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
16494 goto nla_put_failure;
04a773ad 16495
3b7b72ee 16496 genlmsg_end(msg, hdr);
04a773ad 16497
68eb5503 16498 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16499 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
16500 return;
16501
16502 nla_put_failure:
04a773ad
JB
16503 nlmsg_free(msg);
16504}
16505
947add36 16506void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
ecbc12ad
BC
16507 const u8 *ie, u8 ie_len,
16508 int sig_dbm, gfp_t gfp)
c93b5e71 16509{
947add36 16510 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16511 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
16512 struct sk_buff *msg;
16513 void *hdr;
16514
947add36
JB
16515 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
16516 return;
16517
16518 trace_cfg80211_notify_new_peer_candidate(dev, addr);
16519
4ef8c1c9 16520 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
16521 if (!msg)
16522 return;
16523
16524 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
16525 if (!hdr) {
16526 nlmsg_free(msg);
16527 return;
16528 }
16529
9360ffd1 16530 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
16531 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16532 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1 16533 (ie_len && ie &&
ecbc12ad
BC
16534 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
16535 (sig_dbm &&
16536 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
9360ffd1 16537 goto nla_put_failure;
c93b5e71 16538
3b7b72ee 16539 genlmsg_end(msg, hdr);
c93b5e71 16540
68eb5503 16541 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16542 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
16543 return;
16544
16545 nla_put_failure:
c93b5e71
JC
16546 nlmsg_free(msg);
16547}
947add36 16548EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 16549
a3b8b056
JM
16550void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
16551 struct net_device *netdev, const u8 *addr,
16552 enum nl80211_key_type key_type, int key_id,
e6d6e342 16553 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
16554{
16555 struct sk_buff *msg;
16556 void *hdr;
16557
e6d6e342 16558 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
16559 if (!msg)
16560 return;
16561
16562 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
16563 if (!hdr) {
16564 nlmsg_free(msg);
16565 return;
16566 }
16567
9360ffd1
DM
16568 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16569 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16570 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
16571 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
16572 (key_id != -1 &&
16573 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
16574 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
16575 goto nla_put_failure;
a3b8b056 16576
3b7b72ee 16577 genlmsg_end(msg, hdr);
a3b8b056 16578
68eb5503 16579 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16580 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
16581 return;
16582
16583 nla_put_failure:
a3b8b056
JM
16584 nlmsg_free(msg);
16585}
16586
6bad8766
LR
16587void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
16588 struct ieee80211_channel *channel_before,
16589 struct ieee80211_channel *channel_after)
16590{
16591 struct sk_buff *msg;
16592 void *hdr;
16593 struct nlattr *nl_freq;
16594
fd2120ca 16595 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
16596 if (!msg)
16597 return;
16598
16599 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
16600 if (!hdr) {
16601 nlmsg_free(msg);
16602 return;
16603 }
16604
16605 /*
16606 * Since we are applying the beacon hint to a wiphy we know its
16607 * wiphy_idx is valid
16608 */
9360ffd1
DM
16609 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
16610 goto nla_put_failure;
6bad8766
LR
16611
16612 /* Before */
ae0be8de 16613 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_BEFORE);
6bad8766
LR
16614 if (!nl_freq)
16615 goto nla_put_failure;
50f32718
HD
16616
16617 if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
6bad8766
LR
16618 goto nla_put_failure;
16619 nla_nest_end(msg, nl_freq);
16620
16621 /* After */
ae0be8de 16622 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_AFTER);
6bad8766
LR
16623 if (!nl_freq)
16624 goto nla_put_failure;
50f32718
HD
16625
16626 if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
6bad8766
LR
16627 goto nla_put_failure;
16628 nla_nest_end(msg, nl_freq);
16629
3b7b72ee 16630 genlmsg_end(msg, hdr);
6bad8766 16631
463d0183 16632 rcu_read_lock();
68eb5503 16633 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 16634 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 16635 rcu_read_unlock();
6bad8766
LR
16636
16637 return;
16638
16639nla_put_failure:
6bad8766
LR
16640 nlmsg_free(msg);
16641}
16642
9588bbd5
JM
16643static void nl80211_send_remain_on_chan_event(
16644 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 16645 struct wireless_dev *wdev, u64 cookie,
9588bbd5 16646 struct ieee80211_channel *chan,
9588bbd5
JM
16647 unsigned int duration, gfp_t gfp)
16648{
16649 struct sk_buff *msg;
16650 void *hdr;
16651
16652 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16653 if (!msg)
16654 return;
16655
16656 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
16657 if (!hdr) {
16658 nlmsg_free(msg);
16659 return;
16660 }
16661
9360ffd1 16662 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16663 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16664 wdev->netdev->ifindex)) ||
2dad624e
ND
16665 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16666 NL80211_ATTR_PAD) ||
9360ffd1 16667 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
16668 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
16669 NL80211_CHAN_NO_HT) ||
2dad624e
ND
16670 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
16671 NL80211_ATTR_PAD))
9360ffd1 16672 goto nla_put_failure;
9588bbd5 16673
9360ffd1
DM
16674 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
16675 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
16676 goto nla_put_failure;
9588bbd5 16677
3b7b72ee 16678 genlmsg_end(msg, hdr);
9588bbd5 16679
68eb5503 16680 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16681 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
16682 return;
16683
16684 nla_put_failure:
9588bbd5
JM
16685 nlmsg_free(msg);
16686}
16687
947add36
JB
16688void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
16689 struct ieee80211_channel *chan,
16690 unsigned int duration, gfp_t gfp)
9588bbd5 16691{
947add36 16692 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16693 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
16694
16695 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 16696 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 16697 rdev, wdev, cookie, chan,
42d97a59 16698 duration, gfp);
9588bbd5 16699}
947add36 16700EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 16701
947add36
JB
16702void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
16703 struct ieee80211_channel *chan,
16704 gfp_t gfp)
9588bbd5 16705{
947add36 16706 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16707 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
16708
16709 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 16710 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 16711 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 16712}
947add36 16713EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 16714
1c38c7f2
JP
16715void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
16716 struct ieee80211_channel *chan,
16717 gfp_t gfp)
16718{
16719 struct wiphy *wiphy = wdev->wiphy;
16720 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
16721
16722 trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
16723 nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
16724 rdev, wdev, cookie, chan, 0, gfp);
16725}
16726EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
16727
947add36
JB
16728void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
16729 struct station_info *sinfo, gfp_t gfp)
98b62183 16730{
947add36 16731 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16732 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
16733 struct sk_buff *msg;
16734
947add36
JB
16735 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
16736
58050fce 16737 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
16738 if (!msg)
16739 return;
16740
cf5ead82 16741 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 16742 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
16743 nlmsg_free(msg);
16744 return;
16745 }
16746
68eb5503 16747 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16748 NL80211_MCGRP_MLME, gfp);
98b62183 16749}
947add36 16750EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 16751
cf5ead82
JB
16752void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
16753 struct station_info *sinfo, gfp_t gfp)
ec15e68b 16754{
947add36 16755 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16756 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 16757 struct sk_buff *msg;
73887fd9 16758 struct station_info empty_sinfo = {};
cf5ead82 16759
73887fd9
JB
16760 if (!sinfo)
16761 sinfo = &empty_sinfo;
ec15e68b 16762
947add36
JB
16763 trace_cfg80211_del_sta(dev, mac_addr);
16764
58050fce 16765 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7ea3e110
JB
16766 if (!msg) {
16767 cfg80211_sinfo_release_content(sinfo);
73887fd9 16768 return;
7ea3e110 16769 }
ec15e68b 16770
cf5ead82 16771 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 16772 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b 16773 nlmsg_free(msg);
73887fd9 16774 return;
ec15e68b
JM
16775 }
16776
68eb5503 16777 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16778 NL80211_MCGRP_MLME, gfp);
ec15e68b 16779}
cf5ead82 16780EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 16781
947add36
JB
16782void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
16783 enum nl80211_connect_failed_reason reason,
16784 gfp_t gfp)
ed44a951 16785{
947add36 16786 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 16787 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
16788 struct sk_buff *msg;
16789 void *hdr;
16790
16791 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
16792 if (!msg)
16793 return;
16794
16795 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
16796 if (!hdr) {
16797 nlmsg_free(msg);
16798 return;
16799 }
16800
16801 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16802 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
16803 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
16804 goto nla_put_failure;
16805
16806 genlmsg_end(msg, hdr);
16807
68eb5503 16808 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16809 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
16810 return;
16811
16812 nla_put_failure:
ed44a951
PP
16813 nlmsg_free(msg);
16814}
947add36 16815EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 16816
b92ab5d8
JB
16817static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
16818 const u8 *addr, gfp_t gfp)
28946da7
JB
16819{
16820 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16821 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
16822 struct sk_buff *msg;
16823 void *hdr;
6aa7de05 16824 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 16825
15e47304 16826 if (!nlportid)
28946da7
JB
16827 return false;
16828
16829 msg = nlmsg_new(100, gfp);
16830 if (!msg)
16831 return true;
16832
b92ab5d8 16833 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
16834 if (!hdr) {
16835 nlmsg_free(msg);
16836 return true;
16837 }
16838
9360ffd1
DM
16839 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16840 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16841 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
16842 goto nla_put_failure;
28946da7 16843
9c90a9f6 16844 genlmsg_end(msg, hdr);
15e47304 16845 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
16846 return true;
16847
16848 nla_put_failure:
28946da7
JB
16849 nlmsg_free(msg);
16850 return true;
16851}
16852
947add36
JB
16853bool cfg80211_rx_spurious_frame(struct net_device *dev,
16854 const u8 *addr, gfp_t gfp)
b92ab5d8 16855{
947add36
JB
16856 struct wireless_dev *wdev = dev->ieee80211_ptr;
16857 bool ret;
16858
16859 trace_cfg80211_rx_spurious_frame(dev, addr);
16860
16861 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
16862 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
16863 trace_cfg80211_return_bool(false);
16864 return false;
16865 }
16866 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
16867 addr, gfp);
16868 trace_cfg80211_return_bool(ret);
16869 return ret;
b92ab5d8 16870}
947add36 16871EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 16872
947add36
JB
16873bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
16874 const u8 *addr, gfp_t gfp)
b92ab5d8 16875{
947add36
JB
16876 struct wireless_dev *wdev = dev->ieee80211_ptr;
16877 bool ret;
16878
16879 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
16880
16881 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
16882 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
16883 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
16884 trace_cfg80211_return_bool(false);
16885 return false;
16886 }
16887 ret = __nl80211_unexpected_frame(dev,
16888 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
16889 addr, gfp);
16890 trace_cfg80211_return_bool(ret);
16891 return ret;
b92ab5d8 16892}
947add36 16893EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 16894
2e161f78 16895int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 16896 struct wireless_dev *wdev, u32 nlportid,
804483e9 16897 int freq, int sig_dbm,
19504cf5 16898 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 16899{
71bbc994 16900 struct net_device *netdev = wdev->netdev;
026331c4
JM
16901 struct sk_buff *msg;
16902 void *hdr;
026331c4 16903
4ef8c1c9 16904 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
16905 if (!msg)
16906 return -ENOMEM;
16907
2e161f78 16908 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
16909 if (!hdr) {
16910 nlmsg_free(msg);
16911 return -ENOMEM;
16912 }
16913
9360ffd1 16914 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16915 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16916 netdev->ifindex)) ||
2dad624e
ND
16917 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16918 NL80211_ATTR_PAD) ||
e76fede8 16919 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(freq)) ||
942ba88b 16920 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, freq % 1000) ||
9360ffd1
DM
16921 (sig_dbm &&
16922 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
16923 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
16924 (flags &&
16925 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 16926 goto nla_put_failure;
026331c4 16927
3b7b72ee 16928 genlmsg_end(msg, hdr);
026331c4 16929
15e47304 16930 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
16931
16932 nla_put_failure:
026331c4
JM
16933 nlmsg_free(msg);
16934 return -ENOBUFS;
16935}
16936
dca9ca2d
MT
16937static void nl80211_frame_tx_status(struct wireless_dev *wdev, u64 cookie,
16938 const u8 *buf, size_t len, bool ack,
16939 gfp_t gfp, enum nl80211_commands command)
026331c4 16940{
947add36 16941 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16942 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 16943 struct net_device *netdev = wdev->netdev;
026331c4
JM
16944 struct sk_buff *msg;
16945 void *hdr;
16946
dca9ca2d
MT
16947 if (command == NL80211_CMD_FRAME_TX_STATUS)
16948 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
16949 else
16950 trace_cfg80211_control_port_tx_status(wdev, cookie, ack);
947add36 16951
4ef8c1c9 16952 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
16953 if (!msg)
16954 return;
16955
dca9ca2d 16956 hdr = nl80211hdr_put(msg, 0, 0, 0, command);
026331c4
JM
16957 if (!hdr) {
16958 nlmsg_free(msg);
16959 return;
16960 }
16961
9360ffd1 16962 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
16963 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16964 netdev->ifindex)) ||
2dad624e
ND
16965 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16966 NL80211_ATTR_PAD) ||
9360ffd1 16967 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
16968 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
16969 NL80211_ATTR_PAD) ||
9360ffd1
DM
16970 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
16971 goto nla_put_failure;
026331c4 16972
3b7b72ee 16973 genlmsg_end(msg, hdr);
026331c4 16974
68eb5503 16975 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16976 NL80211_MCGRP_MLME, gfp);
026331c4
JM
16977 return;
16978
dca9ca2d 16979nla_put_failure:
026331c4
JM
16980 nlmsg_free(msg);
16981}
dca9ca2d
MT
16982
16983void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
16984 const u8 *buf, size_t len, bool ack,
16985 gfp_t gfp)
16986{
16987 nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
16988 NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS);
16989}
16990EXPORT_SYMBOL(cfg80211_control_port_tx_status);
16991
16992void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
16993 const u8 *buf, size_t len, bool ack, gfp_t gfp)
16994{
16995 nl80211_frame_tx_status(wdev, cookie, buf, len, ack, gfp,
16996 NL80211_CMD_FRAME_TX_STATUS);
16997}
947add36 16998EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 16999
6a671a50 17000static int __nl80211_rx_control_port(struct net_device *dev,
a948f713 17001 struct sk_buff *skb,
6a671a50
DK
17002 bool unencrypted, gfp_t gfp)
17003{
17004 struct wireless_dev *wdev = dev->ieee80211_ptr;
17005 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
a948f713 17006 struct ethhdr *ehdr = eth_hdr(skb);
8d74a623 17007 const u8 *addr = ehdr->h_source;
a948f713 17008 u16 proto = be16_to_cpu(skb->protocol);
6a671a50
DK
17009 struct sk_buff *msg;
17010 void *hdr;
a948f713
DK
17011 struct nlattr *frame;
17012
6a671a50
DK
17013 u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
17014
17015 if (!nlportid)
17016 return -ENOENT;
17017
a948f713 17018 msg = nlmsg_new(100 + skb->len, gfp);
6a671a50
DK
17019 if (!msg)
17020 return -ENOMEM;
17021
17022 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
17023 if (!hdr) {
17024 nlmsg_free(msg);
17025 return -ENOBUFS;
17026 }
17027
17028 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17029 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17030 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17031 NL80211_ATTR_PAD) ||
8d74a623 17032 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
6a671a50
DK
17033 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
17034 (unencrypted && nla_put_flag(msg,
17035 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
17036 goto nla_put_failure;
17037
a948f713
DK
17038 frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
17039 if (!frame)
17040 goto nla_put_failure;
17041
17042 skb_copy_bits(skb, 0, nla_data(frame), skb->len);
6a671a50
DK
17043 genlmsg_end(msg, hdr);
17044
17045 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
17046
17047 nla_put_failure:
17048 nlmsg_free(msg);
17049 return -ENOBUFS;
17050}
17051
17052bool cfg80211_rx_control_port(struct net_device *dev,
a948f713 17053 struct sk_buff *skb, bool unencrypted)
6a671a50
DK
17054{
17055 int ret;
17056
a948f713
DK
17057 trace_cfg80211_rx_control_port(dev, skb, unencrypted);
17058 ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC);
6a671a50
DK
17059 trace_cfg80211_return_bool(ret == 0);
17060 return ret == 0;
17061}
17062EXPORT_SYMBOL(cfg80211_rx_control_port);
17063
5b97f49d
JB
17064static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
17065 const char *mac, gfp_t gfp)
d6dc1a38 17066{
947add36 17067 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
17068 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
17069 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17070 void **cb;
947add36 17071
d6dc1a38 17072 if (!msg)
5b97f49d 17073 return NULL;
d6dc1a38 17074
5b97f49d
JB
17075 cb = (void **)msg->cb;
17076
17077 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
17078 if (!cb[0]) {
d6dc1a38 17079 nlmsg_free(msg);
5b97f49d 17080 return NULL;
d6dc1a38
JO
17081 }
17082
9360ffd1 17083 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 17084 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 17085 goto nla_put_failure;
d6dc1a38 17086
5b97f49d 17087 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
17088 goto nla_put_failure;
17089
ae0be8de 17090 cb[1] = nla_nest_start_noflag(msg, NL80211_ATTR_CQM);
5b97f49d 17091 if (!cb[1])
9360ffd1 17092 goto nla_put_failure;
d6dc1a38 17093
5b97f49d 17094 cb[2] = rdev;
d6dc1a38 17095
5b97f49d
JB
17096 return msg;
17097 nla_put_failure:
17098 nlmsg_free(msg);
17099 return NULL;
17100}
17101
17102static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
17103{
17104 void **cb = (void **)msg->cb;
17105 struct cfg80211_registered_device *rdev = cb[2];
17106
17107 nla_nest_end(msg, cb[1]);
17108 genlmsg_end(msg, cb[0]);
17109
17110 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 17111
68eb5503 17112 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17113 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
17114}
17115
17116void cfg80211_cqm_rssi_notify(struct net_device *dev,
17117 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 17118 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
17119{
17120 struct sk_buff *msg;
4a4b8169
AZ
17121 struct wireless_dev *wdev = dev->ieee80211_ptr;
17122 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 17123
bee427b8 17124 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 17125
98f03342
JB
17126 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
17127 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
17128 return;
17129
4a4b8169
AZ
17130 if (wdev->cqm_config) {
17131 wdev->cqm_config->last_rssi_event_value = rssi_level;
17132
17133 cfg80211_cqm_rssi_update(rdev, dev);
17134
17135 if (rssi_level == 0)
17136 rssi_level = wdev->cqm_config->last_rssi_event_value;
17137 }
17138
5b97f49d
JB
17139 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
17140 if (!msg)
17141 return;
17142
17143 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
17144 rssi_event))
17145 goto nla_put_failure;
17146
bee427b8
AZ
17147 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
17148 rssi_level))
17149 goto nla_put_failure;
17150
5b97f49d
JB
17151 cfg80211_send_cqm(msg, gfp);
17152
d6dc1a38
JO
17153 return;
17154
17155 nla_put_failure:
d6dc1a38
JO
17156 nlmsg_free(msg);
17157}
947add36 17158EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 17159
5b97f49d
JB
17160void cfg80211_cqm_txe_notify(struct net_device *dev,
17161 const u8 *peer, u32 num_packets,
17162 u32 rate, u32 intvl, gfp_t gfp)
17163{
17164 struct sk_buff *msg;
17165
17166 msg = cfg80211_prepare_cqm(dev, peer, gfp);
17167 if (!msg)
17168 return;
17169
17170 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
17171 goto nla_put_failure;
17172
17173 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
17174 goto nla_put_failure;
17175
17176 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
17177 goto nla_put_failure;
17178
17179 cfg80211_send_cqm(msg, gfp);
17180 return;
17181
17182 nla_put_failure:
17183 nlmsg_free(msg);
17184}
17185EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
17186
17187void cfg80211_cqm_pktloss_notify(struct net_device *dev,
17188 const u8 *peer, u32 num_packets, gfp_t gfp)
17189{
17190 struct sk_buff *msg;
17191
17192 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
17193
17194 msg = cfg80211_prepare_cqm(dev, peer, gfp);
17195 if (!msg)
17196 return;
17197
17198 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
17199 goto nla_put_failure;
17200
17201 cfg80211_send_cqm(msg, gfp);
17202 return;
17203
17204 nla_put_failure:
17205 nlmsg_free(msg);
17206}
17207EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
17208
98f03342
JB
17209void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
17210{
17211 struct sk_buff *msg;
17212
17213 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
17214 if (!msg)
17215 return;
17216
17217 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
17218 goto nla_put_failure;
17219
17220 cfg80211_send_cqm(msg, gfp);
17221 return;
17222
17223 nla_put_failure:
17224 nlmsg_free(msg);
17225}
17226EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
17227
947add36
JB
17228static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
17229 struct net_device *netdev, const u8 *bssid,
17230 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
17231{
17232 struct sk_buff *msg;
17233 struct nlattr *rekey_attr;
17234 void *hdr;
17235
58050fce 17236 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
17237 if (!msg)
17238 return;
17239
17240 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
17241 if (!hdr) {
17242 nlmsg_free(msg);
17243 return;
17244 }
17245
9360ffd1
DM
17246 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17247 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17248 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
17249 goto nla_put_failure;
e5497d76 17250
ae0be8de 17251 rekey_attr = nla_nest_start_noflag(msg, NL80211_ATTR_REKEY_DATA);
e5497d76
JB
17252 if (!rekey_attr)
17253 goto nla_put_failure;
17254
9360ffd1
DM
17255 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
17256 NL80211_REPLAY_CTR_LEN, replay_ctr))
17257 goto nla_put_failure;
e5497d76
JB
17258
17259 nla_nest_end(msg, rekey_attr);
17260
3b7b72ee 17261 genlmsg_end(msg, hdr);
e5497d76 17262
68eb5503 17263 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17264 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
17265 return;
17266
17267 nla_put_failure:
e5497d76
JB
17268 nlmsg_free(msg);
17269}
17270
947add36
JB
17271void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
17272 const u8 *replay_ctr, gfp_t gfp)
17273{
17274 struct wireless_dev *wdev = dev->ieee80211_ptr;
17275 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17276 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17277
17278 trace_cfg80211_gtk_rekey_notify(dev, bssid);
17279 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
17280}
17281EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
17282
17283static void
17284nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
17285 struct net_device *netdev, int index,
17286 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
17287{
17288 struct sk_buff *msg;
17289 struct nlattr *attr;
17290 void *hdr;
17291
58050fce 17292 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
17293 if (!msg)
17294 return;
17295
17296 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
17297 if (!hdr) {
17298 nlmsg_free(msg);
17299 return;
17300 }
17301
9360ffd1
DM
17302 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17303 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
17304 goto nla_put_failure;
c9df56b4 17305
ae0be8de 17306 attr = nla_nest_start_noflag(msg, NL80211_ATTR_PMKSA_CANDIDATE);
c9df56b4
JM
17307 if (!attr)
17308 goto nla_put_failure;
17309
9360ffd1
DM
17310 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
17311 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
17312 (preauth &&
17313 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
17314 goto nla_put_failure;
c9df56b4
JM
17315
17316 nla_nest_end(msg, attr);
17317
3b7b72ee 17318 genlmsg_end(msg, hdr);
c9df56b4 17319
68eb5503 17320 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17321 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
17322 return;
17323
17324 nla_put_failure:
c9df56b4
JM
17325 nlmsg_free(msg);
17326}
17327
947add36
JB
17328void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
17329 const u8 *bssid, bool preauth, gfp_t gfp)
17330{
17331 struct wireless_dev *wdev = dev->ieee80211_ptr;
17332 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17333 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
17334
17335 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
17336 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
17337}
17338EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
17339
17340static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
17341 struct net_device *netdev,
17342 struct cfg80211_chan_def *chandef,
f8d7552e
LC
17343 gfp_t gfp,
17344 enum nl80211_commands notif,
669b8413 17345 u8 count, bool quiet)
5314526b
TP
17346{
17347 struct sk_buff *msg;
17348 void *hdr;
17349
58050fce 17350 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
17351 if (!msg)
17352 return;
17353
f8d7552e 17354 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
17355 if (!hdr) {
17356 nlmsg_free(msg);
17357 return;
17358 }
17359
683b6d3b
JB
17360 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
17361 goto nla_put_failure;
17362
17363 if (nl80211_send_chandef(msg, chandef))
7eab0f64 17364 goto nla_put_failure;
5314526b 17365
669b8413
JB
17366 if (notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) {
17367 if (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count))
f8d7552e 17368 goto nla_put_failure;
669b8413
JB
17369 if (quiet &&
17370 nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX))
f8d7552e 17371 goto nla_put_failure;
669b8413 17372 }
f8d7552e 17373
5314526b
TP
17374 genlmsg_end(msg, hdr);
17375
68eb5503 17376 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17377 NL80211_MCGRP_MLME, gfp);
5314526b
TP
17378 return;
17379
17380 nla_put_failure:
5314526b
TP
17381 nlmsg_free(msg);
17382}
17383
947add36
JB
17384void cfg80211_ch_switch_notify(struct net_device *dev,
17385 struct cfg80211_chan_def *chandef)
84f10708 17386{
947add36
JB
17387 struct wireless_dev *wdev = dev->ieee80211_ptr;
17388 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17389 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 17390
e487eaeb 17391 ASSERT_WDEV_LOCK(wdev);
947add36 17392
e487eaeb 17393 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 17394
9e0e2961 17395 wdev->chandef = *chandef;
96f55f12 17396 wdev->preset_chandef = *chandef;
5dc8cdce
SM
17397
17398 if (wdev->iftype == NL80211_IFTYPE_STATION &&
17399 !WARN_ON(!wdev->current_bss))
0afd425b 17400 cfg80211_update_assoc_bss_entry(wdev, chandef->chan);
5dc8cdce 17401
d34990bb
MV
17402 cfg80211_sched_dfs_chan_update(rdev);
17403
f8d7552e 17404 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
669b8413 17405 NL80211_CMD_CH_SWITCH_NOTIFY, 0, false);
947add36
JB
17406}
17407EXPORT_SYMBOL(cfg80211_ch_switch_notify);
17408
f8d7552e
LC
17409void cfg80211_ch_switch_started_notify(struct net_device *dev,
17410 struct cfg80211_chan_def *chandef,
669b8413 17411 u8 count, bool quiet)
f8d7552e
LC
17412{
17413 struct wireless_dev *wdev = dev->ieee80211_ptr;
17414 struct wiphy *wiphy = wdev->wiphy;
17415 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
17416
17417 trace_cfg80211_ch_switch_started_notify(dev, chandef);
17418
17419 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
669b8413
JB
17420 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
17421 count, quiet);
f8d7552e
LC
17422}
17423EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
17424
04f39047
SW
17425void
17426nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 17427 const struct cfg80211_chan_def *chandef,
04f39047
SW
17428 enum nl80211_radar_event event,
17429 struct net_device *netdev, gfp_t gfp)
17430{
17431 struct sk_buff *msg;
17432 void *hdr;
17433
17434 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17435 if (!msg)
17436 return;
17437
17438 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
17439 if (!hdr) {
17440 nlmsg_free(msg);
17441 return;
17442 }
17443
17444 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
17445 goto nla_put_failure;
17446
17447 /* NOP and radar events don't need a netdev parameter */
17448 if (netdev) {
17449 struct wireless_dev *wdev = netdev->ieee80211_ptr;
17450
17451 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
17452 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17453 NL80211_ATTR_PAD))
04f39047
SW
17454 goto nla_put_failure;
17455 }
17456
17457 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
17458 goto nla_put_failure;
17459
17460 if (nl80211_send_chandef(msg, chandef))
17461 goto nla_put_failure;
17462
9c90a9f6 17463 genlmsg_end(msg, hdr);
04f39047 17464
68eb5503 17465 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17466 NL80211_MCGRP_MLME, gfp);
04f39047
SW
17467 return;
17468
17469 nla_put_failure:
04f39047
SW
17470 nlmsg_free(msg);
17471}
17472
466b9936 17473void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
17474 struct sta_opmode_info *sta_opmode,
17475 gfp_t gfp)
17476{
17477 struct sk_buff *msg;
17478 struct wireless_dev *wdev = dev->ieee80211_ptr;
17479 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
17480 void *hdr;
17481
17482 if (WARN_ON(!mac))
17483 return;
17484
17485 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17486 if (!msg)
17487 return;
17488
17489 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
17490 if (!hdr) {
17491 nlmsg_free(msg);
17492 return;
17493 }
17494
17495 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
17496 goto nla_put_failure;
17497
17498 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
17499 goto nla_put_failure;
17500
17501 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
17502 goto nla_put_failure;
17503
17504 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
17505 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
17506 goto nla_put_failure;
17507
17508 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
0016d320 17509 nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
466b9936 17510 goto nla_put_failure;
17511
17512 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
17513 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
17514 goto nla_put_failure;
17515
17516 genlmsg_end(msg, hdr);
17517
17518 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17519 NL80211_MCGRP_MLME, gfp);
17520
17521 return;
17522
17523nla_put_failure:
17524 nlmsg_free(msg);
17525}
17526EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
17527
7f6cf311 17528void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
c4b50cd3
VN
17529 u64 cookie, bool acked, s32 ack_signal,
17530 bool is_valid_ack_signal, gfp_t gfp)
7f6cf311
JB
17531{
17532 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 17533 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
17534 struct sk_buff *msg;
17535 void *hdr;
7f6cf311 17536
4ee3e063
BL
17537 trace_cfg80211_probe_status(dev, addr, cookie, acked);
17538
58050fce 17539 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 17540
7f6cf311
JB
17541 if (!msg)
17542 return;
17543
17544 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
17545 if (!hdr) {
17546 nlmsg_free(msg);
17547 return;
17548 }
17549
9360ffd1
DM
17550 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17551 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17552 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
17553 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
17554 NL80211_ATTR_PAD) ||
c4b50cd3
VN
17555 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
17556 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
17557 ack_signal)))
9360ffd1 17558 goto nla_put_failure;
7f6cf311 17559
9c90a9f6 17560 genlmsg_end(msg, hdr);
7f6cf311 17561
68eb5503 17562 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17563 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
17564 return;
17565
17566 nla_put_failure:
7f6cf311
JB
17567 nlmsg_free(msg);
17568}
17569EXPORT_SYMBOL(cfg80211_probe_status);
17570
e76fede8
TP
17571void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame,
17572 size_t len, int freq, int sig_dbm)
5e760230 17573{
f26cbf40 17574 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
17575 struct sk_buff *msg;
17576 void *hdr;
37c73b5f 17577 struct cfg80211_beacon_registration *reg;
5e760230 17578
4ee3e063
BL
17579 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
17580
37c73b5f
BG
17581 spin_lock_bh(&rdev->beacon_registrations_lock);
17582 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
17583 msg = nlmsg_new(len + 100, GFP_ATOMIC);
17584 if (!msg) {
17585 spin_unlock_bh(&rdev->beacon_registrations_lock);
17586 return;
17587 }
5e760230 17588
37c73b5f
BG
17589 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
17590 if (!hdr)
17591 goto nla_put_failure;
5e760230 17592
37c73b5f
BG
17593 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17594 (freq &&
942ba88b
TP
17595 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
17596 KHZ_TO_MHZ(freq)) ||
17597 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
17598 freq % 1000))) ||
37c73b5f
BG
17599 (sig_dbm &&
17600 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
17601 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
17602 goto nla_put_failure;
5e760230 17603
37c73b5f 17604 genlmsg_end(msg, hdr);
5e760230 17605
37c73b5f
BG
17606 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
17607 }
17608 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
17609 return;
17610
17611 nla_put_failure:
37c73b5f 17612 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
17613 nlmsg_free(msg);
17614}
e76fede8 17615EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz);
5e760230 17616
cd8f7cb4 17617#ifdef CONFIG_PM
8cd4d456
LC
17618static int cfg80211_net_detect_results(struct sk_buff *msg,
17619 struct cfg80211_wowlan_wakeup *wakeup)
17620{
17621 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
17622 struct nlattr *nl_results, *nl_match, *nl_freqs;
17623 int i, j;
17624
ae0be8de
MK
17625 nl_results = nla_nest_start_noflag(msg,
17626 NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
8cd4d456
LC
17627 if (!nl_results)
17628 return -EMSGSIZE;
17629
17630 for (i = 0; i < nd->n_matches; i++) {
17631 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
17632
ae0be8de 17633 nl_match = nla_nest_start_noflag(msg, i);
8cd4d456
LC
17634 if (!nl_match)
17635 break;
17636
17637 /* The SSID attribute is optional in nl80211, but for
17638 * simplicity reasons it's always present in the
17639 * cfg80211 structure. If a driver can't pass the
17640 * SSID, that needs to be changed. A zero length SSID
17641 * is still a valid SSID (wildcard), so it cannot be
17642 * used for this purpose.
17643 */
17644 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
17645 match->ssid.ssid)) {
17646 nla_nest_cancel(msg, nl_match);
17647 goto out;
17648 }
17649
17650 if (match->n_channels) {
ae0be8de
MK
17651 nl_freqs = nla_nest_start_noflag(msg,
17652 NL80211_ATTR_SCAN_FREQUENCIES);
8cd4d456
LC
17653 if (!nl_freqs) {
17654 nla_nest_cancel(msg, nl_match);
17655 goto out;
17656 }
17657
17658 for (j = 0; j < match->n_channels; j++) {
5528fae8 17659 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
17660 nla_nest_cancel(msg, nl_freqs);
17661 nla_nest_cancel(msg, nl_match);
17662 goto out;
17663 }
17664 }
17665
17666 nla_nest_end(msg, nl_freqs);
17667 }
17668
17669 nla_nest_end(msg, nl_match);
17670 }
17671
17672out:
17673 nla_nest_end(msg, nl_results);
17674 return 0;
17675}
17676
cd8f7cb4
JB
17677void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
17678 struct cfg80211_wowlan_wakeup *wakeup,
17679 gfp_t gfp)
17680{
f26cbf40 17681 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
17682 struct sk_buff *msg;
17683 void *hdr;
9c90a9f6 17684 int size = 200;
cd8f7cb4
JB
17685
17686 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
17687
17688 if (wakeup)
17689 size += wakeup->packet_present_len;
17690
17691 msg = nlmsg_new(size, gfp);
17692 if (!msg)
17693 return;
17694
17695 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
17696 if (!hdr)
17697 goto free_msg;
17698
17699 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
17700 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17701 NL80211_ATTR_PAD))
cd8f7cb4
JB
17702 goto free_msg;
17703
17704 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
17705 wdev->netdev->ifindex))
17706 goto free_msg;
17707
17708 if (wakeup) {
17709 struct nlattr *reasons;
17710
ae0be8de
MK
17711 reasons = nla_nest_start_noflag(msg,
17712 NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
17713 if (!reasons)
17714 goto free_msg;
cd8f7cb4
JB
17715
17716 if (wakeup->disconnect &&
17717 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
17718 goto free_msg;
17719 if (wakeup->magic_pkt &&
17720 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
17721 goto free_msg;
17722 if (wakeup->gtk_rekey_failure &&
17723 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
17724 goto free_msg;
17725 if (wakeup->eap_identity_req &&
17726 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
17727 goto free_msg;
17728 if (wakeup->four_way_handshake &&
17729 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
17730 goto free_msg;
17731 if (wakeup->rfkill_release &&
17732 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
17733 goto free_msg;
17734
17735 if (wakeup->pattern_idx >= 0 &&
17736 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
17737 wakeup->pattern_idx))
17738 goto free_msg;
17739
ae917c9f
JB
17740 if (wakeup->tcp_match &&
17741 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
17742 goto free_msg;
2a0e047e 17743
ae917c9f
JB
17744 if (wakeup->tcp_connlost &&
17745 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
17746 goto free_msg;
2a0e047e 17747
ae917c9f
JB
17748 if (wakeup->tcp_nomoretokens &&
17749 nla_put_flag(msg,
17750 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
17751 goto free_msg;
2a0e047e 17752
cd8f7cb4
JB
17753 if (wakeup->packet) {
17754 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
17755 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
17756
17757 if (!wakeup->packet_80211) {
17758 pkt_attr =
17759 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
17760 len_attr =
17761 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
17762 }
17763
17764 if (wakeup->packet_len &&
17765 nla_put_u32(msg, len_attr, wakeup->packet_len))
17766 goto free_msg;
17767
17768 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
17769 wakeup->packet))
17770 goto free_msg;
17771 }
17772
8cd4d456
LC
17773 if (wakeup->net_detect &&
17774 cfg80211_net_detect_results(msg, wakeup))
17775 goto free_msg;
17776
cd8f7cb4
JB
17777 nla_nest_end(msg, reasons);
17778 }
17779
9c90a9f6 17780 genlmsg_end(msg, hdr);
cd8f7cb4 17781
68eb5503 17782 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17783 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
17784 return;
17785
17786 free_msg:
17787 nlmsg_free(msg);
17788}
17789EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
17790#endif
17791
3475b094
JM
17792void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
17793 enum nl80211_tdls_operation oper,
17794 u16 reason_code, gfp_t gfp)
17795{
17796 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 17797 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
17798 struct sk_buff *msg;
17799 void *hdr;
3475b094
JM
17800
17801 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
17802 reason_code);
17803
17804 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17805 if (!msg)
17806 return;
17807
17808 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
17809 if (!hdr) {
17810 nlmsg_free(msg);
17811 return;
17812 }
17813
17814 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17815 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
17816 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
17817 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
17818 (reason_code > 0 &&
17819 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
17820 goto nla_put_failure;
17821
9c90a9f6 17822 genlmsg_end(msg, hdr);
3475b094 17823
68eb5503 17824 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17825 NL80211_MCGRP_MLME, gfp);
3475b094
JM
17826 return;
17827
17828 nla_put_failure:
3475b094
JM
17829 nlmsg_free(msg);
17830}
17831EXPORT_SYMBOL(cfg80211_tdls_oper_request);
17832
026331c4
JM
17833static int nl80211_netlink_notify(struct notifier_block * nb,
17834 unsigned long state,
17835 void *_notify)
17836{
17837 struct netlink_notify *notify = _notify;
17838 struct cfg80211_registered_device *rdev;
17839 struct wireless_dev *wdev;
37c73b5f 17840 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 17841
8f815cdd 17842 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
17843 return NOTIFY_DONE;
17844
17845 rcu_read_lock();
17846
5e760230 17847 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 17848 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 17849
ca986ad9
AVS
17850 list_for_each_entry_rcu(sched_scan_req,
17851 &rdev->sched_scan_req_list,
17852 list) {
17853 if (sched_scan_req->owner_nlportid == notify->portid) {
17854 sched_scan_req->nl_owner_dead = true;
753aacfd 17855 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 17856 }
753aacfd 17857 }
78f22b6a 17858
53873f13 17859 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 17860 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 17861
ab81007a
JB
17862 if (wdev->owner_nlportid == notify->portid) {
17863 wdev->nl_owner_dead = true;
17864 schedule_work(&rdev->destroy_work);
17865 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 17866 schedule_work(&wdev->disconnect_wk);
ab81007a 17867 }
9bb7e0f2
JB
17868
17869 cfg80211_release_pmsr(wdev, notify->portid);
78f22b6a
JB
17870 }
17871
37c73b5f
BG
17872 spin_lock_bh(&rdev->beacon_registrations_lock);
17873 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
17874 list) {
17875 if (reg->nlportid == notify->portid) {
17876 list_del(&reg->list);
17877 kfree(reg);
17878 break;
17879 }
17880 }
17881 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 17882 }
026331c4
JM
17883
17884 rcu_read_unlock();
17885
05050753
I
17886 /*
17887 * It is possible that the user space process that is controlling the
17888 * indoor setting disappeared, so notify the regulatory core.
17889 */
17890 regulatory_netlink_notify(notify->portid);
6784c7db 17891 return NOTIFY_OK;
026331c4
JM
17892}
17893
17894static struct notifier_block nl80211_netlink_notifier = {
17895 .notifier_call = nl80211_netlink_notify,
17896};
17897
355199e0
JM
17898void cfg80211_ft_event(struct net_device *netdev,
17899 struct cfg80211_ft_event_params *ft_event)
17900{
17901 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 17902 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
17903 struct sk_buff *msg;
17904 void *hdr;
355199e0
JM
17905
17906 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
17907
17908 if (!ft_event->target_ap)
17909 return;
17910
1039d081
DL
17911 msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
17912 GFP_KERNEL);
355199e0
JM
17913 if (!msg)
17914 return;
17915
17916 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
17917 if (!hdr)
17918 goto out;
355199e0 17919
ae917c9f
JB
17920 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17921 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
17922 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
17923 goto out;
355199e0 17924
ae917c9f
JB
17925 if (ft_event->ies &&
17926 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
17927 goto out;
17928 if (ft_event->ric_ies &&
17929 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
17930 ft_event->ric_ies))
17931 goto out;
355199e0 17932
9c90a9f6 17933 genlmsg_end(msg, hdr);
355199e0 17934
68eb5503 17935 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 17936 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
17937 return;
17938 out:
17939 nlmsg_free(msg);
355199e0
JM
17940}
17941EXPORT_SYMBOL(cfg80211_ft_event);
17942
5de17984
AS
17943void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
17944{
17945 struct cfg80211_registered_device *rdev;
17946 struct sk_buff *msg;
17947 void *hdr;
17948 u32 nlportid;
17949
f26cbf40 17950 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
17951 if (!rdev->crit_proto_nlportid)
17952 return;
17953
17954 nlportid = rdev->crit_proto_nlportid;
17955 rdev->crit_proto_nlportid = 0;
17956
17957 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
17958 if (!msg)
17959 return;
17960
17961 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
17962 if (!hdr)
17963 goto nla_put_failure;
17964
17965 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
17966 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17967 NL80211_ATTR_PAD))
5de17984
AS
17968 goto nla_put_failure;
17969
17970 genlmsg_end(msg, hdr);
17971
17972 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
17973 return;
17974
17975 nla_put_failure:
5de17984 17976 nlmsg_free(msg);
5de17984
AS
17977}
17978EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
17979
348baf0e
JB
17980void nl80211_send_ap_stopped(struct wireless_dev *wdev)
17981{
17982 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 17983 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
17984 struct sk_buff *msg;
17985 void *hdr;
17986
17987 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17988 if (!msg)
17989 return;
17990
17991 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
17992 if (!hdr)
17993 goto out;
17994
17995 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17996 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
17997 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17998 NL80211_ATTR_PAD))
348baf0e
JB
17999 goto out;
18000
18001 genlmsg_end(msg, hdr);
18002
18003 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
18004 NL80211_MCGRP_MLME, GFP_KERNEL);
18005 return;
18006 out:
18007 nlmsg_free(msg);
18008}
18009
40cbfa90
SD
18010int cfg80211_external_auth_request(struct net_device *dev,
18011 struct cfg80211_external_auth_params *params,
18012 gfp_t gfp)
18013{
18014 struct wireless_dev *wdev = dev->ieee80211_ptr;
18015 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
18016 struct sk_buff *msg;
18017 void *hdr;
18018
18019 if (!wdev->conn_owner_nlportid)
18020 return -EINVAL;
18021
18022 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18023 if (!msg)
18024 return -ENOMEM;
18025
18026 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
18027 if (!hdr)
18028 goto nla_put_failure;
18029
18030 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18031 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18032 nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
18033 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
18034 params->action) ||
18035 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
18036 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
18037 params->ssid.ssid))
18038 goto nla_put_failure;
18039
18040 genlmsg_end(msg, hdr);
18041 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
18042 wdev->conn_owner_nlportid);
18043 return 0;
18044
18045 nla_put_failure:
18046 nlmsg_free(msg);
18047 return -ENOBUFS;
18048}
18049EXPORT_SYMBOL(cfg80211_external_auth_request);
18050
cb74e977
SD
18051void cfg80211_update_owe_info_event(struct net_device *netdev,
18052 struct cfg80211_update_owe_info *owe_info,
18053 gfp_t gfp)
18054{
18055 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
18056 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18057 struct sk_buff *msg;
18058 void *hdr;
18059
18060 trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
18061
18062 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18063 if (!msg)
18064 return;
18065
18066 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
18067 if (!hdr)
18068 goto nla_put_failure;
18069
18070 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18071 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18072 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
18073 goto nla_put_failure;
18074
18075 if (!owe_info->ie_len ||
18076 nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
18077 goto nla_put_failure;
18078
18079 genlmsg_end(msg, hdr);
18080
18081 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18082 NL80211_MCGRP_MLME, gfp);
18083 return;
18084
18085nla_put_failure:
18086 genlmsg_cancel(msg, hdr);
18087 nlmsg_free(msg);
18088}
18089EXPORT_SYMBOL(cfg80211_update_owe_info_event);
18090
55682965
JB
18091/* initialisation/exit functions */
18092
56989f6d 18093int __init nl80211_init(void)
55682965 18094{
0d63cbb5 18095 int err;
55682965 18096
489111e5 18097 err = genl_register_family(&nl80211_fam);
55682965
JB
18098 if (err)
18099 return err;
18100
026331c4
JM
18101 err = netlink_register_notifier(&nl80211_netlink_notifier);
18102 if (err)
18103 goto err_out;
18104
55682965
JB
18105 return 0;
18106 err_out:
18107 genl_unregister_family(&nl80211_fam);
18108 return err;
18109}
18110
18111void nl80211_exit(void)
18112{
026331c4 18113 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
18114 genl_unregister_family(&nl80211_fam);
18115}