mac80211: free peer keys before vif down in mesh
[linux-block.git] / net / wireless / nl80211.c
CommitLineData
55682965
JB
1/*
2 * This is the new netlink-based wireless configuration interface.
3 *
026331c4 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
2740f0cf 5 * Copyright 2013-2014 Intel Mobile Communications GmbH
66cd794e 6 * Copyright 2015-2017 Intel Deutschland GmbH
55c1fdf0 7 * Copyright (C) 2018-2019 Intel Corporation
55682965
JB
8 */
9
10#include <linux/if.h>
11#include <linux/module.h>
12#include <linux/err.h>
5a0e3ad6 13#include <linux/slab.h>
55682965
JB
14#include <linux/list.h>
15#include <linux/if_ether.h>
16#include <linux/ieee80211.h>
17#include <linux/nl80211.h>
18#include <linux/rtnetlink.h>
19#include <linux/netlink.h>
259d8c1e 20#include <linux/nospec.h>
2a519311 21#include <linux/etherdevice.h>
463d0183 22#include <net/net_namespace.h>
55682965
JB
23#include <net/genetlink.h>
24#include <net/cfg80211.h>
463d0183 25#include <net/sock.h>
2a0e047e 26#include <net/inet_connection_sock.h>
55682965
JB
27#include "core.h"
28#include "nl80211.h"
b2e1b302 29#include "reg.h"
e35e4d28 30#include "rdev-ops.h"
55682965 31
5fb628e9
JM
32static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
33 struct genl_info *info,
34 struct cfg80211_crypto_settings *settings,
35 int cipher_limit);
36
55682965 37/* the netlink family */
489111e5 38static struct genl_family nl80211_fam;
55682965 39
2a94fe48
JB
40/* multicast groups */
41enum nl80211_multicast_groups {
42 NL80211_MCGRP_CONFIG,
43 NL80211_MCGRP_SCAN,
44 NL80211_MCGRP_REGULATORY,
45 NL80211_MCGRP_MLME,
567ffc35 46 NL80211_MCGRP_VENDOR,
50bcd31d 47 NL80211_MCGRP_NAN,
2a94fe48
JB
48 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
49};
50
51static const struct genl_multicast_group nl80211_mcgrps[] = {
71b836ec
JB
52 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
53 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
54 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
55 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
56 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
50bcd31d 57 [NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
2a94fe48 58#ifdef CONFIG_NL80211_TESTMODE
71b836ec 59 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
2a94fe48
JB
60#endif
61};
62
89a54e48
JB
63/* returns ERR_PTR values */
64static struct wireless_dev *
65__cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
55682965 66{
89a54e48
JB
67 struct cfg80211_registered_device *rdev;
68 struct wireless_dev *result = NULL;
69 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
70 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
71 u64 wdev_id;
72 int wiphy_idx = -1;
73 int ifidx = -1;
55682965 74
5fe231e8 75 ASSERT_RTNL();
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
89a54e48
JB
87 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
88 struct wireless_dev *wdev;
89
90 if (wiphy_net(&rdev->wiphy) != netns)
91 continue;
92
93 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
94 continue;
95
53873f13 96 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
89a54e48
JB
97 if (have_ifidx && wdev->netdev &&
98 wdev->netdev->ifindex == ifidx) {
99 result = wdev;
100 break;
101 }
102 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
103 result = wdev;
104 break;
105 }
106 }
89a54e48
JB
107
108 if (result)
109 break;
110 }
111
112 if (result)
113 return result;
114 return ERR_PTR(-ENODEV);
55682965
JB
115}
116
a9455408 117static struct cfg80211_registered_device *
878d9ec7 118__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
a9455408 119{
7fee4778
JB
120 struct cfg80211_registered_device *rdev = NULL, *tmp;
121 struct net_device *netdev;
a9455408 122
5fe231e8 123 ASSERT_RTNL();
a9455408 124
878d9ec7 125 if (!attrs[NL80211_ATTR_WIPHY] &&
89a54e48
JB
126 !attrs[NL80211_ATTR_IFINDEX] &&
127 !attrs[NL80211_ATTR_WDEV])
7fee4778
JB
128 return ERR_PTR(-EINVAL);
129
878d9ec7 130 if (attrs[NL80211_ATTR_WIPHY])
7fee4778 131 rdev = cfg80211_rdev_by_wiphy_idx(
878d9ec7 132 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
a9455408 133
89a54e48
JB
134 if (attrs[NL80211_ATTR_WDEV]) {
135 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
136 struct wireless_dev *wdev;
137 bool found = false;
138
139 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
140 if (tmp) {
141 /* make sure wdev exists */
53873f13 142 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
89a54e48
JB
143 if (wdev->identifier != (u32)wdev_id)
144 continue;
145 found = true;
146 break;
147 }
89a54e48
JB
148
149 if (!found)
150 tmp = NULL;
151
152 if (rdev && tmp != rdev)
153 return ERR_PTR(-EINVAL);
154 rdev = tmp;
155 }
156 }
157
878d9ec7
JB
158 if (attrs[NL80211_ATTR_IFINDEX]) {
159 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
7a087e74 160
7f2b8562 161 netdev = __dev_get_by_index(netns, ifindex);
7fee4778
JB
162 if (netdev) {
163 if (netdev->ieee80211_ptr)
f26cbf40
ZG
164 tmp = wiphy_to_rdev(
165 netdev->ieee80211_ptr->wiphy);
7fee4778
JB
166 else
167 tmp = NULL;
168
7fee4778
JB
169 /* not wireless device -- return error */
170 if (!tmp)
171 return ERR_PTR(-EINVAL);
172
173 /* mismatch -- return error */
174 if (rdev && tmp != rdev)
175 return ERR_PTR(-EINVAL);
176
177 rdev = tmp;
a9455408 178 }
a9455408 179 }
a9455408 180
4f7eff10
JB
181 if (!rdev)
182 return ERR_PTR(-ENODEV);
a9455408 183
4f7eff10
JB
184 if (netns != wiphy_net(&rdev->wiphy))
185 return ERR_PTR(-ENODEV);
186
187 return rdev;
a9455408
JB
188}
189
190/*
191 * This function returns a pointer to the driver
192 * that the genl_info item that is passed refers to.
a9455408
JB
193 *
194 * The result of this can be a PTR_ERR and hence must
195 * be checked with IS_ERR() for errors.
196 */
197static struct cfg80211_registered_device *
4f7eff10 198cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
a9455408 199{
5fe231e8 200 return __cfg80211_rdev_from_attrs(netns, info->attrs);
a9455408
JB
201}
202
3d7af878
JB
203static int validate_ie_attr(const struct nlattr *attr,
204 struct netlink_ext_ack *extack)
205{
9f308616
JB
206 const u8 *data = nla_data(attr);
207 unsigned int len = nla_len(attr);
7388afe0 208 const struct element *elem;
3d7af878 209
9f308616
JB
210 for_each_element(elem, data, len) {
211 /* nothing */
3d7af878
JB
212 }
213
9f308616
JB
214 if (for_each_element_completed(elem, data, len))
215 return 0;
216
3d7af878
JB
217 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed information elements");
218 return -EINVAL;
219}
220
55682965 221/* policy for the attributes */
81e54d08
PKC
222static const struct nla_policy
223nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
224 [NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
225 [NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
226 .len = U8_MAX },
227 [NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
228 .len = U8_MAX },
229};
230
9bb7e0f2
JB
231static const struct nla_policy
232nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
233 [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
234 [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
235 [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
236 NLA_POLICY_MAX(NLA_U8, 15),
237 [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
238 [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
239 NLA_POLICY_MAX(NLA_U8, 15),
240 [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] =
ea18709a 241 NLA_POLICY_MAX(NLA_U8, 31),
9bb7e0f2
JB
242 [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
243 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
244 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
245};
246
247static const struct nla_policy
248nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
249 [NL80211_PMSR_TYPE_FTM] =
23323289 250 NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
9bb7e0f2
JB
251};
252
253static const struct nla_policy
254nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
255 [NL80211_PMSR_REQ_ATTR_DATA] =
23323289 256 NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
9bb7e0f2
JB
257 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
258};
259
260static const struct nla_policy
261nl80211_psmr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
262 [NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
263 /*
264 * we could specify this again to be the top-level policy,
265 * but that would open us up to recursion problems ...
266 */
267 [NL80211_PMSR_PEER_ATTR_CHAN] = { .type = NLA_NESTED },
268 [NL80211_PMSR_PEER_ATTR_REQ] =
23323289 269 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
9bb7e0f2
JB
270 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
271};
272
273static const struct nla_policy
274nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
275 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
276 [NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
277 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
278 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
279 [NL80211_PMSR_ATTR_PEERS] =
23323289 280 NLA_POLICY_NESTED_ARRAY(nl80211_psmr_peer_attr_policy),
9bb7e0f2
JB
281};
282
283const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
55682965
JB
284 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
285 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
079e24ed 286 .len = 20-1 },
31888487 287 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
3d9d1d66 288
72bdcf34 289 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
094d05dc 290 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
3d9d1d66
JB
291 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
292 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
293 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
294
ab0d76f6
JB
295 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
296 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
b9a5f8ca
JM
297 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
298 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
81077e82 299 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
3057dbfd 300 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
55682965 301
ab0d76f6 302 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
55682965
JB
303 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
304 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
41ade00f 305
e007b857
EP
306 [NL80211_ATTR_MAC] = { .len = ETH_ALEN },
307 [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
41ade00f 308
b9454e83 309 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
41ade00f
JB
310 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
311 .len = WLAN_MAX_KEY_LEN },
ab0d76f6 312 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 5),
41ade00f
JB
313 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
314 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
81962267 315 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
ab0d76f6
JB
316 [NL80211_ATTR_KEY_TYPE] =
317 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
ed1b6cc7
JB
318
319 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
320 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
321 [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY,
322 .len = IEEE80211_MAX_DATA_LEN },
3d7af878
JB
323 [NL80211_ATTR_BEACON_TAIL] =
324 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
325 IEEE80211_MAX_DATA_LEN),
ab0d76f6
JB
326 [NL80211_ATTR_STA_AID] =
327 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
5727ef1b
JB
328 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
329 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
330 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
331 .len = NL80211_MAX_SUPP_RATES },
ab0d76f6
JB
332 [NL80211_ATTR_STA_PLINK_ACTION] =
333 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
e96d1cd2
ARN
334 [NL80211_ATTR_STA_TX_POWER_SETTING] =
335 NLA_POLICY_RANGE(NLA_U8,
336 NL80211_TX_POWER_AUTOMATIC,
337 NL80211_TX_POWER_FIXED),
338 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
5727ef1b 339 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
0a9542ee 340 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
2ec600d6 341 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
a4f606ea 342 .len = IEEE80211_MAX_MESH_ID_LEN },
2ec600d6 343 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
9f1ba906 344
b2e1b302
LR
345 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
346 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
347
9f1ba906
JM
348 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
349 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
350 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
90c97a04
JM
351 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
352 .len = NL80211_MAX_SUPP_RATES },
50b12f59 353 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
36aedc90 354
24bdd9f4 355 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
15d5dda6 356 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
93da9cc1 357
6c739419 358 [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
9aed3cc1
JM
359
360 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
3d7af878
JB
361 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
362 validate_ie_attr,
363 IEEE80211_MAX_DATA_LEN),
2a519311
JB
364 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
365 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
636a5d36
JM
366
367 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
368 .len = IEEE80211_MAX_SSID_LEN },
369 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
370 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
04a773ad 371 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
1965c853 372 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
ab0d76f6
JB
373 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
374 NL80211_MFP_NO,
375 NL80211_MFP_OPTIONAL),
eccb8e8f
JB
376 [NL80211_ATTR_STA_FLAGS2] = {
377 .len = sizeof(struct nl80211_sta_flag_update),
378 },
3f77316c 379 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
c0692b8f
JB
380 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
381 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
64bf3d4b 382 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
b23aa676
SO
383 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
384 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
385 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
463d0183 386 [NL80211_ATTR_PID] = { .type = NLA_U32 },
8b787643 387 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
9361df14 388 [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
9588bbd5
JM
389 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
390 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
13ae75b1 391 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
026331c4
JM
392 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
393 .len = IEEE80211_MAX_DATA_LEN },
394 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
ab0d76f6
JB
395 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
396 NL80211_PS_DISABLED,
397 NL80211_PS_ENABLED),
d6dc1a38 398 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
d5cdfacb 399 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
fd8aaaf3 400 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
98d2ff8b
JO
401 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
402 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
2e161f78 403 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
afe0cbf8
BR
404 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
405 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
885a46d0 406 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
f7ca38df 407 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
dbd2fd65 408 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
ff1b6e69 409 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
ab0d76f6
JB
410 [NL80211_ATTR_STA_PLINK_STATE] =
411 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
412 [NL80211_ATTR_MESH_PEER_AID] =
413 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
bbe6ad6d 414 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
e5497d76 415 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
34850ab2 416 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
ab0d76f6
JB
417 [NL80211_ATTR_HIDDEN_SSID] =
418 NLA_POLICY_RANGE(NLA_U32,
419 NL80211_HIDDEN_SSID_NOT_IN_USE,
420 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
3d7af878
JB
421 [NL80211_ATTR_IE_PROBE_RESP] =
422 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
423 IEEE80211_MAX_DATA_LEN),
424 [NL80211_ATTR_IE_ASSOC_RESP] =
425 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
426 IEEE80211_MAX_DATA_LEN),
f4b34b55 427 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
a1f1c21c 428 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
e9f935e3 429 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
109086ce
AN
430 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
431 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
432 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
433 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
434 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
31fa97c5 435 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
e247bd90 436 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
00f740e1
AN
437 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
438 .len = IEEE80211_MAX_DATA_LEN },
8b60b078 439 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
7e7c8926
BG
440 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
441 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
442 .len = NL80211_HT_CAPABILITY_LEN
443 },
1d9d9213 444 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
1b658f11 445 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
4486ea98 446 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
89a54e48 447 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
57b5ce07 448 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
11b6b5a4 449 [NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
f461be3e 450 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
ed473771 451 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
ab0d76f6
JB
452 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
453 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
454 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
455 NLA_POLICY_RANGE(NLA_U32,
456 NL80211_MESH_POWER_UNKNOWN + 1,
457 NL80211_MESH_POWER_MAX),
77765eaf
VT
458 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
459 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
9d62a986
JM
460 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
461 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
3713b4e3 462 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
ee2aca34
JB
463 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
464 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
465 .len = NL80211_VHT_CAPABILITY_LEN,
466 },
355199e0
JM
467 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
468 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
469 .len = IEEE80211_MAX_DATA_LEN },
ab0d76f6
JB
470 [NL80211_ATTR_PEER_AID] =
471 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
16ef1fe2
SW
472 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
473 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
474 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
9a774c78
AO
475 [NL80211_ATTR_CSA_C_OFF_BEACON] = { .type = NLA_BINARY },
476 [NL80211_ATTR_CSA_C_OFF_PRESP] = { .type = NLA_BINARY },
c01fc9ad
SD
477 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = { .type = NLA_BINARY },
478 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] = { .type = NLA_BINARY },
5336fa88 479 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
60f4a7b1 480 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
ad7e718c
JB
481 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
482 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
483 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
fa9ffc74
KP
484 [NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
485 .len = IEEE80211_QOS_MAP_LEN_MAX },
1df4a510
JM
486 [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
487 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
df942e7b 488 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
18e5ca65 489 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
34d22ce2 490 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
bab5ab7d 491 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
ab0d76f6
JB
492 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
493 [NL80211_ATTR_USER_PRIO] =
494 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
960d01ac 495 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
18998c38 496 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
ad2b26ab 497 [NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
1bdd716c 498 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
4b681c82 499 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
9c748934 500 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
05050753 501 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
34d50519 502 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
38de03d2 503 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
ab0d76f6
JB
504 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
505 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
c6e6a0c8
AE
506 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
507 .len = VHT_MUMIMO_GROUPS_DATA_LEN
508 },
509 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
ab0d76f6 510 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
8585989d 511 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
a442b761 512 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
348bd456
JM
513 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
514 .len = FILS_MAX_KEK_LEN },
515 [NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
ce0ce13a 516 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
2fa436b3 517 [NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
bf95ecdb 518 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
519 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
520 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
521 },
3093ebbe 522 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
a3caf744
VK
523 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
524 .len = FILS_ERP_MAX_USERNAME_LEN },
525 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
526 .len = FILS_ERP_MAX_REALM_LEN },
527 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
528 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
529 .len = FILS_ERP_MAX_RRK_LEN },
530 [NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
531 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
ca986ad9 532 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
40cbfa90 533 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
52539ca8
THJ
534
535 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
536 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
537 [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 },
c4cbaf79
LC
538 [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY,
539 .len = NL80211_HE_MAX_CAPABILITY_LEN },
81e54d08
PKC
540
541 [NL80211_ATTR_FTM_RESPONDER] = {
542 .type = NLA_NESTED,
543 .validation_data = nl80211_ftm_responder_policy,
544 },
9bb7e0f2
JB
545 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
546 [NL80211_ATTR_PEER_MEASUREMENTS] =
23323289 547 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
36647055 548 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
55682965
JB
549};
550
e31b8213 551/* policy for the key attributes */
b54452b0 552static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
fffd0934 553 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
b9454e83
JB
554 [NL80211_KEY_IDX] = { .type = NLA_U8 },
555 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
81962267 556 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
b9454e83
JB
557 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
558 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
ab0d76f6 559 [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
dbd2fd65 560 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
6cdd3979 561 [NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
dbd2fd65
JB
562};
563
564/* policy for the key default flags */
565static const struct nla_policy
566nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
567 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
568 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
b9454e83
JB
569};
570
f83ace3b 571#ifdef CONFIG_PM
ff1b6e69
JB
572/* policy for WoWLAN attributes */
573static const struct nla_policy
574nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
575 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
576 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
577 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
578 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
77dbbb13
JB
579 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
580 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
581 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
582 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
2a0e047e 583 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
8cd4d456 584 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
2a0e047e
JB
585};
586
587static const struct nla_policy
588nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
589 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
590 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
591 [NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
592 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
593 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
594 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
595 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
596 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
597 },
598 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
599 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
600 },
601 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
602 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
603 [NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
ff1b6e69 604};
f83ace3b 605#endif /* CONFIG_PM */
ff1b6e69 606
be29b99a
AK
607/* policy for coalesce rule attributes */
608static const struct nla_policy
609nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
610 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
ab0d76f6
JB
611 [NL80211_ATTR_COALESCE_RULE_CONDITION] =
612 NLA_POLICY_RANGE(NLA_U32,
613 NL80211_COALESCE_CONDITION_MATCH,
614 NL80211_COALESCE_CONDITION_NO_MATCH),
be29b99a
AK
615 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
616};
617
e5497d76
JB
618/* policy for GTK rekey offload attributes */
619static const struct nla_policy
620nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
621 [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
622 [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
623 [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
624};
625
1e1b11b6 626static const struct nla_policy
627nl80211_match_band_rssi_policy[NUM_NL80211_BANDS] = {
628 [NL80211_BAND_2GHZ] = { .type = NLA_S32 },
629 [NL80211_BAND_5GHZ] = { .type = NLA_S32 },
630 [NL80211_BAND_60GHZ] = { .type = NLA_S32 },
631};
632
a1f1c21c
LC
633static const struct nla_policy
634nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
4a4ab0d7 635 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
a1f1c21c 636 .len = IEEE80211_MAX_SSID_LEN },
3007e352 637 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
88e920b4 638 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
1e1b11b6 639 [NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
640 NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
a1f1c21c
LC
641};
642
3b06d277
AS
643static const struct nla_policy
644nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
645 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
646 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
647};
648
38de03d2
AS
649static const struct nla_policy
650nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
651 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
652 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
653 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
654 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
655 },
656};
657
a442b761
AB
658/* policy for NAN function attributes */
659static const struct nla_policy
660nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
661 [NL80211_NAN_FUNC_TYPE] = { .type = NLA_U8 },
0a27844c 662 [NL80211_NAN_FUNC_SERVICE_ID] = {
a442b761
AB
663 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
664 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
665 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
666 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
667 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
668 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
669 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
670 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
671 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
672 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
673 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
674 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
675 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
676 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
677 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
678 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
679};
680
681/* policy for Service Response Filter attributes */
682static const struct nla_policy
683nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
684 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
685 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
686 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
687 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
688 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
689};
690
ad670233
PX
691/* policy for packet pattern attributes */
692static const struct nla_policy
693nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
694 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
695 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
696 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
697};
698
9bb7e0f2
JB
699int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
700 struct cfg80211_registered_device **rdev,
701 struct wireless_dev **wdev)
a043897a 702{
97990a06 703 int err;
a043897a 704
97990a06 705 if (!cb->args[0]) {
8cb08174
JB
706 err = nlmsg_parse_deprecated(cb->nlh,
707 GENL_HDRLEN + nl80211_fam.hdrsize,
708 genl_family_attrbuf(&nl80211_fam),
709 nl80211_fam.maxattr,
710 nl80211_policy, NULL);
97990a06 711 if (err)
ea90e0dc 712 return err;
67748893 713
c90c39da 714 *wdev = __cfg80211_wdev_from_attrs(
5297c65c 715 sock_net(cb->skb->sk),
c90c39da 716 genl_family_attrbuf(&nl80211_fam));
ea90e0dc
JB
717 if (IS_ERR(*wdev))
718 return PTR_ERR(*wdev);
f26cbf40 719 *rdev = wiphy_to_rdev((*wdev)->wiphy);
c319d50b
JB
720 /* 0 is the first index - add 1 to parse only once */
721 cb->args[0] = (*rdev)->wiphy_idx + 1;
97990a06
JB
722 cb->args[1] = (*wdev)->identifier;
723 } else {
c319d50b
JB
724 /* subtract the 1 again here */
725 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
97990a06 726 struct wireless_dev *tmp;
67748893 727
ea90e0dc
JB
728 if (!wiphy)
729 return -ENODEV;
f26cbf40 730 *rdev = wiphy_to_rdev(wiphy);
97990a06 731 *wdev = NULL;
67748893 732
53873f13 733 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
97990a06
JB
734 if (tmp->identifier == cb->args[1]) {
735 *wdev = tmp;
736 break;
737 }
738 }
67748893 739
ea90e0dc
JB
740 if (!*wdev)
741 return -ENODEV;
67748893
JB
742 }
743
67748893 744 return 0;
67748893
JB
745}
746
55682965 747/* message building helper */
9bb7e0f2
JB
748void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
749 int flags, u8 cmd)
55682965
JB
750{
751 /* since there is no private header just add the generic one */
15e47304 752 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
55682965
JB
753}
754
50f32718
HD
755static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
756 const struct ieee80211_reg_rule *rule)
757{
758 int j;
759 struct nlattr *nl_wmm_rules =
ae0be8de 760 nla_nest_start_noflag(msg, NL80211_FREQUENCY_ATTR_WMM);
50f32718
HD
761
762 if (!nl_wmm_rules)
763 goto nla_put_failure;
764
765 for (j = 0; j < IEEE80211_NUM_ACS; j++) {
ae0be8de 766 struct nlattr *nl_wmm_rule = nla_nest_start_noflag(msg, j);
50f32718
HD
767
768 if (!nl_wmm_rule)
769 goto nla_put_failure;
770
771 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
38cb87ee 772 rule->wmm_rule.client[j].cw_min) ||
50f32718 773 nla_put_u16(msg, NL80211_WMMR_CW_MAX,
38cb87ee 774 rule->wmm_rule.client[j].cw_max) ||
50f32718 775 nla_put_u8(msg, NL80211_WMMR_AIFSN,
38cb87ee 776 rule->wmm_rule.client[j].aifsn) ||
d3c89bbc
HD
777 nla_put_u16(msg, NL80211_WMMR_TXOP,
778 rule->wmm_rule.client[j].cot))
50f32718
HD
779 goto nla_put_failure;
780
781 nla_nest_end(msg, nl_wmm_rule);
782 }
783 nla_nest_end(msg, nl_wmm_rules);
784
785 return 0;
786
787nla_put_failure:
788 return -ENOBUFS;
789}
790
791static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
cdc89b97
JB
792 struct ieee80211_channel *chan,
793 bool large)
5dab3b8a 794{
ea077c1c
RL
795 /* Some channels must be completely excluded from the
796 * list to protect old user-space tools from breaking
797 */
798 if (!large && chan->flags &
799 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
800 return 0;
801
9360ffd1
DM
802 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
803 chan->center_freq))
804 goto nla_put_failure;
5dab3b8a 805
9360ffd1
DM
806 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
807 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
808 goto nla_put_failure;
8fe02e16
LR
809 if (chan->flags & IEEE80211_CHAN_NO_IR) {
810 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
811 goto nla_put_failure;
812 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
813 goto nla_put_failure;
814 }
cdc89b97
JB
815 if (chan->flags & IEEE80211_CHAN_RADAR) {
816 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
817 goto nla_put_failure;
818 if (large) {
819 u32 time;
820
821 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
822
823 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
824 chan->dfs_state))
825 goto nla_put_failure;
826 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
827 time))
828 goto nla_put_failure;
089027e5
JD
829 if (nla_put_u32(msg,
830 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
831 chan->dfs_cac_ms))
832 goto nla_put_failure;
cdc89b97
JB
833 }
834 }
5dab3b8a 835
fe1abafd
JB
836 if (large) {
837 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
838 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
839 goto nla_put_failure;
840 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
841 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
842 goto nla_put_failure;
843 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
844 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
845 goto nla_put_failure;
846 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
847 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
848 goto nla_put_failure;
570dbde1
DS
849 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
850 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
851 goto nla_put_failure;
06f207fc
AN
852 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
853 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
570dbde1 854 goto nla_put_failure;
ea077c1c
RL
855 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
856 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
857 goto nla_put_failure;
858 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
859 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
860 goto nla_put_failure;
fe1abafd
JB
861 }
862
9360ffd1
DM
863 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
864 DBM_TO_MBM(chan->max_power)))
865 goto nla_put_failure;
5dab3b8a 866
50f32718
HD
867 if (large) {
868 const struct ieee80211_reg_rule *rule =
b88d26d9 869 freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
50f32718 870
38cb87ee 871 if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
50f32718
HD
872 if (nl80211_msg_put_wmm_rules(msg, rule))
873 goto nla_put_failure;
874 }
875 }
876
5dab3b8a
LR
877 return 0;
878
879 nla_put_failure:
880 return -ENOBUFS;
881}
882
52539ca8
THJ
883static bool nl80211_put_txq_stats(struct sk_buff *msg,
884 struct cfg80211_txq_stats *txqstats,
885 int attrtype)
886{
887 struct nlattr *txqattr;
888
889#define PUT_TXQVAL_U32(attr, memb) do { \
890 if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) && \
891 nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
892 return false; \
893 } while (0)
894
ae0be8de 895 txqattr = nla_nest_start_noflag(msg, attrtype);
52539ca8
THJ
896 if (!txqattr)
897 return false;
898
899 PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
900 PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
901 PUT_TXQVAL_U32(FLOWS, flows);
902 PUT_TXQVAL_U32(DROPS, drops);
903 PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
904 PUT_TXQVAL_U32(OVERLIMIT, overlimit);
905 PUT_TXQVAL_U32(OVERMEMORY, overmemory);
906 PUT_TXQVAL_U32(COLLISIONS, collisions);
907 PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
908 PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
909 PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
910 nla_nest_end(msg, txqattr);
911
912#undef PUT_TXQVAL_U32
913 return true;
914}
915
55682965
JB
916/* netlink command implementations */
917
b9454e83
JB
918struct key_parse {
919 struct key_params p;
920 int idx;
e31b8213 921 int type;
b9454e83 922 bool def, defmgmt;
dbd2fd65 923 bool def_uni, def_multi;
b9454e83
JB
924};
925
768075eb
JB
926static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
927 struct key_parse *k)
b9454e83
JB
928{
929 struct nlattr *tb[NL80211_KEY_MAX + 1];
8cb08174
JB
930 int err = nla_parse_nested_deprecated(tb, NL80211_KEY_MAX, key,
931 nl80211_key_policy,
932 info->extack);
b9454e83
JB
933 if (err)
934 return err;
935
936 k->def = !!tb[NL80211_KEY_DEFAULT];
937 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
938
dbd2fd65
JB
939 if (k->def) {
940 k->def_uni = true;
941 k->def_multi = true;
942 }
943 if (k->defmgmt)
944 k->def_multi = true;
945
b9454e83
JB
946 if (tb[NL80211_KEY_IDX])
947 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
948
949 if (tb[NL80211_KEY_DATA]) {
950 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
951 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
952 }
953
954 if (tb[NL80211_KEY_SEQ]) {
955 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
956 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
957 }
958
959 if (tb[NL80211_KEY_CIPHER])
960 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
961
ab0d76f6 962 if (tb[NL80211_KEY_TYPE])
e31b8213 963 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
e31b8213 964
dbd2fd65
JB
965 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
966 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
7a087e74 967
8cb08174
JB
968 err = nla_parse_nested_deprecated(kdt,
969 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
970 tb[NL80211_KEY_DEFAULT_TYPES],
971 nl80211_key_default_policy,
972 info->extack);
dbd2fd65
JB
973 if (err)
974 return err;
975
976 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
977 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
978 }
979
6cdd3979
AW
980 if (tb[NL80211_KEY_MODE])
981 k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
982
b9454e83
JB
983 return 0;
984}
985
986static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
987{
988 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
989 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
990 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
991 }
992
993 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
994 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
995 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
996 }
997
998 if (info->attrs[NL80211_ATTR_KEY_IDX])
999 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1000
1001 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
1002 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1003
1004 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
1005 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
1006
dbd2fd65
JB
1007 if (k->def) {
1008 k->def_uni = true;
1009 k->def_multi = true;
1010 }
1011 if (k->defmgmt)
1012 k->def_multi = true;
1013
ab0d76f6 1014 if (info->attrs[NL80211_ATTR_KEY_TYPE])
e31b8213 1015 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
e31b8213 1016
dbd2fd65
JB
1017 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
1018 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
8cb08174
JB
1019 int err = nla_parse_nested_deprecated(kdt,
1020 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1021 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
1022 nl80211_key_default_policy,
1023 info->extack);
dbd2fd65
JB
1024 if (err)
1025 return err;
1026
1027 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1028 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1029 }
1030
b9454e83
JB
1031 return 0;
1032}
1033
1034static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
1035{
1036 int err;
1037
1038 memset(k, 0, sizeof(*k));
1039 k->idx = -1;
e31b8213 1040 k->type = -1;
b9454e83
JB
1041
1042 if (info->attrs[NL80211_ATTR_KEY])
768075eb 1043 err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
b9454e83
JB
1044 else
1045 err = nl80211_parse_key_old(info, k);
1046
1047 if (err)
1048 return err;
1049
768075eb
JB
1050 if (k->def && k->defmgmt) {
1051 GENL_SET_ERR_MSG(info, "key with def && defmgmt is invalid");
b9454e83 1052 return -EINVAL;
768075eb 1053 }
b9454e83 1054
dbd2fd65 1055 if (k->defmgmt) {
768075eb
JB
1056 if (k->def_uni || !k->def_multi) {
1057 GENL_SET_ERR_MSG(info, "defmgmt key must be mcast");
dbd2fd65 1058 return -EINVAL;
768075eb 1059 }
dbd2fd65
JB
1060 }
1061
b9454e83
JB
1062 if (k->idx != -1) {
1063 if (k->defmgmt) {
768075eb
JB
1064 if (k->idx < 4 || k->idx > 5) {
1065 GENL_SET_ERR_MSG(info,
1066 "defmgmt key idx not 4 or 5");
b9454e83 1067 return -EINVAL;
768075eb 1068 }
b9454e83 1069 } else if (k->def) {
768075eb
JB
1070 if (k->idx < 0 || k->idx > 3) {
1071 GENL_SET_ERR_MSG(info, "def key idx not 0-3");
b9454e83 1072 return -EINVAL;
768075eb 1073 }
b9454e83 1074 } else {
768075eb
JB
1075 if (k->idx < 0 || k->idx > 5) {
1076 GENL_SET_ERR_MSG(info, "key idx not 0-5");
b9454e83 1077 return -EINVAL;
768075eb 1078 }
b9454e83
JB
1079 }
1080 }
1081
1082 return 0;
1083}
1084
fffd0934
JB
1085static struct cfg80211_cached_keys *
1086nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
768075eb 1087 struct genl_info *info, bool *no_ht)
fffd0934 1088{
768075eb 1089 struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
fffd0934
JB
1090 struct key_parse parse;
1091 struct nlattr *key;
1092 struct cfg80211_cached_keys *result;
1093 int rem, err, def = 0;
f1c1f17a
JB
1094 bool have_key = false;
1095
1096 nla_for_each_nested(key, keys, rem) {
1097 have_key = true;
1098 break;
1099 }
1100
1101 if (!have_key)
1102 return NULL;
fffd0934
JB
1103
1104 result = kzalloc(sizeof(*result), GFP_KERNEL);
1105 if (!result)
1106 return ERR_PTR(-ENOMEM);
1107
1108 result->def = -1;
fffd0934
JB
1109
1110 nla_for_each_nested(key, keys, rem) {
1111 memset(&parse, 0, sizeof(parse));
1112 parse.idx = -1;
1113
768075eb 1114 err = nl80211_parse_key_new(info, key, &parse);
fffd0934
JB
1115 if (err)
1116 goto error;
1117 err = -EINVAL;
1118 if (!parse.p.key)
1119 goto error;
768075eb
JB
1120 if (parse.idx < 0 || parse.idx > 3) {
1121 GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
fffd0934 1122 goto error;
768075eb 1123 }
fffd0934 1124 if (parse.def) {
768075eb
JB
1125 if (def) {
1126 GENL_SET_ERR_MSG(info,
1127 "only one key can be default");
fffd0934 1128 goto error;
768075eb 1129 }
fffd0934
JB
1130 def = 1;
1131 result->def = parse.idx;
dbd2fd65
JB
1132 if (!parse.def_uni || !parse.def_multi)
1133 goto error;
fffd0934
JB
1134 } else if (parse.defmgmt)
1135 goto error;
1136 err = cfg80211_validate_key_settings(rdev, &parse.p,
e31b8213 1137 parse.idx, false, NULL);
fffd0934
JB
1138 if (err)
1139 goto error;
386b1f27
JB
1140 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1141 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
768075eb 1142 GENL_SET_ERR_MSG(info, "connect key must be WEP");
386b1f27
JB
1143 err = -EINVAL;
1144 goto error;
1145 }
fffd0934
JB
1146 result->params[parse.idx].cipher = parse.p.cipher;
1147 result->params[parse.idx].key_len = parse.p.key_len;
1148 result->params[parse.idx].key = result->data[parse.idx];
1149 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
de7044ee 1150
386b1f27
JB
1151 /* must be WEP key if we got here */
1152 if (no_ht)
1153 *no_ht = true;
fffd0934
JB
1154 }
1155
f1c1f17a
JB
1156 if (result->def < 0) {
1157 err = -EINVAL;
768075eb 1158 GENL_SET_ERR_MSG(info, "need a default/TX key");
f1c1f17a
JB
1159 goto error;
1160 }
1161
fffd0934
JB
1162 return result;
1163 error:
1164 kfree(result);
1165 return ERR_PTR(err);
1166}
1167
1168static int nl80211_key_allowed(struct wireless_dev *wdev)
1169{
1170 ASSERT_WDEV_LOCK(wdev);
1171
fffd0934
JB
1172 switch (wdev->iftype) {
1173 case NL80211_IFTYPE_AP:
1174 case NL80211_IFTYPE_AP_VLAN:
074ac8df 1175 case NL80211_IFTYPE_P2P_GO:
ff973af7 1176 case NL80211_IFTYPE_MESH_POINT:
fffd0934
JB
1177 break;
1178 case NL80211_IFTYPE_ADHOC:
fffd0934 1179 case NL80211_IFTYPE_STATION:
074ac8df 1180 case NL80211_IFTYPE_P2P_CLIENT:
ceca7b71 1181 if (!wdev->current_bss)
fffd0934
JB
1182 return -ENOLINK;
1183 break;
de4fcbad 1184 case NL80211_IFTYPE_UNSPECIFIED:
6e0bd6c3 1185 case NL80211_IFTYPE_OCB:
de4fcbad 1186 case NL80211_IFTYPE_MONITOR:
cb3b7d87 1187 case NL80211_IFTYPE_NAN:
de4fcbad
JB
1188 case NL80211_IFTYPE_P2P_DEVICE:
1189 case NL80211_IFTYPE_WDS:
1190 case NUM_NL80211_IFTYPES:
fffd0934
JB
1191 return -EINVAL;
1192 }
1193
1194 return 0;
1195}
1196
664834de
JM
1197static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
1198 struct nlattr *tb)
1199{
1200 struct ieee80211_channel *chan;
1201
1202 if (tb == NULL)
1203 return NULL;
1204 chan = ieee80211_get_channel(wiphy, nla_get_u32(tb));
1205 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1206 return NULL;
1207 return chan;
1208}
1209
7527a782
JB
1210static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1211{
ae0be8de 1212 struct nlattr *nl_modes = nla_nest_start_noflag(msg, attr);
7527a782
JB
1213 int i;
1214
1215 if (!nl_modes)
1216 goto nla_put_failure;
1217
1218 i = 0;
1219 while (ifmodes) {
9360ffd1
DM
1220 if ((ifmodes & 1) && nla_put_flag(msg, i))
1221 goto nla_put_failure;
7527a782
JB
1222 ifmodes >>= 1;
1223 i++;
1224 }
1225
1226 nla_nest_end(msg, nl_modes);
1227 return 0;
1228
1229nla_put_failure:
1230 return -ENOBUFS;
1231}
1232
1233static int nl80211_put_iface_combinations(struct wiphy *wiphy,
cdc89b97
JB
1234 struct sk_buff *msg,
1235 bool large)
7527a782
JB
1236{
1237 struct nlattr *nl_combis;
1238 int i, j;
1239
ae0be8de
MK
1240 nl_combis = nla_nest_start_noflag(msg,
1241 NL80211_ATTR_INTERFACE_COMBINATIONS);
7527a782
JB
1242 if (!nl_combis)
1243 goto nla_put_failure;
1244
1245 for (i = 0; i < wiphy->n_iface_combinations; i++) {
1246 const struct ieee80211_iface_combination *c;
1247 struct nlattr *nl_combi, *nl_limits;
1248
1249 c = &wiphy->iface_combinations[i];
1250
ae0be8de 1251 nl_combi = nla_nest_start_noflag(msg, i + 1);
7527a782
JB
1252 if (!nl_combi)
1253 goto nla_put_failure;
1254
ae0be8de
MK
1255 nl_limits = nla_nest_start_noflag(msg,
1256 NL80211_IFACE_COMB_LIMITS);
7527a782
JB
1257 if (!nl_limits)
1258 goto nla_put_failure;
1259
1260 for (j = 0; j < c->n_limits; j++) {
1261 struct nlattr *nl_limit;
1262
ae0be8de 1263 nl_limit = nla_nest_start_noflag(msg, j + 1);
7527a782
JB
1264 if (!nl_limit)
1265 goto nla_put_failure;
9360ffd1
DM
1266 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX,
1267 c->limits[j].max))
1268 goto nla_put_failure;
7527a782
JB
1269 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1270 c->limits[j].types))
1271 goto nla_put_failure;
1272 nla_nest_end(msg, nl_limit);
1273 }
1274
1275 nla_nest_end(msg, nl_limits);
1276
9360ffd1
DM
1277 if (c->beacon_int_infra_match &&
1278 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1279 goto nla_put_failure;
1280 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1281 c->num_different_channels) ||
1282 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1283 c->max_interfaces))
1284 goto nla_put_failure;
cdc89b97 1285 if (large &&
8c48b50a
FF
1286 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1287 c->radar_detect_widths) ||
1288 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1289 c->radar_detect_regions)))
cdc89b97 1290 goto nla_put_failure;
0c317a02
PK
1291 if (c->beacon_int_min_gcd &&
1292 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1293 c->beacon_int_min_gcd))
1294 goto nla_put_failure;
7527a782
JB
1295
1296 nla_nest_end(msg, nl_combi);
1297 }
1298
1299 nla_nest_end(msg, nl_combis);
1300
1301 return 0;
1302nla_put_failure:
1303 return -ENOBUFS;
1304}
1305
3713b4e3 1306#ifdef CONFIG_PM
b56cf720
JB
1307static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1308 struct sk_buff *msg)
1309{
964dc9e2 1310 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
b56cf720
JB
1311 struct nlattr *nl_tcp;
1312
1313 if (!tcp)
1314 return 0;
1315
ae0be8de
MK
1316 nl_tcp = nla_nest_start_noflag(msg,
1317 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
b56cf720
JB
1318 if (!nl_tcp)
1319 return -ENOBUFS;
1320
1321 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1322 tcp->data_payload_max))
1323 return -ENOBUFS;
1324
1325 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1326 tcp->data_payload_max))
1327 return -ENOBUFS;
1328
1329 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1330 return -ENOBUFS;
1331
1332 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1333 sizeof(*tcp->tok), tcp->tok))
1334 return -ENOBUFS;
1335
1336 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1337 tcp->data_interval_max))
1338 return -ENOBUFS;
1339
1340 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1341 tcp->wake_payload_max))
1342 return -ENOBUFS;
1343
1344 nla_nest_end(msg, nl_tcp);
1345 return 0;
1346}
1347
3713b4e3 1348static int nl80211_send_wowlan(struct sk_buff *msg,
1b8ec87a 1349 struct cfg80211_registered_device *rdev,
b56cf720 1350 bool large)
55682965 1351{
3713b4e3 1352 struct nlattr *nl_wowlan;
55682965 1353
1b8ec87a 1354 if (!rdev->wiphy.wowlan)
3713b4e3 1355 return 0;
55682965 1356
ae0be8de
MK
1357 nl_wowlan = nla_nest_start_noflag(msg,
1358 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
3713b4e3
JB
1359 if (!nl_wowlan)
1360 return -ENOBUFS;
9360ffd1 1361
1b8ec87a 1362 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
3713b4e3 1363 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1b8ec87a 1364 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
3713b4e3 1365 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1b8ec87a 1366 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
3713b4e3 1367 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1b8ec87a 1368 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
3713b4e3 1369 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1b8ec87a 1370 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
3713b4e3 1371 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1b8ec87a 1372 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
3713b4e3 1373 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1b8ec87a 1374 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
3713b4e3 1375 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1b8ec87a 1376 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
3713b4e3
JB
1377 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1378 return -ENOBUFS;
9360ffd1 1379
1b8ec87a 1380 if (rdev->wiphy.wowlan->n_patterns) {
50ac6607 1381 struct nl80211_pattern_support pat = {
1b8ec87a
ZG
1382 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1383 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1384 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1385 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
3713b4e3 1386 };
9360ffd1 1387
3713b4e3
JB
1388 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1389 sizeof(pat), &pat))
1390 return -ENOBUFS;
1391 }
9360ffd1 1392
75453ccb
LC
1393 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1394 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1395 rdev->wiphy.wowlan->max_nd_match_sets))
1396 return -ENOBUFS;
1397
1b8ec87a 1398 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
b56cf720
JB
1399 return -ENOBUFS;
1400
3713b4e3 1401 nla_nest_end(msg, nl_wowlan);
9360ffd1 1402
3713b4e3
JB
1403 return 0;
1404}
1405#endif
9360ffd1 1406
be29b99a 1407static int nl80211_send_coalesce(struct sk_buff *msg,
1b8ec87a 1408 struct cfg80211_registered_device *rdev)
be29b99a
AK
1409{
1410 struct nl80211_coalesce_rule_support rule;
1411
1b8ec87a 1412 if (!rdev->wiphy.coalesce)
be29b99a
AK
1413 return 0;
1414
1b8ec87a
ZG
1415 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1416 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1417 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1418 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1419 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1420 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
be29b99a
AK
1421
1422 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1423 return -ENOBUFS;
1424
1425 return 0;
1426}
1427
c4cbaf79
LC
1428static int
1429nl80211_send_iftype_data(struct sk_buff *msg,
1430 const struct ieee80211_sband_iftype_data *iftdata)
1431{
1432 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
1433
1434 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
1435 iftdata->types_mask))
1436 return -ENOBUFS;
1437
1438 if (he_cap->has_he) {
1439 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
1440 sizeof(he_cap->he_cap_elem.mac_cap_info),
1441 he_cap->he_cap_elem.mac_cap_info) ||
1442 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
1443 sizeof(he_cap->he_cap_elem.phy_cap_info),
1444 he_cap->he_cap_elem.phy_cap_info) ||
1445 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
1446 sizeof(he_cap->he_mcs_nss_supp),
1447 &he_cap->he_mcs_nss_supp) ||
1448 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
1449 sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
1450 return -ENOBUFS;
1451 }
1452
1453 return 0;
1454}
1455
3713b4e3
JB
1456static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1457 struct ieee80211_supported_band *sband)
1458{
1459 struct nlattr *nl_rates, *nl_rate;
1460 struct ieee80211_rate *rate;
1461 int i;
87bbbe22 1462
3713b4e3
JB
1463 /* add HT info */
1464 if (sband->ht_cap.ht_supported &&
1465 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1466 sizeof(sband->ht_cap.mcs),
1467 &sband->ht_cap.mcs) ||
1468 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1469 sband->ht_cap.cap) ||
1470 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1471 sband->ht_cap.ampdu_factor) ||
1472 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1473 sband->ht_cap.ampdu_density)))
1474 return -ENOBUFS;
afe0cbf8 1475
3713b4e3
JB
1476 /* add VHT info */
1477 if (sband->vht_cap.vht_supported &&
1478 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1479 sizeof(sband->vht_cap.vht_mcs),
1480 &sband->vht_cap.vht_mcs) ||
1481 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1482 sband->vht_cap.cap)))
1483 return -ENOBUFS;
f59ac048 1484
c4cbaf79
LC
1485 if (sband->n_iftype_data) {
1486 struct nlattr *nl_iftype_data =
ae0be8de
MK
1487 nla_nest_start_noflag(msg,
1488 NL80211_BAND_ATTR_IFTYPE_DATA);
c4cbaf79
LC
1489 int err;
1490
1491 if (!nl_iftype_data)
1492 return -ENOBUFS;
1493
1494 for (i = 0; i < sband->n_iftype_data; i++) {
1495 struct nlattr *iftdata;
1496
ae0be8de 1497 iftdata = nla_nest_start_noflag(msg, i + 1);
c4cbaf79
LC
1498 if (!iftdata)
1499 return -ENOBUFS;
1500
1501 err = nl80211_send_iftype_data(msg,
1502 &sband->iftype_data[i]);
1503 if (err)
1504 return err;
1505
1506 nla_nest_end(msg, iftdata);
1507 }
1508
1509 nla_nest_end(msg, nl_iftype_data);
1510 }
1511
3713b4e3 1512 /* add bitrates */
ae0be8de 1513 nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
3713b4e3
JB
1514 if (!nl_rates)
1515 return -ENOBUFS;
ee688b00 1516
3713b4e3 1517 for (i = 0; i < sband->n_bitrates; i++) {
ae0be8de 1518 nl_rate = nla_nest_start_noflag(msg, i);
3713b4e3
JB
1519 if (!nl_rate)
1520 return -ENOBUFS;
ee688b00 1521
3713b4e3
JB
1522 rate = &sband->bitrates[i];
1523 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1524 rate->bitrate))
1525 return -ENOBUFS;
1526 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1527 nla_put_flag(msg,
1528 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1529 return -ENOBUFS;
ee688b00 1530
3713b4e3
JB
1531 nla_nest_end(msg, nl_rate);
1532 }
d51626df 1533
3713b4e3 1534 nla_nest_end(msg, nl_rates);
bf0c111e 1535
3713b4e3
JB
1536 return 0;
1537}
ee688b00 1538
3713b4e3
JB
1539static int
1540nl80211_send_mgmt_stypes(struct sk_buff *msg,
1541 const struct ieee80211_txrx_stypes *mgmt_stypes)
1542{
1543 u16 stypes;
1544 struct nlattr *nl_ftypes, *nl_ifs;
1545 enum nl80211_iftype ift;
1546 int i;
ee688b00 1547
3713b4e3
JB
1548 if (!mgmt_stypes)
1549 return 0;
5dab3b8a 1550
ae0be8de 1551 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_TX_FRAME_TYPES);
3713b4e3
JB
1552 if (!nl_ifs)
1553 return -ENOBUFS;
e2f367f2 1554
3713b4e3 1555 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1556 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1557 if (!nl_ftypes)
1558 return -ENOBUFS;
1559 i = 0;
1560 stypes = mgmt_stypes[ift].tx;
1561 while (stypes) {
1562 if ((stypes & 1) &&
1563 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1564 (i << 4) | IEEE80211_FTYPE_MGMT))
1565 return -ENOBUFS;
1566 stypes >>= 1;
1567 i++;
ee688b00 1568 }
3713b4e3
JB
1569 nla_nest_end(msg, nl_ftypes);
1570 }
ee688b00 1571
3713b4e3 1572 nla_nest_end(msg, nl_ifs);
ee688b00 1573
ae0be8de 1574 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_RX_FRAME_TYPES);
3713b4e3
JB
1575 if (!nl_ifs)
1576 return -ENOBUFS;
ee688b00 1577
3713b4e3 1578 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
ae0be8de 1579 nl_ftypes = nla_nest_start_noflag(msg, ift);
3713b4e3
JB
1580 if (!nl_ftypes)
1581 return -ENOBUFS;
1582 i = 0;
1583 stypes = mgmt_stypes[ift].rx;
1584 while (stypes) {
1585 if ((stypes & 1) &&
1586 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
1587 (i << 4) | IEEE80211_FTYPE_MGMT))
1588 return -ENOBUFS;
1589 stypes >>= 1;
1590 i++;
1591 }
1592 nla_nest_end(msg, nl_ftypes);
1593 }
1594 nla_nest_end(msg, nl_ifs);
ee688b00 1595
3713b4e3
JB
1596 return 0;
1597}
ee688b00 1598
1794899e
JB
1599#define CMD(op, n) \
1600 do { \
1601 if (rdev->ops->op) { \
1602 i++; \
1603 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
1604 goto nla_put_failure; \
1605 } \
1606 } while (0)
1607
1608static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
1609 struct sk_buff *msg)
1610{
1611 int i = 0;
1612
1613 /*
1614 * do *NOT* add anything into this function, new things need to be
1615 * advertised only to new versions of userspace that can deal with
1616 * the split (and they can't possibly care about new features...
1617 */
1618 CMD(add_virtual_intf, NEW_INTERFACE);
1619 CMD(change_virtual_intf, SET_INTERFACE);
1620 CMD(add_key, NEW_KEY);
1621 CMD(start_ap, START_AP);
1622 CMD(add_station, NEW_STATION);
1623 CMD(add_mpath, NEW_MPATH);
1624 CMD(update_mesh_config, SET_MESH_CONFIG);
1625 CMD(change_bss, SET_BSS);
1626 CMD(auth, AUTHENTICATE);
1627 CMD(assoc, ASSOCIATE);
1628 CMD(deauth, DEAUTHENTICATE);
1629 CMD(disassoc, DISASSOCIATE);
1630 CMD(join_ibss, JOIN_IBSS);
1631 CMD(join_mesh, JOIN_MESH);
1632 CMD(set_pmksa, SET_PMKSA);
1633 CMD(del_pmksa, DEL_PMKSA);
1634 CMD(flush_pmksa, FLUSH_PMKSA);
1635 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
1636 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
1637 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
1638 CMD(mgmt_tx, FRAME);
1639 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
1640 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
1641 i++;
1642 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
1643 goto nla_put_failure;
1644 }
1645 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
1646 rdev->ops->join_mesh) {
1647 i++;
1648 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
1649 goto nla_put_failure;
1650 }
1651 CMD(set_wds_peer, SET_WDS_PEER);
1652 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
1653 CMD(tdls_mgmt, TDLS_MGMT);
1654 CMD(tdls_oper, TDLS_OPER);
1655 }
ca986ad9 1656 if (rdev->wiphy.max_sched_scan_reqs)
1794899e
JB
1657 CMD(sched_scan_start, START_SCHED_SCAN);
1658 CMD(probe_client, PROBE_CLIENT);
1659 CMD(set_noack_map, SET_NOACK_MAP);
1660 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
1661 i++;
1662 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
1663 goto nla_put_failure;
1664 }
1665 CMD(start_p2p_device, START_P2P_DEVICE);
1666 CMD(set_mcast_rate, SET_MCAST_RATE);
1667#ifdef CONFIG_NL80211_TESTMODE
1668 CMD(testmode_cmd, TESTMODE);
1669#endif
1670
1671 if (rdev->ops->connect || rdev->ops->auth) {
1672 i++;
1673 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
1674 goto nla_put_failure;
1675 }
1676
1677 if (rdev->ops->disconnect || rdev->ops->deauth) {
1678 i++;
1679 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
1680 goto nla_put_failure;
1681 }
1682
1683 return i;
1684 nla_put_failure:
1685 return -ENOBUFS;
1686}
1687
9bb7e0f2
JB
1688static int
1689nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
1690 struct sk_buff *msg)
1691{
1692 struct nlattr *ftm;
1693
1694 if (!cap->ftm.supported)
1695 return 0;
1696
ae0be8de 1697 ftm = nla_nest_start_noflag(msg, NL80211_PMSR_TYPE_FTM);
9bb7e0f2
JB
1698 if (!ftm)
1699 return -ENOBUFS;
1700
1701 if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
1702 return -ENOBUFS;
1703 if (cap->ftm.non_asap &&
1704 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
1705 return -ENOBUFS;
1706 if (cap->ftm.request_lci &&
1707 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
1708 return -ENOBUFS;
1709 if (cap->ftm.request_civicloc &&
1710 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
1711 return -ENOBUFS;
1712 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
1713 cap->ftm.preambles))
1714 return -ENOBUFS;
1715 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
1716 cap->ftm.bandwidths))
1717 return -ENOBUFS;
1718 if (cap->ftm.max_bursts_exponent >= 0 &&
1719 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
1720 cap->ftm.max_bursts_exponent))
1721 return -ENOBUFS;
1722 if (cap->ftm.max_ftms_per_burst &&
1723 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
1724 cap->ftm.max_ftms_per_burst))
1725 return -ENOBUFS;
1726
1727 nla_nest_end(msg, ftm);
1728 return 0;
1729}
1730
1731static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
1732 struct sk_buff *msg)
1733{
1734 const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
1735 struct nlattr *pmsr, *caps;
1736
1737 if (!cap)
1738 return 0;
1739
1740 /*
1741 * we don't need to clean up anything here since the caller
1742 * will genlmsg_cancel() if we fail
1743 */
1744
ae0be8de 1745 pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
9bb7e0f2
JB
1746 if (!pmsr)
1747 return -ENOBUFS;
1748
1749 if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
1750 return -ENOBUFS;
1751
1752 if (cap->report_ap_tsf &&
1753 nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
1754 return -ENOBUFS;
1755
1756 if (cap->randomize_mac_addr &&
1757 nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
1758 return -ENOBUFS;
1759
ae0be8de 1760 caps = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
9bb7e0f2
JB
1761 if (!caps)
1762 return -ENOBUFS;
1763
1764 if (nl80211_send_pmsr_ftm_capa(cap, msg))
1765 return -ENOBUFS;
1766
1767 nla_nest_end(msg, caps);
1768 nla_nest_end(msg, pmsr);
1769
1770 return 0;
1771}
1772
86e8cf98
JB
1773struct nl80211_dump_wiphy_state {
1774 s64 filter_wiphy;
1775 long start;
019ae3a9 1776 long split_start, band_start, chan_start, capa_start;
86e8cf98
JB
1777 bool split;
1778};
1779
1b8ec87a 1780static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
3bb20556 1781 enum nl80211_commands cmd,
3713b4e3 1782 struct sk_buff *msg, u32 portid, u32 seq,
86e8cf98 1783 int flags, struct nl80211_dump_wiphy_state *state)
3713b4e3
JB
1784{
1785 void *hdr;
1786 struct nlattr *nl_bands, *nl_band;
1787 struct nlattr *nl_freqs, *nl_freq;
1788 struct nlattr *nl_cmds;
57fbcce3 1789 enum nl80211_band band;
3713b4e3
JB
1790 struct ieee80211_channel *chan;
1791 int i;
1792 const struct ieee80211_txrx_stypes *mgmt_stypes =
1b8ec87a 1793 rdev->wiphy.mgmt_stypes;
fe1abafd 1794 u32 features;
ee688b00 1795
3bb20556 1796 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3713b4e3
JB
1797 if (!hdr)
1798 return -ENOBUFS;
ee688b00 1799
86e8cf98
JB
1800 if (WARN_ON(!state))
1801 return -EINVAL;
ee688b00 1802
1b8ec87a 1803 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3713b4e3 1804 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
1b8ec87a 1805 wiphy_name(&rdev->wiphy)) ||
3713b4e3
JB
1806 nla_put_u32(msg, NL80211_ATTR_GENERATION,
1807 cfg80211_rdev_list_generation))
8fdc621d
JB
1808 goto nla_put_failure;
1809
3bb20556
JB
1810 if (cmd != NL80211_CMD_NEW_WIPHY)
1811 goto finish;
1812
86e8cf98 1813 switch (state->split_start) {
3713b4e3
JB
1814 case 0:
1815 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
1b8ec87a 1816 rdev->wiphy.retry_short) ||
3713b4e3 1817 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
1b8ec87a 1818 rdev->wiphy.retry_long) ||
3713b4e3 1819 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
1b8ec87a 1820 rdev->wiphy.frag_threshold) ||
3713b4e3 1821 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
1b8ec87a 1822 rdev->wiphy.rts_threshold) ||
3713b4e3 1823 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
1b8ec87a 1824 rdev->wiphy.coverage_class) ||
3713b4e3 1825 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
1b8ec87a 1826 rdev->wiphy.max_scan_ssids) ||
3713b4e3 1827 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
1b8ec87a 1828 rdev->wiphy.max_sched_scan_ssids) ||
3713b4e3 1829 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
1b8ec87a 1830 rdev->wiphy.max_scan_ie_len) ||
3713b4e3 1831 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
1b8ec87a 1832 rdev->wiphy.max_sched_scan_ie_len) ||
3713b4e3 1833 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
3b06d277
AS
1834 rdev->wiphy.max_match_sets) ||
1835 nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
1836 rdev->wiphy.max_sched_scan_plans) ||
1837 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
1838 rdev->wiphy.max_sched_scan_plan_interval) ||
1839 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
1840 rdev->wiphy.max_sched_scan_plan_iterations))
9360ffd1 1841 goto nla_put_failure;
3713b4e3 1842
1b8ec87a 1843 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
3713b4e3 1844 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
aa430da4 1845 goto nla_put_failure;
1b8ec87a 1846 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
3713b4e3
JB
1847 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
1848 goto nla_put_failure;
1b8ec87a 1849 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
3713b4e3
JB
1850 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
1851 goto nla_put_failure;
1b8ec87a 1852 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
3713b4e3
JB
1853 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
1854 goto nla_put_failure;
1b8ec87a 1855 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
3713b4e3
JB
1856 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
1857 goto nla_put_failure;
1b8ec87a 1858 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
3713b4e3 1859 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
9360ffd1 1860 goto nla_put_failure;
86e8cf98
JB
1861 state->split_start++;
1862 if (state->split)
3713b4e3 1863 break;
925b5978 1864 /* fall through */
3713b4e3
JB
1865 case 1:
1866 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
1b8ec87a
ZG
1867 sizeof(u32) * rdev->wiphy.n_cipher_suites,
1868 rdev->wiphy.cipher_suites))
3713b4e3 1869 goto nla_put_failure;
4745fc09 1870
3713b4e3 1871 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
1b8ec87a 1872 rdev->wiphy.max_num_pmkids))
3713b4e3 1873 goto nla_put_failure;
b23aa676 1874
1b8ec87a 1875 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
3713b4e3 1876 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
9360ffd1 1877 goto nla_put_failure;
b23aa676 1878
3713b4e3 1879 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
1b8ec87a 1880 rdev->wiphy.available_antennas_tx) ||
3713b4e3 1881 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
1b8ec87a 1882 rdev->wiphy.available_antennas_rx))
9360ffd1 1883 goto nla_put_failure;
b23aa676 1884
1b8ec87a 1885 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
3713b4e3 1886 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
1b8ec87a 1887 rdev->wiphy.probe_resp_offload))
3713b4e3 1888 goto nla_put_failure;
8fdc621d 1889
1b8ec87a
ZG
1890 if ((rdev->wiphy.available_antennas_tx ||
1891 rdev->wiphy.available_antennas_rx) &&
1892 rdev->ops->get_antenna) {
3713b4e3
JB
1893 u32 tx_ant = 0, rx_ant = 0;
1894 int res;
7a087e74 1895
1b8ec87a 1896 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
3713b4e3
JB
1897 if (!res) {
1898 if (nla_put_u32(msg,
1899 NL80211_ATTR_WIPHY_ANTENNA_TX,
1900 tx_ant) ||
1901 nla_put_u32(msg,
1902 NL80211_ATTR_WIPHY_ANTENNA_RX,
1903 rx_ant))
1904 goto nla_put_failure;
1905 }
1906 }
a293911d 1907
86e8cf98
JB
1908 state->split_start++;
1909 if (state->split)
3713b4e3 1910 break;
925b5978 1911 /* fall through */
3713b4e3
JB
1912 case 2:
1913 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
1b8ec87a 1914 rdev->wiphy.interface_modes))
3713b4e3 1915 goto nla_put_failure;
86e8cf98
JB
1916 state->split_start++;
1917 if (state->split)
3713b4e3 1918 break;
925b5978 1919 /* fall through */
3713b4e3 1920 case 3:
ae0be8de
MK
1921 nl_bands = nla_nest_start_noflag(msg,
1922 NL80211_ATTR_WIPHY_BANDS);
3713b4e3
JB
1923 if (!nl_bands)
1924 goto nla_put_failure;
f7ca38df 1925
86e8cf98 1926 for (band = state->band_start;
57fbcce3 1927 band < NUM_NL80211_BANDS; band++) {
3713b4e3 1928 struct ieee80211_supported_band *sband;
2e161f78 1929
1b8ec87a 1930 sband = rdev->wiphy.bands[band];
2e161f78 1931
3713b4e3
JB
1932 if (!sband)
1933 continue;
1934
ae0be8de 1935 nl_band = nla_nest_start_noflag(msg, band);
3713b4e3 1936 if (!nl_band)
2e161f78 1937 goto nla_put_failure;
3713b4e3 1938
86e8cf98 1939 switch (state->chan_start) {
3713b4e3
JB
1940 case 0:
1941 if (nl80211_send_band_rateinfo(msg, sband))
9360ffd1 1942 goto nla_put_failure;
86e8cf98
JB
1943 state->chan_start++;
1944 if (state->split)
3713b4e3 1945 break;
925b5978 1946 /* fall through */
3713b4e3
JB
1947 default:
1948 /* add frequencies */
ae0be8de
MK
1949 nl_freqs = nla_nest_start_noflag(msg,
1950 NL80211_BAND_ATTR_FREQS);
3713b4e3
JB
1951 if (!nl_freqs)
1952 goto nla_put_failure;
1953
86e8cf98 1954 for (i = state->chan_start - 1;
3713b4e3
JB
1955 i < sband->n_channels;
1956 i++) {
ae0be8de
MK
1957 nl_freq = nla_nest_start_noflag(msg,
1958 i);
3713b4e3
JB
1959 if (!nl_freq)
1960 goto nla_put_failure;
1961
1962 chan = &sband->channels[i];
1963
86e8cf98 1964 if (nl80211_msg_put_channel(
50f32718 1965 msg, &rdev->wiphy, chan,
86e8cf98 1966 state->split))
3713b4e3
JB
1967 goto nla_put_failure;
1968
1969 nla_nest_end(msg, nl_freq);
86e8cf98 1970 if (state->split)
3713b4e3
JB
1971 break;
1972 }
1973 if (i < sband->n_channels)
86e8cf98 1974 state->chan_start = i + 2;
3713b4e3 1975 else
86e8cf98 1976 state->chan_start = 0;
3713b4e3
JB
1977 nla_nest_end(msg, nl_freqs);
1978 }
1979
1980 nla_nest_end(msg, nl_band);
1981
86e8cf98 1982 if (state->split) {
3713b4e3 1983 /* start again here */
86e8cf98 1984 if (state->chan_start)
3713b4e3
JB
1985 band--;
1986 break;
2e161f78 1987 }
2e161f78 1988 }
3713b4e3 1989 nla_nest_end(msg, nl_bands);
2e161f78 1990
57fbcce3 1991 if (band < NUM_NL80211_BANDS)
86e8cf98 1992 state->band_start = band + 1;
3713b4e3 1993 else
86e8cf98 1994 state->band_start = 0;
74b70a4e 1995
3713b4e3 1996 /* if bands & channels are done, continue outside */
86e8cf98
JB
1997 if (state->band_start == 0 && state->chan_start == 0)
1998 state->split_start++;
1999 if (state->split)
3713b4e3 2000 break;
925b5978 2001 /* fall through */
3713b4e3 2002 case 4:
ae0be8de
MK
2003 nl_cmds = nla_nest_start_noflag(msg,
2004 NL80211_ATTR_SUPPORTED_COMMANDS);
3713b4e3 2005 if (!nl_cmds)
2e161f78
JB
2006 goto nla_put_failure;
2007
1794899e
JB
2008 i = nl80211_add_commands_unsplit(rdev, msg);
2009 if (i < 0)
2010 goto nla_put_failure;
86e8cf98 2011 if (state->split) {
5de17984
AS
2012 CMD(crit_proto_start, CRIT_PROTOCOL_START);
2013 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
1b8ec87a 2014 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
16ef1fe2 2015 CMD(channel_switch, CHANNEL_SWITCH);
02df00eb 2016 CMD(set_qos_map, SET_QOS_MAP);
723e73ac
JB
2017 if (rdev->wiphy.features &
2018 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
960d01ac 2019 CMD(add_tx_ts, ADD_TX_TS);
ce0ce13a 2020 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
088e8df8 2021 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
5de17984 2022 }
3713b4e3 2023#undef CMD
ff1b6e69 2024
3713b4e3 2025 nla_nest_end(msg, nl_cmds);
86e8cf98
JB
2026 state->split_start++;
2027 if (state->split)
3713b4e3 2028 break;
925b5978 2029 /* fall through */
3713b4e3 2030 case 5:
1b8ec87a
ZG
2031 if (rdev->ops->remain_on_channel &&
2032 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
3713b4e3
JB
2033 nla_put_u32(msg,
2034 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
1b8ec87a 2035 rdev->wiphy.max_remain_on_channel_duration))
3713b4e3
JB
2036 goto nla_put_failure;
2037
1b8ec87a 2038 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
3713b4e3
JB
2039 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
2040 goto nla_put_failure;
2041
2042 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
2043 goto nla_put_failure;
86e8cf98
JB
2044 state->split_start++;
2045 if (state->split)
3713b4e3 2046 break;
925b5978 2047 /* fall through */
3713b4e3
JB
2048 case 6:
2049#ifdef CONFIG_PM
1b8ec87a 2050 if (nl80211_send_wowlan(msg, rdev, state->split))
3713b4e3 2051 goto nla_put_failure;
86e8cf98
JB
2052 state->split_start++;
2053 if (state->split)
3713b4e3
JB
2054 break;
2055#else
86e8cf98 2056 state->split_start++;
dfb89c56 2057#endif
925b5978 2058 /* fall through */
3713b4e3
JB
2059 case 7:
2060 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
1b8ec87a 2061 rdev->wiphy.software_iftypes))
3713b4e3 2062 goto nla_put_failure;
ff1b6e69 2063
1b8ec87a 2064 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
86e8cf98 2065 state->split))
3713b4e3 2066 goto nla_put_failure;
7527a782 2067
86e8cf98
JB
2068 state->split_start++;
2069 if (state->split)
3713b4e3 2070 break;
925b5978 2071 /* fall through */
3713b4e3 2072 case 8:
1b8ec87a 2073 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
3713b4e3 2074 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
1b8ec87a 2075 rdev->wiphy.ap_sme_capa))
3713b4e3 2076 goto nla_put_failure;
7527a782 2077
1b8ec87a 2078 features = rdev->wiphy.features;
fe1abafd
JB
2079 /*
2080 * We can only add the per-channel limit information if the
2081 * dump is split, otherwise it makes it too big. Therefore
2082 * only advertise it in that case.
2083 */
86e8cf98 2084 if (state->split)
fe1abafd
JB
2085 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
2086 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
3713b4e3 2087 goto nla_put_failure;
562a7480 2088
1b8ec87a 2089 if (rdev->wiphy.ht_capa_mod_mask &&
3713b4e3 2090 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
1b8ec87a
ZG
2091 sizeof(*rdev->wiphy.ht_capa_mod_mask),
2092 rdev->wiphy.ht_capa_mod_mask))
3713b4e3 2093 goto nla_put_failure;
1f074bd8 2094
1b8ec87a
ZG
2095 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
2096 rdev->wiphy.max_acl_mac_addrs &&
3713b4e3 2097 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
1b8ec87a 2098 rdev->wiphy.max_acl_mac_addrs))
3713b4e3 2099 goto nla_put_failure;
7e7c8926 2100
3713b4e3
JB
2101 /*
2102 * Any information below this point is only available to
2103 * applications that can deal with it being split. This
2104 * helps ensure that newly added capabilities don't break
2105 * older tools by overrunning their buffers.
2106 *
2107 * We still increment split_start so that in the split
2108 * case we'll continue with more data in the next round,
2109 * but break unconditionally so unsplit data stops here.
2110 */
86e8cf98 2111 state->split_start++;
3713b4e3
JB
2112 break;
2113 case 9:
1b8ec87a 2114 if (rdev->wiphy.extended_capabilities &&
fe1abafd 2115 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
1b8ec87a
ZG
2116 rdev->wiphy.extended_capabilities_len,
2117 rdev->wiphy.extended_capabilities) ||
fe1abafd 2118 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
1b8ec87a
ZG
2119 rdev->wiphy.extended_capabilities_len,
2120 rdev->wiphy.extended_capabilities_mask)))
fe1abafd 2121 goto nla_put_failure;
a50df0c4 2122
1b8ec87a 2123 if (rdev->wiphy.vht_capa_mod_mask &&
ee2aca34 2124 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
1b8ec87a
ZG
2125 sizeof(*rdev->wiphy.vht_capa_mod_mask),
2126 rdev->wiphy.vht_capa_mod_mask))
ee2aca34
JB
2127 goto nla_put_failure;
2128
be29b99a
AK
2129 state->split_start++;
2130 break;
2131 case 10:
1b8ec87a 2132 if (nl80211_send_coalesce(msg, rdev))
be29b99a
AK
2133 goto nla_put_failure;
2134
1b8ec87a 2135 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
01e0daa4
FF
2136 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
2137 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
2138 goto nla_put_failure;
b43504cf 2139
1b8ec87a 2140 if (rdev->wiphy.max_ap_assoc_sta &&
b43504cf 2141 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
1b8ec87a 2142 rdev->wiphy.max_ap_assoc_sta))
b43504cf
JM
2143 goto nla_put_failure;
2144
ad7e718c
JB
2145 state->split_start++;
2146 break;
2147 case 11:
1b8ec87a 2148 if (rdev->wiphy.n_vendor_commands) {
567ffc35
JB
2149 const struct nl80211_vendor_cmd_info *info;
2150 struct nlattr *nested;
2151
ae0be8de
MK
2152 nested = nla_nest_start_noflag(msg,
2153 NL80211_ATTR_VENDOR_DATA);
567ffc35
JB
2154 if (!nested)
2155 goto nla_put_failure;
2156
1b8ec87a
ZG
2157 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
2158 info = &rdev->wiphy.vendor_commands[i].info;
567ffc35
JB
2159 if (nla_put(msg, i + 1, sizeof(*info), info))
2160 goto nla_put_failure;
2161 }
2162 nla_nest_end(msg, nested);
2163 }
2164
1b8ec87a 2165 if (rdev->wiphy.n_vendor_events) {
567ffc35
JB
2166 const struct nl80211_vendor_cmd_info *info;
2167 struct nlattr *nested;
ad7e718c 2168
ae0be8de
MK
2169 nested = nla_nest_start_noflag(msg,
2170 NL80211_ATTR_VENDOR_EVENTS);
567ffc35 2171 if (!nested)
ad7e718c 2172 goto nla_put_failure;
567ffc35 2173
1b8ec87a
ZG
2174 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
2175 info = &rdev->wiphy.vendor_events[i];
567ffc35
JB
2176 if (nla_put(msg, i + 1, sizeof(*info), info))
2177 goto nla_put_failure;
2178 }
2179 nla_nest_end(msg, nested);
2180 }
9a774c78
AO
2181 state->split_start++;
2182 break;
2183 case 12:
2184 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
2185 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
2186 rdev->wiphy.max_num_csa_counters))
2187 goto nla_put_failure;
01e0daa4 2188
1bdd716c
AN
2189 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2190 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
2191 goto nla_put_failure;
2192
ca986ad9
AVS
2193 if (rdev->wiphy.max_sched_scan_reqs &&
2194 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
2195 rdev->wiphy.max_sched_scan_reqs))
2196 goto nla_put_failure;
2197
d75bb06b
GKS
2198 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
2199 sizeof(rdev->wiphy.ext_features),
2200 rdev->wiphy.ext_features))
2201 goto nla_put_failure;
2202
38de03d2
AS
2203 if (rdev->wiphy.bss_select_support) {
2204 struct nlattr *nested;
2205 u32 bss_select_support = rdev->wiphy.bss_select_support;
2206
ae0be8de
MK
2207 nested = nla_nest_start_noflag(msg,
2208 NL80211_ATTR_BSS_SELECT);
38de03d2
AS
2209 if (!nested)
2210 goto nla_put_failure;
2211
2212 i = 0;
2213 while (bss_select_support) {
2214 if ((bss_select_support & 1) &&
2215 nla_put_flag(msg, i))
2216 goto nla_put_failure;
2217 i++;
2218 bss_select_support >>= 1;
2219 }
2220 nla_nest_end(msg, nested);
2221 }
2222
019ae3a9
KV
2223 state->split_start++;
2224 break;
2225 case 13:
2226 if (rdev->wiphy.num_iftype_ext_capab &&
2227 rdev->wiphy.iftype_ext_capab) {
2228 struct nlattr *nested_ext_capab, *nested;
2229
ae0be8de
MK
2230 nested = nla_nest_start_noflag(msg,
2231 NL80211_ATTR_IFTYPE_EXT_CAPA);
019ae3a9
KV
2232 if (!nested)
2233 goto nla_put_failure;
2234
2235 for (i = state->capa_start;
2236 i < rdev->wiphy.num_iftype_ext_capab; i++) {
2237 const struct wiphy_iftype_ext_capab *capab;
2238
2239 capab = &rdev->wiphy.iftype_ext_capab[i];
2240
ae0be8de
MK
2241 nested_ext_capab = nla_nest_start_noflag(msg,
2242 i);
019ae3a9
KV
2243 if (!nested_ext_capab ||
2244 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
2245 capab->iftype) ||
2246 nla_put(msg, NL80211_ATTR_EXT_CAPA,
2247 capab->extended_capabilities_len,
2248 capab->extended_capabilities) ||
2249 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
2250 capab->extended_capabilities_len,
2251 capab->extended_capabilities_mask))
2252 goto nla_put_failure;
2253
2254 nla_nest_end(msg, nested_ext_capab);
2255 if (state->split)
2256 break;
2257 }
2258 nla_nest_end(msg, nested);
2259 if (i < rdev->wiphy.num_iftype_ext_capab) {
2260 state->capa_start = i + 1;
2261 break;
2262 }
2263 }
2264
8585989d
LC
2265 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
2266 rdev->wiphy.nan_supported_bands))
2267 goto nla_put_failure;
2268
52539ca8
THJ
2269 if (wiphy_ext_feature_isset(&rdev->wiphy,
2270 NL80211_EXT_FEATURE_TXQS)) {
2271 struct cfg80211_txq_stats txqstats = {};
2272 int res;
2273
2274 res = rdev_get_txq_stats(rdev, NULL, &txqstats);
2275 if (!res &&
2276 !nl80211_put_txq_stats(msg, &txqstats,
2277 NL80211_ATTR_TXQ_STATS))
2278 goto nla_put_failure;
2279
2280 if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
2281 rdev->wiphy.txq_limit))
2282 goto nla_put_failure;
2283 if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
2284 rdev->wiphy.txq_memory_limit))
2285 goto nla_put_failure;
2286 if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
2287 rdev->wiphy.txq_quantum))
2288 goto nla_put_failure;
2289 }
2290
9bb7e0f2
JB
2291 state->split_start++;
2292 break;
2293 case 14:
2294 if (nl80211_send_pmsr_capa(rdev, msg))
2295 goto nla_put_failure;
2296
ab4dfa20
VJ
2297 state->split_start++;
2298 break;
2299 case 15:
2300 if (rdev->wiphy.akm_suites &&
2301 nla_put(msg, NL80211_ATTR_AKM_SUITES,
2302 sizeof(u32) * rdev->wiphy.n_akm_suites,
2303 rdev->wiphy.akm_suites))
2304 goto nla_put_failure;
2305
3713b4e3 2306 /* done */
86e8cf98 2307 state->split_start = 0;
3713b4e3
JB
2308 break;
2309 }
3bb20556 2310 finish:
053c095a
JB
2311 genlmsg_end(msg, hdr);
2312 return 0;
55682965
JB
2313
2314 nla_put_failure:
bc3ed28c
TG
2315 genlmsg_cancel(msg, hdr);
2316 return -EMSGSIZE;
55682965
JB
2317}
2318
86e8cf98
JB
2319static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
2320 struct netlink_callback *cb,
2321 struct nl80211_dump_wiphy_state *state)
2322{
c90c39da 2323 struct nlattr **tb = genl_family_attrbuf(&nl80211_fam);
8cb08174
JB
2324 int ret = nlmsg_parse_deprecated(cb->nlh,
2325 GENL_HDRLEN + nl80211_fam.hdrsize,
2326 tb, nl80211_fam.maxattr,
2327 nl80211_policy, NULL);
86e8cf98
JB
2328 /* ignore parse errors for backward compatibility */
2329 if (ret)
2330 return 0;
2331
2332 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
2333 if (tb[NL80211_ATTR_WIPHY])
2334 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
2335 if (tb[NL80211_ATTR_WDEV])
2336 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
2337 if (tb[NL80211_ATTR_IFINDEX]) {
2338 struct net_device *netdev;
2339 struct cfg80211_registered_device *rdev;
2340 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
2341
7f2b8562 2342 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
86e8cf98
JB
2343 if (!netdev)
2344 return -ENODEV;
2345 if (netdev->ieee80211_ptr) {
f26cbf40 2346 rdev = wiphy_to_rdev(
86e8cf98
JB
2347 netdev->ieee80211_ptr->wiphy);
2348 state->filter_wiphy = rdev->wiphy_idx;
2349 }
86e8cf98
JB
2350 }
2351
2352 return 0;
2353}
2354
55682965
JB
2355static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
2356{
645e77de 2357 int idx = 0, ret;
86e8cf98 2358 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
1b8ec87a 2359 struct cfg80211_registered_device *rdev;
3a5a423b 2360
5fe231e8 2361 rtnl_lock();
86e8cf98
JB
2362 if (!state) {
2363 state = kzalloc(sizeof(*state), GFP_KERNEL);
57ed5cd6
JL
2364 if (!state) {
2365 rtnl_unlock();
86e8cf98 2366 return -ENOMEM;
3713b4e3 2367 }
86e8cf98
JB
2368 state->filter_wiphy = -1;
2369 ret = nl80211_dump_wiphy_parse(skb, cb, state);
2370 if (ret) {
2371 kfree(state);
2372 rtnl_unlock();
2373 return ret;
3713b4e3 2374 }
86e8cf98 2375 cb->args[0] = (long)state;
3713b4e3
JB
2376 }
2377
1b8ec87a
ZG
2378 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2379 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 2380 continue;
86e8cf98 2381 if (++idx <= state->start)
55682965 2382 continue;
86e8cf98 2383 if (state->filter_wiphy != -1 &&
1b8ec87a 2384 state->filter_wiphy != rdev->wiphy_idx)
3713b4e3
JB
2385 continue;
2386 /* attempt to fit multiple wiphy data chunks into the skb */
2387 do {
3bb20556
JB
2388 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
2389 skb,
3713b4e3
JB
2390 NETLINK_CB(cb->skb).portid,
2391 cb->nlh->nlmsg_seq,
86e8cf98 2392 NLM_F_MULTI, state);
3713b4e3
JB
2393 if (ret < 0) {
2394 /*
2395 * If sending the wiphy data didn't fit (ENOBUFS
2396 * or EMSGSIZE returned), this SKB is still
2397 * empty (so it's not too big because another
2398 * wiphy dataset is already in the skb) and
2399 * we've not tried to adjust the dump allocation
2400 * yet ... then adjust the alloc size to be
2401 * bigger, and return 1 but with the empty skb.
2402 * This results in an empty message being RX'ed
2403 * in userspace, but that is ignored.
2404 *
2405 * We can then retry with the larger buffer.
2406 */
2407 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
f12cb289 2408 !skb->len && !state->split &&
3713b4e3
JB
2409 cb->min_dump_alloc < 4096) {
2410 cb->min_dump_alloc = 4096;
f12cb289 2411 state->split_start = 0;
d98cae64 2412 rtnl_unlock();
3713b4e3
JB
2413 return 1;
2414 }
2415 idx--;
2416 break;
645e77de 2417 }
86e8cf98 2418 } while (state->split_start > 0);
3713b4e3 2419 break;
55682965 2420 }
5fe231e8 2421 rtnl_unlock();
55682965 2422
86e8cf98 2423 state->start = idx;
55682965
JB
2424
2425 return skb->len;
2426}
2427
86e8cf98
JB
2428static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
2429{
2430 kfree((void *)cb->args[0]);
2431 return 0;
2432}
2433
55682965
JB
2434static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
2435{
2436 struct sk_buff *msg;
1b8ec87a 2437 struct cfg80211_registered_device *rdev = info->user_ptr[0];
86e8cf98 2438 struct nl80211_dump_wiphy_state state = {};
55682965 2439
645e77de 2440 msg = nlmsg_new(4096, GFP_KERNEL);
55682965 2441 if (!msg)
4c476991 2442 return -ENOMEM;
55682965 2443
3bb20556
JB
2444 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
2445 info->snd_portid, info->snd_seq, 0,
86e8cf98 2446 &state) < 0) {
4c476991
JB
2447 nlmsg_free(msg);
2448 return -ENOBUFS;
2449 }
55682965 2450
134e6375 2451 return genlmsg_reply(msg, info);
55682965
JB
2452}
2453
31888487
JM
2454static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
2455 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
2456 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
2457 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
2458 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
2459 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
2460};
2461
2462static int parse_txq_params(struct nlattr *tb[],
2463 struct ieee80211_txq_params *txq_params)
2464{
259d8c1e
DW
2465 u8 ac;
2466
a3304b0a 2467 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
31888487
JM
2468 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
2469 !tb[NL80211_TXQ_ATTR_AIFS])
2470 return -EINVAL;
2471
259d8c1e 2472 ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
31888487
JM
2473 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
2474 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
2475 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
2476 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
2477
259d8c1e 2478 if (ac >= NL80211_NUM_ACS)
a3304b0a 2479 return -EINVAL;
259d8c1e 2480 txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
31888487
JM
2481 return 0;
2482}
2483
f444de05
JB
2484static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
2485{
2486 /*
cc1d2806
JB
2487 * You can only set the channel explicitly for WDS interfaces,
2488 * all others have their channel managed via their respective
2489 * "establish a connection" command (connect, join, ...)
2490 *
2491 * For AP/GO and mesh mode, the channel can be set with the
2492 * channel userspace API, but is only stored and passed to the
2493 * low-level driver when the AP starts or the mesh is joined.
2494 * This is for backward compatibility, userspace can also give
2495 * the channel in the start-ap or join-mesh commands instead.
f444de05
JB
2496 *
2497 * Monitors are special as they are normally slaved to
e8c9bd5b
JB
2498 * whatever else is going on, so they have their own special
2499 * operation to set the monitor channel if possible.
f444de05
JB
2500 */
2501 return !wdev ||
2502 wdev->iftype == NL80211_IFTYPE_AP ||
f444de05 2503 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
074ac8df
JB
2504 wdev->iftype == NL80211_IFTYPE_MONITOR ||
2505 wdev->iftype == NL80211_IFTYPE_P2P_GO;
f444de05
JB
2506}
2507
9bb7e0f2
JB
2508int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
2509 struct genl_info *info,
2510 struct cfg80211_chan_def *chandef)
683b6d3b 2511{
49f9cf0e
JB
2512 struct netlink_ext_ack *extack = info->extack;
2513 struct nlattr **attrs = info->attrs;
dbeca2ea 2514 u32 control_freq;
683b6d3b 2515
49f9cf0e 2516 if (!attrs[NL80211_ATTR_WIPHY_FREQ])
683b6d3b
JB
2517 return -EINVAL;
2518
49f9cf0e 2519 control_freq = nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]);
683b6d3b
JB
2520
2521 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
3d9d1d66
JB
2522 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
2523 chandef->center_freq1 = control_freq;
2524 chandef->center_freq2 = 0;
683b6d3b
JB
2525
2526 /* Primary channel not allowed */
49f9cf0e
JB
2527 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) {
2528 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
2529 "Channel is disabled");
683b6d3b 2530 return -EINVAL;
49f9cf0e 2531 }
683b6d3b 2532
49f9cf0e 2533 if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
3d9d1d66
JB
2534 enum nl80211_channel_type chantype;
2535
49f9cf0e 2536 chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
3d9d1d66
JB
2537
2538 switch (chantype) {
2539 case NL80211_CHAN_NO_HT:
2540 case NL80211_CHAN_HT20:
2541 case NL80211_CHAN_HT40PLUS:
2542 case NL80211_CHAN_HT40MINUS:
2543 cfg80211_chandef_create(chandef, chandef->chan,
2544 chantype);
ffa4629e 2545 /* user input for center_freq is incorrect */
49f9cf0e
JB
2546 if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
2547 chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
2548 NL_SET_ERR_MSG_ATTR(extack,
2549 attrs[NL80211_ATTR_CENTER_FREQ1],
2550 "bad center frequency 1");
ffa4629e 2551 return -EINVAL;
49f9cf0e 2552 }
ffa4629e 2553 /* center_freq2 must be zero */
49f9cf0e
JB
2554 if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
2555 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
2556 NL_SET_ERR_MSG_ATTR(extack,
2557 attrs[NL80211_ATTR_CENTER_FREQ2],
2558 "center frequency 2 can't be used");
ffa4629e 2559 return -EINVAL;
49f9cf0e 2560 }
3d9d1d66
JB
2561 break;
2562 default:
49f9cf0e
JB
2563 NL_SET_ERR_MSG_ATTR(extack,
2564 attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
2565 "invalid channel type");
3d9d1d66
JB
2566 return -EINVAL;
2567 }
49f9cf0e 2568 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
3d9d1d66 2569 chandef->width =
49f9cf0e
JB
2570 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
2571 if (attrs[NL80211_ATTR_CENTER_FREQ1])
3d9d1d66 2572 chandef->center_freq1 =
49f9cf0e
JB
2573 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
2574 if (attrs[NL80211_ATTR_CENTER_FREQ2])
3d9d1d66 2575 chandef->center_freq2 =
49f9cf0e 2576 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
3d9d1d66
JB
2577 }
2578
49f9cf0e
JB
2579 if (!cfg80211_chandef_valid(chandef)) {
2580 NL_SET_ERR_MSG(extack, "invalid channel definition");
3d9d1d66 2581 return -EINVAL;
49f9cf0e 2582 }
3d9d1d66 2583
9f5e8f6e 2584 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
49f9cf0e
JB
2585 IEEE80211_CHAN_DISABLED)) {
2586 NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
3d9d1d66 2587 return -EINVAL;
49f9cf0e 2588 }
3d9d1d66 2589
2f301ab2
SW
2590 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
2591 chandef->width == NL80211_CHAN_WIDTH_10) &&
49f9cf0e
JB
2592 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
2593 NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
2f301ab2 2594 return -EINVAL;
49f9cf0e 2595 }
2f301ab2 2596
683b6d3b
JB
2597 return 0;
2598}
2599
f444de05 2600static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
e16821bc 2601 struct net_device *dev,
f444de05
JB
2602 struct genl_info *info)
2603{
683b6d3b 2604 struct cfg80211_chan_def chandef;
f444de05 2605 int result;
e8c9bd5b 2606 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
e16821bc 2607 struct wireless_dev *wdev = NULL;
e8c9bd5b 2608
e16821bc
JM
2609 if (dev)
2610 wdev = dev->ieee80211_ptr;
f444de05
JB
2611 if (!nl80211_can_set_dev_channel(wdev))
2612 return -EOPNOTSUPP;
e16821bc
JM
2613 if (wdev)
2614 iftype = wdev->iftype;
f444de05 2615
683b6d3b
JB
2616 result = nl80211_parse_chandef(rdev, info, &chandef);
2617 if (result)
2618 return result;
f444de05 2619
e8c9bd5b 2620 switch (iftype) {
aa430da4
JB
2621 case NL80211_IFTYPE_AP:
2622 case NL80211_IFTYPE_P2P_GO:
923b352f
AN
2623 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
2624 iftype)) {
aa430da4
JB
2625 result = -EINVAL;
2626 break;
2627 }
e16821bc
JM
2628 if (wdev->beacon_interval) {
2629 if (!dev || !rdev->ops->set_ap_chanwidth ||
2630 !(rdev->wiphy.features &
2631 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE)) {
2632 result = -EBUSY;
2633 break;
2634 }
2635
2636 /* Only allow dynamic channel width changes */
2637 if (chandef.chan != wdev->preset_chandef.chan) {
2638 result = -EBUSY;
2639 break;
2640 }
2641 result = rdev_set_ap_chanwidth(rdev, dev, &chandef);
2642 if (result)
2643 break;
2644 }
683b6d3b 2645 wdev->preset_chandef = chandef;
aa430da4
JB
2646 result = 0;
2647 break;
cc1d2806 2648 case NL80211_IFTYPE_MESH_POINT:
683b6d3b 2649 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
cc1d2806 2650 break;
e8c9bd5b 2651 case NL80211_IFTYPE_MONITOR:
683b6d3b 2652 result = cfg80211_set_monitor_channel(rdev, &chandef);
e8c9bd5b 2653 break;
aa430da4 2654 default:
e8c9bd5b 2655 result = -EINVAL;
f444de05 2656 }
f444de05
JB
2657
2658 return result;
2659}
2660
2661static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
2662{
4c476991
JB
2663 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2664 struct net_device *netdev = info->user_ptr[1];
f444de05 2665
e16821bc 2666 return __nl80211_set_channel(rdev, netdev, info);
f444de05
JB
2667}
2668
e8347eba
BJ
2669static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info)
2670{
43b19952
JB
2671 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2672 struct net_device *dev = info->user_ptr[1];
2673 struct wireless_dev *wdev = dev->ieee80211_ptr;
388ac775 2674 const u8 *bssid;
e8347eba
BJ
2675
2676 if (!info->attrs[NL80211_ATTR_MAC])
2677 return -EINVAL;
2678
43b19952
JB
2679 if (netif_running(dev))
2680 return -EBUSY;
e8347eba 2681
43b19952
JB
2682 if (!rdev->ops->set_wds_peer)
2683 return -EOPNOTSUPP;
e8347eba 2684
43b19952
JB
2685 if (wdev->iftype != NL80211_IFTYPE_WDS)
2686 return -EOPNOTSUPP;
e8347eba
BJ
2687
2688 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
e35e4d28 2689 return rdev_set_wds_peer(rdev, dev, bssid);
e8347eba
BJ
2690}
2691
55682965
JB
2692static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2693{
2694 struct cfg80211_registered_device *rdev;
f444de05
JB
2695 struct net_device *netdev = NULL;
2696 struct wireless_dev *wdev;
a1e567c8 2697 int result = 0, rem_txq_params = 0;
31888487 2698 struct nlattr *nl_txq_params;
b9a5f8ca
JM
2699 u32 changed;
2700 u8 retry_short = 0, retry_long = 0;
2701 u32 frag_threshold = 0, rts_threshold = 0;
81077e82 2702 u8 coverage_class = 0;
52539ca8 2703 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
55682965 2704
5fe231e8
JB
2705 ASSERT_RTNL();
2706
f444de05
JB
2707 /*
2708 * Try to find the wiphy and netdev. Normally this
2709 * function shouldn't need the netdev, but this is
2710 * done for backward compatibility -- previously
2711 * setting the channel was done per wiphy, but now
2712 * it is per netdev. Previous userland like hostapd
2713 * also passed a netdev to set_wiphy, so that it is
2714 * possible to let that go to the right netdev!
2715 */
4bbf4d56 2716
f444de05
JB
2717 if (info->attrs[NL80211_ATTR_IFINDEX]) {
2718 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
2719
7f2b8562 2720 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
5fe231e8 2721 if (netdev && netdev->ieee80211_ptr)
f26cbf40 2722 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
5fe231e8 2723 else
f444de05 2724 netdev = NULL;
4bbf4d56
JB
2725 }
2726
f444de05 2727 if (!netdev) {
878d9ec7
JB
2728 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
2729 info->attrs);
5fe231e8 2730 if (IS_ERR(rdev))
4c476991 2731 return PTR_ERR(rdev);
f444de05
JB
2732 wdev = NULL;
2733 netdev = NULL;
2734 result = 0;
71fe96bf 2735 } else
f444de05 2736 wdev = netdev->ieee80211_ptr;
f444de05
JB
2737
2738 /*
2739 * end workaround code, by now the rdev is available
2740 * and locked, and wdev may or may not be NULL.
2741 */
4bbf4d56
JB
2742
2743 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
31888487
JM
2744 result = cfg80211_dev_rename(
2745 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
4bbf4d56 2746
4bbf4d56 2747 if (result)
7f2b8562 2748 return result;
31888487
JM
2749
2750 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
2751 struct ieee80211_txq_params txq_params;
2752 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
2753
7f2b8562
YX
2754 if (!rdev->ops->set_txq_params)
2755 return -EOPNOTSUPP;
31888487 2756
7f2b8562
YX
2757 if (!netdev)
2758 return -EINVAL;
f70f01c2 2759
133a3ff2 2760 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7f2b8562
YX
2761 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2762 return -EINVAL;
133a3ff2 2763
7f2b8562
YX
2764 if (!netif_running(netdev))
2765 return -ENETDOWN;
2b5f8b0b 2766
31888487
JM
2767 nla_for_each_nested(nl_txq_params,
2768 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
2769 rem_txq_params) {
8cb08174
JB
2770 result = nla_parse_nested_deprecated(tb,
2771 NL80211_TXQ_ATTR_MAX,
2772 nl_txq_params,
2773 txq_params_policy,
2774 info->extack);
ae811e21
JB
2775 if (result)
2776 return result;
31888487
JM
2777 result = parse_txq_params(tb, &txq_params);
2778 if (result)
7f2b8562 2779 return result;
31888487 2780
e35e4d28
HG
2781 result = rdev_set_txq_params(rdev, netdev,
2782 &txq_params);
31888487 2783 if (result)
7f2b8562 2784 return result;
31888487
JM
2785 }
2786 }
55682965 2787
72bdcf34 2788 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
e16821bc
JM
2789 result = __nl80211_set_channel(
2790 rdev,
2791 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
2792 info);
72bdcf34 2793 if (result)
7f2b8562 2794 return result;
72bdcf34
JM
2795 }
2796
98d2ff8b 2797 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
c8442118 2798 struct wireless_dev *txp_wdev = wdev;
98d2ff8b
JO
2799 enum nl80211_tx_power_setting type;
2800 int idx, mbm = 0;
2801
c8442118
JB
2802 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
2803 txp_wdev = NULL;
2804
7f2b8562
YX
2805 if (!rdev->ops->set_tx_power)
2806 return -EOPNOTSUPP;
98d2ff8b
JO
2807
2808 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
2809 type = nla_get_u32(info->attrs[idx]);
2810
2811 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
7f2b8562
YX
2812 (type != NL80211_TX_POWER_AUTOMATIC))
2813 return -EINVAL;
98d2ff8b
JO
2814
2815 if (type != NL80211_TX_POWER_AUTOMATIC) {
2816 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
2817 mbm = nla_get_u32(info->attrs[idx]);
2818 }
2819
c8442118 2820 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
98d2ff8b 2821 if (result)
7f2b8562 2822 return result;
98d2ff8b
JO
2823 }
2824
afe0cbf8
BR
2825 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
2826 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
2827 u32 tx_ant, rx_ant;
7a087e74 2828
7f531e03
BR
2829 if ((!rdev->wiphy.available_antennas_tx &&
2830 !rdev->wiphy.available_antennas_rx) ||
7f2b8562
YX
2831 !rdev->ops->set_antenna)
2832 return -EOPNOTSUPP;
afe0cbf8
BR
2833
2834 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
2835 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
2836
a7ffac95 2837 /* reject antenna configurations which don't match the
7f531e03
BR
2838 * available antenna masks, except for the "all" mask */
2839 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
7f2b8562
YX
2840 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx)))
2841 return -EINVAL;
a7ffac95 2842
7f531e03
BR
2843 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
2844 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
a7ffac95 2845
e35e4d28 2846 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
afe0cbf8 2847 if (result)
7f2b8562 2848 return result;
afe0cbf8
BR
2849 }
2850
b9a5f8ca
JM
2851 changed = 0;
2852
2853 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
2854 retry_short = nla_get_u8(
2855 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
7f2b8562 2856
b9a5f8ca
JM
2857 changed |= WIPHY_PARAM_RETRY_SHORT;
2858 }
2859
2860 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
2861 retry_long = nla_get_u8(
2862 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
7f2b8562 2863
b9a5f8ca
JM
2864 changed |= WIPHY_PARAM_RETRY_LONG;
2865 }
2866
2867 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
2868 frag_threshold = nla_get_u32(
2869 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
7f2b8562
YX
2870 if (frag_threshold < 256)
2871 return -EINVAL;
2872
b9a5f8ca
JM
2873 if (frag_threshold != (u32) -1) {
2874 /*
2875 * Fragments (apart from the last one) are required to
2876 * have even length. Make the fragmentation code
2877 * simpler by stripping LSB should someone try to use
2878 * odd threshold value.
2879 */
2880 frag_threshold &= ~0x1;
2881 }
2882 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
2883 }
2884
2885 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
2886 rts_threshold = nla_get_u32(
2887 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
2888 changed |= WIPHY_PARAM_RTS_THRESHOLD;
2889 }
2890
81077e82 2891 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3057dbfd
LB
2892 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK])
2893 return -EINVAL;
2894
81077e82
LT
2895 coverage_class = nla_get_u8(
2896 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
2897 changed |= WIPHY_PARAM_COVERAGE_CLASS;
2898 }
2899
3057dbfd
LB
2900 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
2901 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION))
2902 return -EOPNOTSUPP;
2903
2904 changed |= WIPHY_PARAM_DYN_ACK;
81077e82
LT
2905 }
2906
52539ca8
THJ
2907 if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
2908 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2909 NL80211_EXT_FEATURE_TXQS))
2910 return -EOPNOTSUPP;
2911 txq_limit = nla_get_u32(
2912 info->attrs[NL80211_ATTR_TXQ_LIMIT]);
2913 changed |= WIPHY_PARAM_TXQ_LIMIT;
2914 }
2915
2916 if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
2917 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2918 NL80211_EXT_FEATURE_TXQS))
2919 return -EOPNOTSUPP;
2920 txq_memory_limit = nla_get_u32(
2921 info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
2922 changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
2923 }
2924
2925 if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
2926 if (!wiphy_ext_feature_isset(&rdev->wiphy,
2927 NL80211_EXT_FEATURE_TXQS))
2928 return -EOPNOTSUPP;
2929 txq_quantum = nla_get_u32(
2930 info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
2931 changed |= WIPHY_PARAM_TXQ_QUANTUM;
2932 }
2933
b9a5f8ca
JM
2934 if (changed) {
2935 u8 old_retry_short, old_retry_long;
2936 u32 old_frag_threshold, old_rts_threshold;
81077e82 2937 u8 old_coverage_class;
52539ca8 2938 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
b9a5f8ca 2939
7f2b8562
YX
2940 if (!rdev->ops->set_wiphy_params)
2941 return -EOPNOTSUPP;
b9a5f8ca
JM
2942
2943 old_retry_short = rdev->wiphy.retry_short;
2944 old_retry_long = rdev->wiphy.retry_long;
2945 old_frag_threshold = rdev->wiphy.frag_threshold;
2946 old_rts_threshold = rdev->wiphy.rts_threshold;
81077e82 2947 old_coverage_class = rdev->wiphy.coverage_class;
52539ca8
THJ
2948 old_txq_limit = rdev->wiphy.txq_limit;
2949 old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
2950 old_txq_quantum = rdev->wiphy.txq_quantum;
b9a5f8ca
JM
2951
2952 if (changed & WIPHY_PARAM_RETRY_SHORT)
2953 rdev->wiphy.retry_short = retry_short;
2954 if (changed & WIPHY_PARAM_RETRY_LONG)
2955 rdev->wiphy.retry_long = retry_long;
2956 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
2957 rdev->wiphy.frag_threshold = frag_threshold;
2958 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
2959 rdev->wiphy.rts_threshold = rts_threshold;
81077e82
LT
2960 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
2961 rdev->wiphy.coverage_class = coverage_class;
52539ca8
THJ
2962 if (changed & WIPHY_PARAM_TXQ_LIMIT)
2963 rdev->wiphy.txq_limit = txq_limit;
2964 if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
2965 rdev->wiphy.txq_memory_limit = txq_memory_limit;
2966 if (changed & WIPHY_PARAM_TXQ_QUANTUM)
2967 rdev->wiphy.txq_quantum = txq_quantum;
b9a5f8ca 2968
e35e4d28 2969 result = rdev_set_wiphy_params(rdev, changed);
b9a5f8ca
JM
2970 if (result) {
2971 rdev->wiphy.retry_short = old_retry_short;
2972 rdev->wiphy.retry_long = old_retry_long;
2973 rdev->wiphy.frag_threshold = old_frag_threshold;
2974 rdev->wiphy.rts_threshold = old_rts_threshold;
81077e82 2975 rdev->wiphy.coverage_class = old_coverage_class;
52539ca8
THJ
2976 rdev->wiphy.txq_limit = old_txq_limit;
2977 rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
2978 rdev->wiphy.txq_quantum = old_txq_quantum;
9189ee31 2979 return result;
b9a5f8ca
JM
2980 }
2981 }
7f2b8562 2982 return 0;
55682965
JB
2983}
2984
683b6d3b 2985static int nl80211_send_chandef(struct sk_buff *msg,
d2859df5 2986 const struct cfg80211_chan_def *chandef)
683b6d3b 2987{
601555cd
JB
2988 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
2989 return -EINVAL;
3d9d1d66 2990
683b6d3b
JB
2991 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
2992 chandef->chan->center_freq))
2993 return -ENOBUFS;
3d9d1d66
JB
2994 switch (chandef->width) {
2995 case NL80211_CHAN_WIDTH_20_NOHT:
2996 case NL80211_CHAN_WIDTH_20:
2997 case NL80211_CHAN_WIDTH_40:
2998 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
2999 cfg80211_get_chandef_type(chandef)))
3000 return -ENOBUFS;
3001 break;
3002 default:
3003 break;
3004 }
3005 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
3006 return -ENOBUFS;
3007 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
3008 return -ENOBUFS;
3009 if (chandef->center_freq2 &&
3010 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
683b6d3b
JB
3011 return -ENOBUFS;
3012 return 0;
3013}
3014
15e47304 3015static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
d726405a 3016 struct cfg80211_registered_device *rdev,
3d1a5bbf
AZ
3017 struct wireless_dev *wdev,
3018 enum nl80211_commands cmd)
55682965 3019{
72fb2abc 3020 struct net_device *dev = wdev->netdev;
55682965
JB
3021 void *hdr;
3022
3d1a5bbf
AZ
3023 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
3024 cmd != NL80211_CMD_DEL_INTERFACE &&
3025 cmd != NL80211_CMD_SET_INTERFACE);
8f894be2
TB
3026
3027 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
55682965
JB
3028 if (!hdr)
3029 return -1;
3030
72fb2abc
JB
3031 if (dev &&
3032 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
98104fde 3033 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
72fb2abc
JB
3034 goto nla_put_failure;
3035
3036 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3037 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
2dad624e
ND
3038 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
3039 NL80211_ATTR_PAD) ||
98104fde 3040 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
9360ffd1
DM
3041 nla_put_u32(msg, NL80211_ATTR_GENERATION,
3042 rdev->devlist_generation ^
446faa15
AQ
3043 (cfg80211_rdev_list_generation << 2)) ||
3044 nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr))
9360ffd1 3045 goto nla_put_failure;
f5ea9120 3046
5b7ccaf3 3047 if (rdev->ops->get_channel) {
683b6d3b
JB
3048 int ret;
3049 struct cfg80211_chan_def chandef;
3050
3051 ret = rdev_get_channel(rdev, wdev, &chandef);
3052 if (ret == 0) {
3053 if (nl80211_send_chandef(msg, &chandef))
3054 goto nla_put_failure;
3055 }
d91df0e3
PF
3056 }
3057
d55d0d59
RM
3058 if (rdev->ops->get_tx_power) {
3059 int dbm, ret;
3060
3061 ret = rdev_get_tx_power(rdev, wdev, &dbm);
3062 if (ret == 0 &&
3063 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
3064 DBM_TO_MBM(dbm)))
3065 goto nla_put_failure;
3066 }
3067
44905265
JB
3068 wdev_lock(wdev);
3069 switch (wdev->iftype) {
3070 case NL80211_IFTYPE_AP:
3071 if (wdev->ssid_len &&
3072 nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
4564b187 3073 goto nla_put_failure_locked;
44905265
JB
3074 break;
3075 case NL80211_IFTYPE_STATION:
3076 case NL80211_IFTYPE_P2P_CLIENT:
3077 case NL80211_IFTYPE_ADHOC: {
3078 const u8 *ssid_ie;
3079 if (!wdev->current_bss)
3080 break;
7a94b8c2 3081 rcu_read_lock();
44905265
JB
3082 ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
3083 WLAN_EID_SSID);
7a94b8c2
DB
3084 if (ssid_ie &&
3085 nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2))
3086 goto nla_put_failure_rcu_locked;
3087 rcu_read_unlock();
44905265
JB
3088 break;
3089 }
3090 default:
3091 /* nothing */
3092 break;
b84e7a05 3093 }
44905265 3094 wdev_unlock(wdev);
b84e7a05 3095
52539ca8
THJ
3096 if (rdev->ops->get_txq_stats) {
3097 struct cfg80211_txq_stats txqstats = {};
3098 int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
3099
3100 if (ret == 0 &&
3101 !nl80211_put_txq_stats(msg, &txqstats,
3102 NL80211_ATTR_TXQ_STATS))
3103 goto nla_put_failure;
3104 }
3105
053c095a
JB
3106 genlmsg_end(msg, hdr);
3107 return 0;
55682965 3108
7a94b8c2
DB
3109 nla_put_failure_rcu_locked:
3110 rcu_read_unlock();
4564b187
JB
3111 nla_put_failure_locked:
3112 wdev_unlock(wdev);
55682965 3113 nla_put_failure:
bc3ed28c
TG
3114 genlmsg_cancel(msg, hdr);
3115 return -EMSGSIZE;
55682965
JB
3116}
3117
3118static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
3119{
3120 int wp_idx = 0;
3121 int if_idx = 0;
3122 int wp_start = cb->args[0];
3123 int if_start = cb->args[1];
b7fb44da 3124 int filter_wiphy = -1;
f5ea9120 3125 struct cfg80211_registered_device *rdev;
55682965 3126 struct wireless_dev *wdev;
ea90e0dc 3127 int ret;
55682965 3128
5fe231e8 3129 rtnl_lock();
b7fb44da
DK
3130 if (!cb->args[2]) {
3131 struct nl80211_dump_wiphy_state state = {
3132 .filter_wiphy = -1,
3133 };
b7fb44da
DK
3134
3135 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
3136 if (ret)
ea90e0dc 3137 goto out_unlock;
b7fb44da
DK
3138
3139 filter_wiphy = state.filter_wiphy;
3140
3141 /*
3142 * if filtering, set cb->args[2] to +1 since 0 is the default
3143 * value needed to determine that parsing is necessary.
3144 */
3145 if (filter_wiphy >= 0)
3146 cb->args[2] = filter_wiphy + 1;
3147 else
3148 cb->args[2] = -1;
3149 } else if (cb->args[2] > 0) {
3150 filter_wiphy = cb->args[2] - 1;
3151 }
3152
f5ea9120
JB
3153 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
3154 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
463d0183 3155 continue;
bba95fef
JB
3156 if (wp_idx < wp_start) {
3157 wp_idx++;
55682965 3158 continue;
bba95fef 3159 }
b7fb44da
DK
3160
3161 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
3162 continue;
3163
55682965
JB
3164 if_idx = 0;
3165
53873f13 3166 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
bba95fef
JB
3167 if (if_idx < if_start) {
3168 if_idx++;
55682965 3169 continue;
bba95fef 3170 }
15e47304 3171 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
55682965 3172 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3d1a5bbf
AZ
3173 rdev, wdev,
3174 NL80211_CMD_NEW_INTERFACE) < 0) {
bba95fef
JB
3175 goto out;
3176 }
3177 if_idx++;
55682965 3178 }
bba95fef
JB
3179
3180 wp_idx++;
55682965 3181 }
bba95fef 3182 out:
55682965
JB
3183 cb->args[0] = wp_idx;
3184 cb->args[1] = if_idx;
3185
ea90e0dc
JB
3186 ret = skb->len;
3187 out_unlock:
3188 rtnl_unlock();
3189
3190 return ret;
55682965
JB
3191}
3192
3193static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
3194{
3195 struct sk_buff *msg;
1b8ec87a 3196 struct cfg80211_registered_device *rdev = info->user_ptr[0];
72fb2abc 3197 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3198
fd2120ca 3199 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965 3200 if (!msg)
4c476991 3201 return -ENOMEM;
55682965 3202
15e47304 3203 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 3204 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
4c476991
JB
3205 nlmsg_free(msg);
3206 return -ENOBUFS;
3207 }
55682965 3208
134e6375 3209 return genlmsg_reply(msg, info);
55682965
JB
3210}
3211
66f7ac50
MW
3212static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
3213 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
3214 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
3215 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
3216 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
3217 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
e057d3c3 3218 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
66f7ac50
MW
3219};
3220
3221static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
3222{
3223 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
3224 int flag;
3225
3226 *mntrflags = 0;
3227
3228 if (!nla)
3229 return -EINVAL;
3230
8cb08174 3231 if (nla_parse_nested_deprecated(flags, NL80211_MNTR_FLAG_MAX, nla, mntr_flags_policy, NULL))
66f7ac50
MW
3232 return -EINVAL;
3233
3234 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
3235 if (flags[flag])
3236 *mntrflags |= (1<<flag);
3237
818a986e
JB
3238 *mntrflags |= MONITOR_FLAG_CHANGED;
3239
66f7ac50
MW
3240 return 0;
3241}
3242
1db77596
JB
3243static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
3244 enum nl80211_iftype type,
3245 struct genl_info *info,
3246 struct vif_params *params)
3247{
3248 bool change = false;
3249 int err;
3250
3251 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
3252 if (type != NL80211_IFTYPE_MONITOR)
3253 return -EINVAL;
3254
3255 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
3256 &params->flags);
3257 if (err)
3258 return err;
3259
3260 change = true;
3261 }
3262
3263 if (params->flags & MONITOR_FLAG_ACTIVE &&
3264 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
3265 return -EOPNOTSUPP;
3266
3267 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
3268 const u8 *mumimo_groups;
3269 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3270
3271 if (type != NL80211_IFTYPE_MONITOR)
3272 return -EINVAL;
3273
3274 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3275 return -EOPNOTSUPP;
3276
3277 mumimo_groups =
3278 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
3279
3280 /* bits 0 and 63 are reserved and must be zero */
4954601f
JB
3281 if ((mumimo_groups[0] & BIT(0)) ||
3282 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
1db77596
JB
3283 return -EINVAL;
3284
3285 params->vht_mumimo_groups = mumimo_groups;
3286 change = true;
3287 }
3288
3289 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
3290 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
3291
3292 if (type != NL80211_IFTYPE_MONITOR)
3293 return -EINVAL;
3294
3295 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
3296 return -EOPNOTSUPP;
3297
3298 params->vht_mumimo_follow_addr =
3299 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
3300 change = true;
3301 }
3302
3303 return change ? 1 : 0;
3304}
3305
9bc383de 3306static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
ad4bb6f8
JB
3307 struct net_device *netdev, u8 use_4addr,
3308 enum nl80211_iftype iftype)
9bc383de 3309{
ad4bb6f8 3310 if (!use_4addr) {
f350a0a8 3311 if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT))
ad4bb6f8 3312 return -EBUSY;
9bc383de 3313 return 0;
ad4bb6f8 3314 }
9bc383de
JB
3315
3316 switch (iftype) {
3317 case NL80211_IFTYPE_AP_VLAN:
3318 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
3319 return 0;
3320 break;
3321 case NL80211_IFTYPE_STATION:
3322 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
3323 return 0;
3324 break;
3325 default:
3326 break;
3327 }
3328
3329 return -EOPNOTSUPP;
3330}
3331
55682965
JB
3332static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
3333{
4c476991 3334 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3335 struct vif_params params;
e36d56b6 3336 int err;
04a773ad 3337 enum nl80211_iftype otype, ntype;
4c476991 3338 struct net_device *dev = info->user_ptr[1];
ac7f9cfa 3339 bool change = false;
55682965 3340
2ec600d6
LCC
3341 memset(&params, 0, sizeof(params));
3342
04a773ad 3343 otype = ntype = dev->ieee80211_ptr->iftype;
55682965 3344
723b038d 3345 if (info->attrs[NL80211_ATTR_IFTYPE]) {
ac7f9cfa 3346 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
04a773ad 3347 if (otype != ntype)
ac7f9cfa 3348 change = true;
723b038d
JB
3349 }
3350
92ffe055 3351 if (info->attrs[NL80211_ATTR_MESH_ID]) {
29cbe68c
JB
3352 struct wireless_dev *wdev = dev->ieee80211_ptr;
3353
4c476991
JB
3354 if (ntype != NL80211_IFTYPE_MESH_POINT)
3355 return -EINVAL;
29cbe68c
JB
3356 if (netif_running(dev))
3357 return -EBUSY;
3358
3359 wdev_lock(wdev);
3360 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3361 IEEE80211_MAX_MESH_ID_LEN);
3362 wdev->mesh_id_up_len =
3363 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3364 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3365 wdev->mesh_id_up_len);
3366 wdev_unlock(wdev);
2ec600d6
LCC
3367 }
3368
8b787643
FF
3369 if (info->attrs[NL80211_ATTR_4ADDR]) {
3370 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
3371 change = true;
ad4bb6f8 3372 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
9bc383de 3373 if (err)
4c476991 3374 return err;
8b787643
FF
3375 } else {
3376 params.use_4addr = -1;
3377 }
3378
1db77596
JB
3379 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
3380 if (err < 0)
3381 return err;
3382 if (err > 0)
c6e6a0c8 3383 change = true;
e057d3c3 3384
ac7f9cfa 3385 if (change)
818a986e 3386 err = cfg80211_change_iface(rdev, dev, ntype, &params);
ac7f9cfa
JB
3387 else
3388 err = 0;
60719ffd 3389
9bc383de
JB
3390 if (!err && params.use_4addr != -1)
3391 dev->ieee80211_ptr->use_4addr = params.use_4addr;
3392
3d1a5bbf
AZ
3393 if (change && !err) {
3394 struct wireless_dev *wdev = dev->ieee80211_ptr;
3395
3396 nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
3397 }
3398
55682965
JB
3399 return err;
3400}
3401
3402static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
3403{
4c476991 3404 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 3405 struct vif_params params;
84efbb84 3406 struct wireless_dev *wdev;
896ff063 3407 struct sk_buff *msg;
55682965
JB
3408 int err;
3409 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
3410
78f22b6a
JB
3411 /* to avoid failing a new interface creation due to pending removal */
3412 cfg80211_destroy_ifaces(rdev);
3413
2ec600d6
LCC
3414 memset(&params, 0, sizeof(params));
3415
55682965
JB
3416 if (!info->attrs[NL80211_ATTR_IFNAME])
3417 return -EINVAL;
3418
ab0d76f6 3419 if (info->attrs[NL80211_ATTR_IFTYPE])
55682965 3420 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
55682965 3421
33d915d9 3422 if (!rdev->ops->add_virtual_intf)
4c476991 3423 return -EOPNOTSUPP;
55682965 3424
cb3b7d87 3425 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
e8f479b1
BG
3426 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
3427 info->attrs[NL80211_ATTR_MAC]) {
1c18f145
AS
3428 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
3429 ETH_ALEN);
3430 if (!is_valid_ether_addr(params.macaddr))
3431 return -EADDRNOTAVAIL;
3432 }
3433
9bc383de 3434 if (info->attrs[NL80211_ATTR_4ADDR]) {
8b787643 3435 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
ad4bb6f8 3436 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
9bc383de 3437 if (err)
4c476991 3438 return err;
9bc383de 3439 }
8b787643 3440
33d915d9
MP
3441 if (!(rdev->wiphy.interface_modes & (1 << type)) &&
3442 !(type == NL80211_IFTYPE_AP_VLAN && params.use_4addr &&
3443 rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP))
3444 return -EOPNOTSUPP;
3445
1db77596
JB
3446 err = nl80211_parse_mon_options(rdev, type, info, &params);
3447 if (err < 0)
3448 return err;
e057d3c3 3449
a18c7192
JB
3450 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3451 if (!msg)
3452 return -ENOMEM;
3453
e35e4d28
HG
3454 wdev = rdev_add_virtual_intf(rdev,
3455 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
818a986e 3456 NET_NAME_USER, type, &params);
d687cbb7
RM
3457 if (WARN_ON(!wdev)) {
3458 nlmsg_free(msg);
3459 return -EPROTO;
3460 } else if (IS_ERR(wdev)) {
1c90f9d4 3461 nlmsg_free(msg);
84efbb84 3462 return PTR_ERR(wdev);
1c90f9d4 3463 }
2ec600d6 3464
18e5ca65 3465 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
78f22b6a
JB
3466 wdev->owner_nlportid = info->snd_portid;
3467
98104fde
JB
3468 switch (type) {
3469 case NL80211_IFTYPE_MESH_POINT:
3470 if (!info->attrs[NL80211_ATTR_MESH_ID])
3471 break;
29cbe68c
JB
3472 wdev_lock(wdev);
3473 BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN !=
3474 IEEE80211_MAX_MESH_ID_LEN);
3475 wdev->mesh_id_up_len =
3476 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
3477 memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
3478 wdev->mesh_id_up_len);
3479 wdev_unlock(wdev);
98104fde 3480 break;
cb3b7d87 3481 case NL80211_IFTYPE_NAN:
98104fde
JB
3482 case NL80211_IFTYPE_P2P_DEVICE:
3483 /*
cb3b7d87 3484 * P2P Device and NAN do not have a netdev, so don't go
98104fde
JB
3485 * through the netdev notifier and must be added here
3486 */
e4d4216e 3487 cfg80211_init_wdev(rdev, wdev);
98104fde
JB
3488 break;
3489 default:
3490 break;
29cbe68c
JB
3491 }
3492
15e47304 3493 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
3d1a5bbf 3494 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
1c90f9d4
JB
3495 nlmsg_free(msg);
3496 return -ENOBUFS;
3497 }
3498
3499 return genlmsg_reply(msg, info);
55682965
JB
3500}
3501
3502static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
3503{
4c476991 3504 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84efbb84 3505 struct wireless_dev *wdev = info->user_ptr[1];
55682965 3506
4c476991
JB
3507 if (!rdev->ops->del_virtual_intf)
3508 return -EOPNOTSUPP;
55682965 3509
84efbb84
JB
3510 /*
3511 * If we remove a wireless device without a netdev then clear
3512 * user_ptr[1] so that nl80211_post_doit won't dereference it
3513 * to check if it needs to do dev_put(). Otherwise it crashes
3514 * since the wdev has been freed, unlike with a netdev where
3515 * we need the dev_put() for the netdev to really be freed.
3516 */
3517 if (!wdev->netdev)
3518 info->user_ptr[1] = NULL;
3519
7f8ed01e 3520 return rdev_del_virtual_intf(rdev, wdev);
55682965
JB
3521}
3522
1d9d9213
SW
3523static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
3524{
3525 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3526 struct net_device *dev = info->user_ptr[1];
3527 u16 noack_map;
3528
3529 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
3530 return -EINVAL;
3531
3532 if (!rdev->ops->set_noack_map)
3533 return -EOPNOTSUPP;
3534
3535 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
3536
e35e4d28 3537 return rdev_set_noack_map(rdev, dev, noack_map);
1d9d9213
SW
3538}
3539
41ade00f
JB
3540struct get_key_cookie {
3541 struct sk_buff *msg;
3542 int error;
b9454e83 3543 int idx;
41ade00f
JB
3544};
3545
3546static void get_key_callback(void *c, struct key_params *params)
3547{
b9454e83 3548 struct nlattr *key;
41ade00f
JB
3549 struct get_key_cookie *cookie = c;
3550
9360ffd1
DM
3551 if ((params->key &&
3552 nla_put(cookie->msg, NL80211_ATTR_KEY_DATA,
3553 params->key_len, params->key)) ||
3554 (params->seq &&
3555 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
3556 params->seq_len, params->seq)) ||
3557 (params->cipher &&
3558 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
3559 params->cipher)))
3560 goto nla_put_failure;
41ade00f 3561
ae0be8de 3562 key = nla_nest_start_noflag(cookie->msg, NL80211_ATTR_KEY);
b9454e83
JB
3563 if (!key)
3564 goto nla_put_failure;
3565
9360ffd1
DM
3566 if ((params->key &&
3567 nla_put(cookie->msg, NL80211_KEY_DATA,
3568 params->key_len, params->key)) ||
3569 (params->seq &&
3570 nla_put(cookie->msg, NL80211_KEY_SEQ,
3571 params->seq_len, params->seq)) ||
3572 (params->cipher &&
3573 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
3574 params->cipher)))
3575 goto nla_put_failure;
b9454e83 3576
efdfce72 3577 if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
9360ffd1 3578 goto nla_put_failure;
b9454e83
JB
3579
3580 nla_nest_end(cookie->msg, key);
3581
41ade00f
JB
3582 return;
3583 nla_put_failure:
3584 cookie->error = 1;
3585}
3586
3587static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
3588{
4c476991 3589 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3590 int err;
4c476991 3591 struct net_device *dev = info->user_ptr[1];
41ade00f 3592 u8 key_idx = 0;
e31b8213
JB
3593 const u8 *mac_addr = NULL;
3594 bool pairwise;
41ade00f
JB
3595 struct get_key_cookie cookie = {
3596 .error = 0,
3597 };
3598 void *hdr;
3599 struct sk_buff *msg;
3600
3601 if (info->attrs[NL80211_ATTR_KEY_IDX])
3602 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
3603
41ade00f
JB
3604 if (info->attrs[NL80211_ATTR_MAC])
3605 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3606
e31b8213
JB
3607 pairwise = !!mac_addr;
3608 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
3609 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
7a087e74 3610
e31b8213
JB
3611 if (kt != NL80211_KEYTYPE_GROUP &&
3612 kt != NL80211_KEYTYPE_PAIRWISE)
3613 return -EINVAL;
3614 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
3615 }
3616
4c476991
JB
3617 if (!rdev->ops->get_key)
3618 return -EOPNOTSUPP;
41ade00f 3619
0fa7b391
JB
3620 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3621 return -ENOENT;
3622
fd2120ca 3623 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
3624 if (!msg)
3625 return -ENOMEM;
41ade00f 3626
15e47304 3627 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
41ade00f 3628 NL80211_CMD_NEW_KEY);
cb35fba3 3629 if (!hdr)
9fe271af 3630 goto nla_put_failure;
41ade00f
JB
3631
3632 cookie.msg = msg;
b9454e83 3633 cookie.idx = key_idx;
41ade00f 3634
9360ffd1
DM
3635 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3636 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
3637 goto nla_put_failure;
3638 if (mac_addr &&
3639 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
3640 goto nla_put_failure;
41ade00f 3641
e35e4d28
HG
3642 err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie,
3643 get_key_callback);
41ade00f
JB
3644
3645 if (err)
6c95e2a2 3646 goto free_msg;
41ade00f
JB
3647
3648 if (cookie.error)
3649 goto nla_put_failure;
3650
3651 genlmsg_end(msg, hdr);
4c476991 3652 return genlmsg_reply(msg, info);
41ade00f
JB
3653
3654 nla_put_failure:
3655 err = -ENOBUFS;
6c95e2a2 3656 free_msg:
41ade00f 3657 nlmsg_free(msg);
41ade00f
JB
3658 return err;
3659}
3660
3661static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
3662{
4c476991 3663 struct cfg80211_registered_device *rdev = info->user_ptr[0];
b9454e83 3664 struct key_parse key;
41ade00f 3665 int err;
4c476991 3666 struct net_device *dev = info->user_ptr[1];
41ade00f 3667
b9454e83
JB
3668 err = nl80211_parse_key(info, &key);
3669 if (err)
3670 return err;
41ade00f 3671
b9454e83 3672 if (key.idx < 0)
41ade00f
JB
3673 return -EINVAL;
3674
6cdd3979
AW
3675 /* Only support setting default key and
3676 * Extended Key ID action NL80211_KEY_SET_TX.
3677 */
3678 if (!key.def && !key.defmgmt &&
3679 !(key.p.mode == NL80211_KEY_SET_TX))
41ade00f
JB
3680 return -EINVAL;
3681
dbd2fd65 3682 wdev_lock(dev->ieee80211_ptr);
3cfcf6ac 3683
dbd2fd65
JB
3684 if (key.def) {
3685 if (!rdev->ops->set_default_key) {
3686 err = -EOPNOTSUPP;
3687 goto out;
3688 }
41ade00f 3689
dbd2fd65
JB
3690 err = nl80211_key_allowed(dev->ieee80211_ptr);
3691 if (err)
3692 goto out;
3693
e35e4d28 3694 err = rdev_set_default_key(rdev, dev, key.idx,
dbd2fd65
JB
3695 key.def_uni, key.def_multi);
3696
3697 if (err)
3698 goto out;
fffd0934 3699
3d23e349 3700#ifdef CONFIG_CFG80211_WEXT
dbd2fd65
JB
3701 dev->ieee80211_ptr->wext.default_key = key.idx;
3702#endif
6cdd3979 3703 } else if (key.defmgmt) {
dbd2fd65
JB
3704 if (key.def_uni || !key.def_multi) {
3705 err = -EINVAL;
3706 goto out;
3707 }
3708
3709 if (!rdev->ops->set_default_mgmt_key) {
3710 err = -EOPNOTSUPP;
3711 goto out;
3712 }
3713
3714 err = nl80211_key_allowed(dev->ieee80211_ptr);
3715 if (err)
3716 goto out;
3717
e35e4d28 3718 err = rdev_set_default_mgmt_key(rdev, dev, key.idx);
dbd2fd65
JB
3719 if (err)
3720 goto out;
3721
3722#ifdef CONFIG_CFG80211_WEXT
3723 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
08645126 3724#endif
6cdd3979
AW
3725 } else if (key.p.mode == NL80211_KEY_SET_TX &&
3726 wiphy_ext_feature_isset(&rdev->wiphy,
3727 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
3728 u8 *mac_addr = NULL;
3729
3730 if (info->attrs[NL80211_ATTR_MAC])
3731 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3732
3733 if (!mac_addr || key.idx < 0 || key.idx > 1) {
3734 err = -EINVAL;
3735 goto out;
3736 }
dbd2fd65 3737
6cdd3979
AW
3738 err = rdev_add_key(rdev, dev, key.idx,
3739 NL80211_KEYTYPE_PAIRWISE,
3740 mac_addr, &key.p);
3741 } else {
3742 err = -EINVAL;
3743 }
dbd2fd65 3744 out:
fffd0934 3745 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3746
41ade00f
JB
3747 return err;
3748}
3749
3750static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
3751{
4c476991 3752 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fffd0934 3753 int err;
4c476991 3754 struct net_device *dev = info->user_ptr[1];
b9454e83 3755 struct key_parse key;
e31b8213 3756 const u8 *mac_addr = NULL;
41ade00f 3757
b9454e83
JB
3758 err = nl80211_parse_key(info, &key);
3759 if (err)
3760 return err;
41ade00f 3761
b9454e83 3762 if (!key.p.key)
41ade00f
JB
3763 return -EINVAL;
3764
41ade00f
JB
3765 if (info->attrs[NL80211_ATTR_MAC])
3766 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3767
e31b8213
JB
3768 if (key.type == -1) {
3769 if (mac_addr)
3770 key.type = NL80211_KEYTYPE_PAIRWISE;
3771 else
3772 key.type = NL80211_KEYTYPE_GROUP;
3773 }
3774
3775 /* for now */
3776 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3777 key.type != NL80211_KEYTYPE_GROUP)
3778 return -EINVAL;
3779
4c476991
JB
3780 if (!rdev->ops->add_key)
3781 return -EOPNOTSUPP;
25e47c18 3782
e31b8213
JB
3783 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
3784 key.type == NL80211_KEYTYPE_PAIRWISE,
3785 mac_addr))
4c476991 3786 return -EINVAL;
41ade00f 3787
fffd0934
JB
3788 wdev_lock(dev->ieee80211_ptr);
3789 err = nl80211_key_allowed(dev->ieee80211_ptr);
3790 if (!err)
e35e4d28
HG
3791 err = rdev_add_key(rdev, dev, key.idx,
3792 key.type == NL80211_KEYTYPE_PAIRWISE,
3793 mac_addr, &key.p);
fffd0934 3794 wdev_unlock(dev->ieee80211_ptr);
41ade00f 3795
41ade00f
JB
3796 return err;
3797}
3798
3799static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
3800{
4c476991 3801 struct cfg80211_registered_device *rdev = info->user_ptr[0];
41ade00f 3802 int err;
4c476991 3803 struct net_device *dev = info->user_ptr[1];
41ade00f 3804 u8 *mac_addr = NULL;
b9454e83 3805 struct key_parse key;
41ade00f 3806
b9454e83
JB
3807 err = nl80211_parse_key(info, &key);
3808 if (err)
3809 return err;
41ade00f
JB
3810
3811 if (info->attrs[NL80211_ATTR_MAC])
3812 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
3813
e31b8213
JB
3814 if (key.type == -1) {
3815 if (mac_addr)
3816 key.type = NL80211_KEYTYPE_PAIRWISE;
3817 else
3818 key.type = NL80211_KEYTYPE_GROUP;
3819 }
3820
3821 /* for now */
3822 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
3823 key.type != NL80211_KEYTYPE_GROUP)
3824 return -EINVAL;
3825
4c476991
JB
3826 if (!rdev->ops->del_key)
3827 return -EOPNOTSUPP;
41ade00f 3828
fffd0934
JB
3829 wdev_lock(dev->ieee80211_ptr);
3830 err = nl80211_key_allowed(dev->ieee80211_ptr);
e31b8213 3831
0fa7b391 3832 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
e31b8213
JB
3833 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
3834 err = -ENOENT;
3835
fffd0934 3836 if (!err)
e35e4d28
HG
3837 err = rdev_del_key(rdev, dev, key.idx,
3838 key.type == NL80211_KEYTYPE_PAIRWISE,
3839 mac_addr);
41ade00f 3840
3d23e349 3841#ifdef CONFIG_CFG80211_WEXT
08645126 3842 if (!err) {
b9454e83 3843 if (key.idx == dev->ieee80211_ptr->wext.default_key)
08645126 3844 dev->ieee80211_ptr->wext.default_key = -1;
b9454e83 3845 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
08645126
JB
3846 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
3847 }
3848#endif
fffd0934 3849 wdev_unlock(dev->ieee80211_ptr);
08645126 3850
41ade00f
JB
3851 return err;
3852}
3853
77765eaf
VT
3854/* This function returns an error or the number of nested attributes */
3855static int validate_acl_mac_addrs(struct nlattr *nl_attr)
3856{
3857 struct nlattr *attr;
3858 int n_entries = 0, tmp;
3859
3860 nla_for_each_nested(attr, nl_attr, tmp) {
3861 if (nla_len(attr) != ETH_ALEN)
3862 return -EINVAL;
3863
3864 n_entries++;
3865 }
3866
3867 return n_entries;
3868}
3869
3870/*
3871 * This function parses ACL information and allocates memory for ACL data.
3872 * On successful return, the calling function is responsible to free the
3873 * ACL buffer returned by this function.
3874 */
3875static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
3876 struct genl_info *info)
3877{
3878 enum nl80211_acl_policy acl_policy;
3879 struct nlattr *attr;
3880 struct cfg80211_acl_data *acl;
3881 int i = 0, n_entries, tmp;
3882
3883 if (!wiphy->max_acl_mac_addrs)
3884 return ERR_PTR(-EOPNOTSUPP);
3885
3886 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
3887 return ERR_PTR(-EINVAL);
3888
3889 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
3890 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
3891 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
3892 return ERR_PTR(-EINVAL);
3893
3894 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
3895 return ERR_PTR(-EINVAL);
3896
3897 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
3898 if (n_entries < 0)
3899 return ERR_PTR(n_entries);
3900
3901 if (n_entries > wiphy->max_acl_mac_addrs)
3902 return ERR_PTR(-ENOTSUPP);
3903
391d132c 3904 acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
77765eaf
VT
3905 if (!acl)
3906 return ERR_PTR(-ENOMEM);
3907
3908 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
3909 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
3910 i++;
3911 }
3912
3913 acl->n_acl_entries = n_entries;
3914 acl->acl_policy = acl_policy;
3915
3916 return acl;
3917}
3918
3919static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
3920{
3921 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3922 struct net_device *dev = info->user_ptr[1];
3923 struct cfg80211_acl_data *acl;
3924 int err;
3925
3926 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3927 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3928 return -EOPNOTSUPP;
3929
3930 if (!dev->ieee80211_ptr->beacon_interval)
3931 return -EINVAL;
3932
3933 acl = parse_acl_data(&rdev->wiphy, info);
3934 if (IS_ERR(acl))
3935 return PTR_ERR(acl);
3936
3937 err = rdev_set_mac_acl(rdev, dev, acl);
3938
3939 kfree(acl);
3940
3941 return err;
3942}
3943
a7c7fbff
PK
3944static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
3945 u8 *rates, u8 rates_len)
3946{
3947 u8 i;
3948 u32 mask = 0;
3949
3950 for (i = 0; i < rates_len; i++) {
3951 int rate = (rates[i] & 0x7f) * 5;
3952 int ridx;
3953
3954 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
3955 struct ieee80211_rate *srate =
3956 &sband->bitrates[ridx];
3957 if (rate == srate->bitrate) {
3958 mask |= 1 << ridx;
3959 break;
3960 }
3961 }
3962 if (ridx == sband->n_bitrates)
3963 return 0; /* rate not found */
3964 }
3965
3966 return mask;
3967}
3968
3969static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
3970 u8 *rates, u8 rates_len,
3971 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
3972{
3973 u8 i;
3974
3975 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
3976
3977 for (i = 0; i < rates_len; i++) {
3978 int ridx, rbit;
3979
3980 ridx = rates[i] / 8;
3981 rbit = BIT(rates[i] % 8);
3982
3983 /* check validity */
3984 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
3985 return false;
3986
3987 /* check availability */
30fe6d50 3988 ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
a7c7fbff
PK
3989 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
3990 mcs[ridx] |= rbit;
3991 else
3992 return false;
3993 }
3994
3995 return true;
3996}
3997
3998static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
3999{
4000 u16 mcs_mask = 0;
4001
4002 switch (vht_mcs_map) {
4003 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
4004 break;
4005 case IEEE80211_VHT_MCS_SUPPORT_0_7:
4006 mcs_mask = 0x00FF;
4007 break;
4008 case IEEE80211_VHT_MCS_SUPPORT_0_8:
4009 mcs_mask = 0x01FF;
4010 break;
4011 case IEEE80211_VHT_MCS_SUPPORT_0_9:
4012 mcs_mask = 0x03FF;
4013 break;
4014 default:
4015 break;
4016 }
4017
4018 return mcs_mask;
4019}
4020
4021static void vht_build_mcs_mask(u16 vht_mcs_map,
4022 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
4023{
4024 u8 nss;
4025
4026 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
4027 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
4028 vht_mcs_map >>= 2;
4029 }
4030}
4031
4032static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
4033 struct nl80211_txrate_vht *txrate,
4034 u16 mcs[NL80211_VHT_NSS_MAX])
4035{
4036 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4037 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
4038 u8 i;
4039
4040 if (!sband->vht_cap.vht_supported)
4041 return false;
4042
4043 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
4044
4045 /* Build vht_mcs_mask from VHT capabilities */
4046 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
4047
4048 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
4049 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
4050 mcs[i] = txrate->mcs[i];
4051 else
4052 return false;
4053 }
4054
4055 return true;
4056}
4057
4058static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
4059 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
4060 .len = NL80211_MAX_SUPP_RATES },
4061 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
4062 .len = NL80211_MAX_SUPP_HT_RATES },
4063 [NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
4064 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
4065};
4066
4067static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
4068 struct cfg80211_bitrate_mask *mask)
4069{
4070 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4071 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4072 int rem, i;
4073 struct nlattr *tx_rates;
4074 struct ieee80211_supported_band *sband;
4075 u16 vht_tx_mcs_map;
4076
4077 memset(mask, 0, sizeof(*mask));
4078 /* Default to all rates enabled */
4079 for (i = 0; i < NUM_NL80211_BANDS; i++) {
4080 sband = rdev->wiphy.bands[i];
4081
4082 if (!sband)
4083 continue;
4084
4085 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
4086 memcpy(mask->control[i].ht_mcs,
4087 sband->ht_cap.mcs.rx_mask,
4088 sizeof(mask->control[i].ht_mcs));
4089
4090 if (!sband->vht_cap.vht_supported)
4091 continue;
4092
4093 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
4094 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
4095 }
4096
4097 /* if no rates are given set it back to the defaults */
4098 if (!info->attrs[NL80211_ATTR_TX_RATES])
4099 goto out;
4100
4101 /* The nested attribute uses enum nl80211_band as the index. This maps
4102 * directly to the enum nl80211_band values used in cfg80211.
4103 */
4104 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
4105 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) {
4106 enum nl80211_band band = nla_type(tx_rates);
4107 int err;
4108
4109 if (band < 0 || band >= NUM_NL80211_BANDS)
4110 return -EINVAL;
4111 sband = rdev->wiphy.bands[band];
4112 if (sband == NULL)
4113 return -EINVAL;
8cb08174
JB
4114 err = nla_parse_nested_deprecated(tb, NL80211_TXRATE_MAX,
4115 tx_rates,
4116 nl80211_txattr_policy,
4117 info->extack);
a7c7fbff
PK
4118 if (err)
4119 return err;
4120 if (tb[NL80211_TXRATE_LEGACY]) {
4121 mask->control[band].legacy = rateset_to_mask(
4122 sband,
4123 nla_data(tb[NL80211_TXRATE_LEGACY]),
4124 nla_len(tb[NL80211_TXRATE_LEGACY]));
4125 if ((mask->control[band].legacy == 0) &&
4126 nla_len(tb[NL80211_TXRATE_LEGACY]))
4127 return -EINVAL;
4128 }
4129 if (tb[NL80211_TXRATE_HT]) {
4130 if (!ht_rateset_to_mask(
4131 sband,
4132 nla_data(tb[NL80211_TXRATE_HT]),
4133 nla_len(tb[NL80211_TXRATE_HT]),
4134 mask->control[band].ht_mcs))
4135 return -EINVAL;
4136 }
4137 if (tb[NL80211_TXRATE_VHT]) {
4138 if (!vht_set_mcs_mask(
4139 sband,
4140 nla_data(tb[NL80211_TXRATE_VHT]),
4141 mask->control[band].vht_mcs))
4142 return -EINVAL;
4143 }
4144 if (tb[NL80211_TXRATE_GI]) {
4145 mask->control[band].gi =
4146 nla_get_u8(tb[NL80211_TXRATE_GI]);
4147 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
4148 return -EINVAL;
4149 }
4150
4151 if (mask->control[band].legacy == 0) {
4152 /* don't allow empty legacy rates if HT or VHT
4153 * are not even supported.
4154 */
4155 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
4156 rdev->wiphy.bands[band]->vht_cap.vht_supported))
4157 return -EINVAL;
4158
4159 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
4160 if (mask->control[band].ht_mcs[i])
4161 goto out;
4162
4163 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
4164 if (mask->control[band].vht_mcs[i])
4165 goto out;
4166
4167 /* legacy and mcs rates may not be both empty */
4168 return -EINVAL;
4169 }
4170 }
4171
4172out:
4173 return 0;
4174}
4175
8564e382
JB
4176static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
4177 enum nl80211_band band,
4178 struct cfg80211_bitrate_mask *beacon_rate)
a7c7fbff 4179{
8564e382
JB
4180 u32 count_ht, count_vht, i;
4181 u32 rate = beacon_rate->control[band].legacy;
a7c7fbff
PK
4182
4183 /* Allow only one rate */
4184 if (hweight32(rate) > 1)
4185 return -EINVAL;
4186
4187 count_ht = 0;
4188 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
8564e382 4189 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
a7c7fbff 4190 return -EINVAL;
8564e382 4191 } else if (beacon_rate->control[band].ht_mcs[i]) {
a7c7fbff
PK
4192 count_ht++;
4193 if (count_ht > 1)
4194 return -EINVAL;
4195 }
4196 if (count_ht && rate)
4197 return -EINVAL;
4198 }
4199
4200 count_vht = 0;
4201 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
8564e382 4202 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
a7c7fbff 4203 return -EINVAL;
8564e382 4204 } else if (beacon_rate->control[band].vht_mcs[i]) {
a7c7fbff
PK
4205 count_vht++;
4206 if (count_vht > 1)
4207 return -EINVAL;
4208 }
4209 if (count_vht && rate)
4210 return -EINVAL;
4211 }
4212
4213 if ((count_ht && count_vht) || (!rate && !count_ht && !count_vht))
4214 return -EINVAL;
4215
8564e382
JB
4216 if (rate &&
4217 !wiphy_ext_feature_isset(&rdev->wiphy,
4218 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
4219 return -EINVAL;
4220 if (count_ht &&
4221 !wiphy_ext_feature_isset(&rdev->wiphy,
4222 NL80211_EXT_FEATURE_BEACON_RATE_HT))
4223 return -EINVAL;
4224 if (count_vht &&
4225 !wiphy_ext_feature_isset(&rdev->wiphy,
4226 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
4227 return -EINVAL;
4228
a7c7fbff
PK
4229 return 0;
4230}
4231
81e54d08
PKC
4232static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
4233 struct nlattr *attrs[],
8860020e 4234 struct cfg80211_beacon_data *bcn)
ed1b6cc7 4235{
8860020e 4236 bool haveinfo = false;
81e54d08 4237 int err;
ed1b6cc7 4238
8860020e 4239 memset(bcn, 0, sizeof(*bcn));
ed1b6cc7 4240
a1193be8
SW
4241 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
4242 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
4243 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
8860020e
JB
4244 if (!bcn->head_len)
4245 return -EINVAL;
4246 haveinfo = true;
ed1b6cc7
JB
4247 }
4248
a1193be8
SW
4249 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
4250 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
4251 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
8860020e 4252 haveinfo = true;
ed1b6cc7
JB
4253 }
4254
4c476991
JB
4255 if (!haveinfo)
4256 return -EINVAL;
3b85875a 4257
a1193be8
SW
4258 if (attrs[NL80211_ATTR_IE]) {
4259 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
4260 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
9946ecfb
JM
4261 }
4262
a1193be8 4263 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
8860020e 4264 bcn->proberesp_ies =
a1193be8 4265 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
8860020e 4266 bcn->proberesp_ies_len =
a1193be8 4267 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
9946ecfb
JM
4268 }
4269
a1193be8 4270 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
8860020e 4271 bcn->assocresp_ies =
a1193be8 4272 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
8860020e 4273 bcn->assocresp_ies_len =
a1193be8 4274 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
9946ecfb
JM
4275 }
4276
a1193be8
SW
4277 if (attrs[NL80211_ATTR_PROBE_RESP]) {
4278 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
4279 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
00f740e1
AN
4280 }
4281
81e54d08
PKC
4282 if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
4283 struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
4284
8cb08174
JB
4285 err = nla_parse_nested_deprecated(tb,
4286 NL80211_FTM_RESP_ATTR_MAX,
4287 attrs[NL80211_ATTR_FTM_RESPONDER],
4288 NULL, NULL);
81e54d08
PKC
4289 if (err)
4290 return err;
4291
4292 if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
4293 wiphy_ext_feature_isset(&rdev->wiphy,
4294 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
4295 bcn->ftm_responder = 1;
4296 else
4297 return -EOPNOTSUPP;
4298
4299 if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
4300 bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
4301 bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
4302 }
4303
4304 if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
4305 bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
4306 bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
4307 }
4308 } else {
4309 bcn->ftm_responder = -1;
4310 }
4311
8860020e
JB
4312 return 0;
4313}
4314
66cd794e
JB
4315static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
4316 const u8 *rates)
4317{
4318 int i;
4319
4320 if (!rates)
4321 return;
4322
4323 for (i = 0; i < rates[1]; i++) {
4324 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
4325 params->ht_required = true;
4326 if (rates[2 + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
4327 params->vht_required = true;
4328 }
4329}
4330
4331/*
4332 * Since the nl80211 API didn't include, from the beginning, attributes about
4333 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
4334 * benefit of drivers that rebuild IEs in the firmware.
4335 */
4336static void nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
4337{
4338 const struct cfg80211_beacon_data *bcn = &params->beacon;
ba83bfb1
IM
4339 size_t ies_len = bcn->tail_len;
4340 const u8 *ies = bcn->tail;
66cd794e
JB
4341 const u8 *rates;
4342 const u8 *cap;
4343
4344 rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
4345 nl80211_check_ap_rate_selectors(params, rates);
4346
4347 rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
4348 nl80211_check_ap_rate_selectors(params, rates);
4349
4350 cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
4351 if (cap && cap[1] >= sizeof(*params->ht_cap))
4352 params->ht_cap = (void *)(cap + 2);
4353 cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
4354 if (cap && cap[1] >= sizeof(*params->vht_cap))
4355 params->vht_cap = (void *)(cap + 2);
244eb9ae
ST
4356 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
4357 if (cap && cap[1] >= sizeof(*params->he_cap) + 1)
4358 params->he_cap = (void *)(cap + 3);
66cd794e
JB
4359}
4360
46c1dd0c
FF
4361static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
4362 struct cfg80211_ap_settings *params)
4363{
4364 struct wireless_dev *wdev;
4365 bool ret = false;
4366
53873f13 4367 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
46c1dd0c
FF
4368 if (wdev->iftype != NL80211_IFTYPE_AP &&
4369 wdev->iftype != NL80211_IFTYPE_P2P_GO)
4370 continue;
4371
683b6d3b 4372 if (!wdev->preset_chandef.chan)
46c1dd0c
FF
4373 continue;
4374
683b6d3b 4375 params->chandef = wdev->preset_chandef;
46c1dd0c
FF
4376 ret = true;
4377 break;
4378 }
4379
46c1dd0c
FF
4380 return ret;
4381}
4382
e39e5b5e
JM
4383static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
4384 enum nl80211_auth_type auth_type,
4385 enum nl80211_commands cmd)
4386{
4387 if (auth_type > NL80211_AUTHTYPE_MAX)
4388 return false;
4389
4390 switch (cmd) {
4391 case NL80211_CMD_AUTHENTICATE:
4392 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
4393 auth_type == NL80211_AUTHTYPE_SAE)
4394 return false;
63181060
JM
4395 if (!wiphy_ext_feature_isset(&rdev->wiphy,
4396 NL80211_EXT_FEATURE_FILS_STA) &&
4397 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
4398 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4399 auth_type == NL80211_AUTHTYPE_FILS_PK))
4400 return false;
e39e5b5e
JM
4401 return true;
4402 case NL80211_CMD_CONNECT:
10773a7c
SD
4403 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
4404 auth_type == NL80211_AUTHTYPE_SAE)
a3caf744 4405 return false;
10773a7c 4406
a3caf744
VK
4407 /* FILS with SK PFS or PK not supported yet */
4408 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4409 auth_type == NL80211_AUTHTYPE_FILS_PK)
4410 return false;
4411 if (!wiphy_ext_feature_isset(
4412 &rdev->wiphy,
4413 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
4414 auth_type == NL80211_AUTHTYPE_FILS_SK)
4415 return false;
4416 return true;
e39e5b5e
JM
4417 case NL80211_CMD_START_AP:
4418 /* SAE not supported yet */
4419 if (auth_type == NL80211_AUTHTYPE_SAE)
4420 return false;
63181060
JM
4421 /* FILS not supported yet */
4422 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
4423 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
4424 auth_type == NL80211_AUTHTYPE_FILS_PK)
4425 return false;
e39e5b5e
JM
4426 return true;
4427 default:
4428 return false;
4429 }
4430}
4431
8860020e
JB
4432static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
4433{
4434 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4435 struct net_device *dev = info->user_ptr[1];
4436 struct wireless_dev *wdev = dev->ieee80211_ptr;
4437 struct cfg80211_ap_settings params;
4438 int err;
4439
4440 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4441 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4442 return -EOPNOTSUPP;
4443
4444 if (!rdev->ops->start_ap)
4445 return -EOPNOTSUPP;
4446
4447 if (wdev->beacon_interval)
4448 return -EALREADY;
4449
4450 memset(&params, 0, sizeof(params));
4451
4452 /* these are required for START_AP */
4453 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
4454 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
4455 !info->attrs[NL80211_ATTR_BEACON_HEAD])
4456 return -EINVAL;
4457
81e54d08 4458 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon);
8860020e
JB
4459 if (err)
4460 return err;
4461
4462 params.beacon_interval =
4463 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
4464 params.dtim_period =
4465 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
4466
0c317a02
PK
4467 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
4468 params.beacon_interval);
8860020e
JB
4469 if (err)
4470 return err;
4471
4472 /*
4473 * In theory, some of these attributes should be required here
4474 * but since they were not used when the command was originally
4475 * added, keep them optional for old user space programs to let
4476 * them continue to work with drivers that do not need the
4477 * additional information -- drivers must check!
4478 */
4479 if (info->attrs[NL80211_ATTR_SSID]) {
4480 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
4481 params.ssid_len =
4482 nla_len(info->attrs[NL80211_ATTR_SSID]);
4483 if (params.ssid_len == 0 ||
4484 params.ssid_len > IEEE80211_MAX_SSID_LEN)
4485 return -EINVAL;
4486 }
4487
ab0d76f6 4488 if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
8860020e
JB
4489 params.hidden_ssid = nla_get_u32(
4490 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
8860020e
JB
4491
4492 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
4493
4494 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
4495 params.auth_type = nla_get_u32(
4496 info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
4497 if (!nl80211_valid_auth_type(rdev, params.auth_type,
4498 NL80211_CMD_START_AP))
8860020e
JB
4499 return -EINVAL;
4500 } else
4501 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
4502
4503 err = nl80211_crypto_settings(rdev, info, &params.crypto,
4504 NL80211_MAX_NR_CIPHER_SUITES);
4505 if (err)
4506 return err;
4507
1b658f11
VT
4508 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
4509 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER))
4510 return -EOPNOTSUPP;
4511 params.inactivity_timeout = nla_get_u16(
4512 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
4513 }
4514
53cabad7
JB
4515 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
4516 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4517 return -EINVAL;
4518 params.p2p_ctwindow =
4519 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
4520 if (params.p2p_ctwindow != 0 &&
4521 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
4522 return -EINVAL;
4523 }
4524
4525 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
4526 u8 tmp;
4527
4528 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4529 return -EINVAL;
4530 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
4531 params.p2p_opp_ps = tmp;
4532 if (params.p2p_opp_ps != 0 &&
4533 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
4534 return -EINVAL;
4535 }
4536
aa430da4 4537 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
4538 err = nl80211_parse_chandef(rdev, info, &params.chandef);
4539 if (err)
4540 return err;
4541 } else if (wdev->preset_chandef.chan) {
4542 params.chandef = wdev->preset_chandef;
46c1dd0c 4543 } else if (!nl80211_get_ap_channel(rdev, &params))
aa430da4
JB
4544 return -EINVAL;
4545
923b352f
AN
4546 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
4547 wdev->iftype))
aa430da4
JB
4548 return -EINVAL;
4549
a7c7fbff
PK
4550 if (info->attrs[NL80211_ATTR_TX_RATES]) {
4551 err = nl80211_parse_tx_bitrate_mask(info, &params.beacon_rate);
4552 if (err)
4553 return err;
4554
8564e382
JB
4555 err = validate_beacon_tx_rate(rdev, params.chandef.chan->band,
4556 &params.beacon_rate);
a7c7fbff
PK
4557 if (err)
4558 return err;
4559 }
4560
18998c38
EP
4561 if (info->attrs[NL80211_ATTR_SMPS_MODE]) {
4562 params.smps_mode =
4563 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]);
4564 switch (params.smps_mode) {
4565 case NL80211_SMPS_OFF:
4566 break;
4567 case NL80211_SMPS_STATIC:
4568 if (!(rdev->wiphy.features &
4569 NL80211_FEATURE_STATIC_SMPS))
4570 return -EINVAL;
4571 break;
4572 case NL80211_SMPS_DYNAMIC:
4573 if (!(rdev->wiphy.features &
4574 NL80211_FEATURE_DYNAMIC_SMPS))
4575 return -EINVAL;
4576 break;
4577 default:
4578 return -EINVAL;
4579 }
4580 } else {
4581 params.smps_mode = NL80211_SMPS_OFF;
4582 }
4583
6e8ef842
PK
4584 params.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
4585 if (params.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ])
4586 return -EOPNOTSUPP;
4587
4baf6bea
OO
4588 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
4589 params.acl = parse_acl_data(&rdev->wiphy, info);
4590 if (IS_ERR(params.acl))
4591 return PTR_ERR(params.acl);
4592 }
4593
66cd794e
JB
4594 nl80211_calculate_ap_params(&params);
4595
fe494370
SD
4596 if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
4597 params.flags |= AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
4598
c56589ed 4599 wdev_lock(wdev);
e35e4d28 4600 err = rdev_start_ap(rdev, dev, &params);
46c1dd0c 4601 if (!err) {
683b6d3b 4602 wdev->preset_chandef = params.chandef;
8860020e 4603 wdev->beacon_interval = params.beacon_interval;
9e0e2961 4604 wdev->chandef = params.chandef;
06e191e2
AQ
4605 wdev->ssid_len = params.ssid_len;
4606 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
466a3061
DK
4607
4608 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
4609 wdev->conn_owner_nlportid = info->snd_portid;
46c1dd0c 4610 }
c56589ed 4611 wdev_unlock(wdev);
77765eaf
VT
4612
4613 kfree(params.acl);
4614
56d1893d 4615 return err;
ed1b6cc7
JB
4616}
4617
8860020e
JB
4618static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
4619{
4620 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4621 struct net_device *dev = info->user_ptr[1];
4622 struct wireless_dev *wdev = dev->ieee80211_ptr;
4623 struct cfg80211_beacon_data params;
4624 int err;
4625
4626 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4627 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
4628 return -EOPNOTSUPP;
4629
4630 if (!rdev->ops->change_beacon)
4631 return -EOPNOTSUPP;
4632
4633 if (!wdev->beacon_interval)
4634 return -EINVAL;
4635
81e54d08 4636 err = nl80211_parse_beacon(rdev, info->attrs, &params);
8860020e
JB
4637 if (err)
4638 return err;
4639
c56589ed
SW
4640 wdev_lock(wdev);
4641 err = rdev_change_beacon(rdev, dev, &params);
4642 wdev_unlock(wdev);
4643
4644 return err;
8860020e
JB
4645}
4646
4647static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
ed1b6cc7 4648{
4c476991
JB
4649 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4650 struct net_device *dev = info->user_ptr[1];
ed1b6cc7 4651
7c8d5e03 4652 return cfg80211_stop_ap(rdev, dev, false);
ed1b6cc7
JB
4653}
4654
5727ef1b
JB
4655static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
4656 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
4657 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
4658 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
0e46724a 4659 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
b39c48fa 4660 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
d83023da 4661 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
5727ef1b
JB
4662};
4663
eccb8e8f 4664static int parse_station_flags(struct genl_info *info,
bdd3ae3d 4665 enum nl80211_iftype iftype,
eccb8e8f 4666 struct station_parameters *params)
5727ef1b
JB
4667{
4668 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
eccb8e8f 4669 struct nlattr *nla;
5727ef1b
JB
4670 int flag;
4671
eccb8e8f
JB
4672 /*
4673 * Try parsing the new attribute first so userspace
4674 * can specify both for older kernels.
4675 */
4676 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
4677 if (nla) {
4678 struct nl80211_sta_flag_update *sta_flags;
4679
4680 sta_flags = nla_data(nla);
4681 params->sta_flags_mask = sta_flags->mask;
4682 params->sta_flags_set = sta_flags->set;
77ee7c89 4683 params->sta_flags_set &= params->sta_flags_mask;
eccb8e8f
JB
4684 if ((params->sta_flags_mask |
4685 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
4686 return -EINVAL;
4687 return 0;
4688 }
4689
4690 /* if present, parse the old attribute */
5727ef1b 4691
eccb8e8f 4692 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
5727ef1b
JB
4693 if (!nla)
4694 return 0;
4695
8cb08174 4696 if (nla_parse_nested_deprecated(flags, NL80211_STA_FLAG_MAX, nla, sta_flags_policy, info->extack))
5727ef1b
JB
4697 return -EINVAL;
4698
bdd3ae3d
JB
4699 /*
4700 * Only allow certain flags for interface types so that
4701 * other attributes are silently ignored. Remember that
4702 * this is backward compatibility code with old userspace
4703 * and shouldn't be hit in other cases anyway.
4704 */
4705 switch (iftype) {
4706 case NL80211_IFTYPE_AP:
4707 case NL80211_IFTYPE_AP_VLAN:
4708 case NL80211_IFTYPE_P2P_GO:
4709 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4710 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
4711 BIT(NL80211_STA_FLAG_WME) |
4712 BIT(NL80211_STA_FLAG_MFP);
4713 break;
4714 case NL80211_IFTYPE_P2P_CLIENT:
4715 case NL80211_IFTYPE_STATION:
4716 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
4717 BIT(NL80211_STA_FLAG_TDLS_PEER);
4718 break;
4719 case NL80211_IFTYPE_MESH_POINT:
4720 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
4721 BIT(NL80211_STA_FLAG_MFP) |
4722 BIT(NL80211_STA_FLAG_AUTHORIZED);
5cf3006c 4723 break;
bdd3ae3d
JB
4724 default:
4725 return -EINVAL;
4726 }
5727ef1b 4727
3383b5a6
JB
4728 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
4729 if (flags[flag]) {
eccb8e8f 4730 params->sta_flags_set |= (1<<flag);
5727ef1b 4731
3383b5a6
JB
4732 /* no longer support new API additions in old API */
4733 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
4734 return -EINVAL;
4735 }
4736 }
4737
5727ef1b
JB
4738 return 0;
4739}
4740
9bb7e0f2 4741bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
c8dcfd8a
FF
4742{
4743 struct nlattr *rate;
8eb41c8d
VK
4744 u32 bitrate;
4745 u16 bitrate_compat;
bbf67e45 4746 enum nl80211_rate_info rate_flg;
c8dcfd8a 4747
ae0be8de 4748 rate = nla_nest_start_noflag(msg, attr);
c8dcfd8a 4749 if (!rate)
db9c64cf 4750 return false;
c8dcfd8a
FF
4751
4752 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
4753 bitrate = cfg80211_calculate_bitrate(info);
8eb41c8d
VK
4754 /* report 16-bit bitrate only if we can */
4755 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
db9c64cf
JB
4756 if (bitrate > 0 &&
4757 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
4758 return false;
4759 if (bitrate_compat > 0 &&
4760 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
4761 return false;
4762
b51f3bee
JB
4763 switch (info->bw) {
4764 case RATE_INFO_BW_5:
4765 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
4766 break;
4767 case RATE_INFO_BW_10:
4768 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
4769 break;
4770 default:
4771 WARN_ON(1);
4772 /* fall through */
4773 case RATE_INFO_BW_20:
4774 rate_flg = 0;
4775 break;
4776 case RATE_INFO_BW_40:
4777 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
4778 break;
4779 case RATE_INFO_BW_80:
4780 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
4781 break;
4782 case RATE_INFO_BW_160:
4783 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
4784 break;
c4cbaf79
LC
4785 case RATE_INFO_BW_HE_RU:
4786 rate_flg = 0;
4787 WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
b51f3bee
JB
4788 }
4789
4790 if (rate_flg && nla_put_flag(msg, rate_flg))
4791 return false;
4792
db9c64cf
JB
4793 if (info->flags & RATE_INFO_FLAGS_MCS) {
4794 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
4795 return false;
db9c64cf
JB
4796 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4797 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4798 return false;
4799 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
4800 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
4801 return false;
4802 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
4803 return false;
db9c64cf
JB
4804 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
4805 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
4806 return false;
c4cbaf79
LC
4807 } else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
4808 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
4809 return false;
4810 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
4811 return false;
4812 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
4813 return false;
4814 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
4815 return false;
4816 if (info->bw == RATE_INFO_BW_HE_RU &&
4817 nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
4818 info->he_ru_alloc))
4819 return false;
db9c64cf 4820 }
c8dcfd8a
FF
4821
4822 nla_nest_end(msg, rate);
4823 return true;
c8dcfd8a
FF
4824}
4825
119363c7
FF
4826static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
4827 int id)
4828{
4829 void *attr;
4830 int i = 0;
4831
4832 if (!mask)
4833 return true;
4834
ae0be8de 4835 attr = nla_nest_start_noflag(msg, id);
119363c7
FF
4836 if (!attr)
4837 return false;
4838
4839 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
4840 if (!(mask & BIT(i)))
4841 continue;
4842
4843 if (nla_put_u8(msg, i, signal[i]))
4844 return false;
4845 }
4846
4847 nla_nest_end(msg, attr);
4848
4849 return true;
4850}
4851
cf5ead82
JB
4852static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
4853 u32 seq, int flags,
66266b3a
JL
4854 struct cfg80211_registered_device *rdev,
4855 struct net_device *dev,
98b62183 4856 const u8 *mac_addr, struct station_info *sinfo)
fd5b74dc
JB
4857{
4858 void *hdr;
f4263c98 4859 struct nlattr *sinfoattr, *bss_param;
fd5b74dc 4860
cf5ead82 4861 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
f77bf486
AS
4862 if (!hdr) {
4863 cfg80211_sinfo_release_content(sinfo);
fd5b74dc 4864 return -1;
f77bf486 4865 }
fd5b74dc 4866
9360ffd1
DM
4867 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4868 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
4869 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
4870 goto nla_put_failure;
f5ea9120 4871
ae0be8de 4872 sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
2ec600d6 4873 if (!sinfoattr)
fd5b74dc 4874 goto nla_put_failure;
319090bf
JB
4875
4876#define PUT_SINFO(attr, memb, type) do { \
d686b920 4877 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
397c657a 4878 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
319090bf
JB
4879 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
4880 sinfo->memb)) \
4881 goto nla_put_failure; \
4882 } while (0)
d686b920 4883#define PUT_SINFO_U64(attr, memb) do { \
397c657a 4884 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
d686b920
JB
4885 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
4886 sinfo->memb, NL80211_STA_INFO_PAD)) \
4887 goto nla_put_failure; \
4888 } while (0)
319090bf
JB
4889
4890 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
4891 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
4892
397c657a
OE
4893 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
4894 BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
9360ffd1 4895 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
42745e03 4896 (u32)sinfo->rx_bytes))
9360ffd1 4897 goto nla_put_failure;
319090bf 4898
397c657a
OE
4899 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
4900 BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
9360ffd1 4901 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
42745e03
VK
4902 (u32)sinfo->tx_bytes))
4903 goto nla_put_failure;
319090bf 4904
d686b920
JB
4905 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
4906 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
319090bf
JB
4907 PUT_SINFO(LLID, llid, u16);
4908 PUT_SINFO(PLID, plid, u16);
4909 PUT_SINFO(PLINK_STATE, plink_state, u8);
d686b920 4910 PUT_SINFO_U64(RX_DURATION, rx_duration);
36647055
THJ
4911 PUT_SINFO_U64(TX_DURATION, tx_duration);
4912
4913 if (wiphy_ext_feature_isset(&rdev->wiphy,
4914 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
4915 PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
319090bf 4916
66266b3a
JL
4917 switch (rdev->wiphy.signal_type) {
4918 case CFG80211_SIGNAL_TYPE_MBM:
319090bf
JB
4919 PUT_SINFO(SIGNAL, signal, u8);
4920 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
66266b3a
JL
4921 break;
4922 default:
4923 break;
4924 }
397c657a 4925 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
119363c7
FF
4926 if (!nl80211_put_signal(msg, sinfo->chains,
4927 sinfo->chain_signal,
4928 NL80211_STA_INFO_CHAIN_SIGNAL))
4929 goto nla_put_failure;
4930 }
397c657a 4931 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
119363c7
FF
4932 if (!nl80211_put_signal(msg, sinfo->chains,
4933 sinfo->chain_signal_avg,
4934 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
4935 goto nla_put_failure;
4936 }
397c657a 4937 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
c8dcfd8a
FF
4938 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
4939 NL80211_STA_INFO_TX_BITRATE))
4940 goto nla_put_failure;
4941 }
397c657a 4942 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
c8dcfd8a
FF
4943 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
4944 NL80211_STA_INFO_RX_BITRATE))
420e7fab 4945 goto nla_put_failure;
420e7fab 4946 }
319090bf
JB
4947
4948 PUT_SINFO(RX_PACKETS, rx_packets, u32);
4949 PUT_SINFO(TX_PACKETS, tx_packets, u32);
4950 PUT_SINFO(TX_RETRIES, tx_retries, u32);
4951 PUT_SINFO(TX_FAILED, tx_failed, u32);
4952 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
ab60633c 4953 PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
319090bf
JB
4954 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
4955 PUT_SINFO(LOCAL_PM, local_pm, u32);
4956 PUT_SINFO(PEER_PM, peer_pm, u32);
4957 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
dbdaee7a 4958 PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
319090bf 4959
397c657a 4960 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
ae0be8de
MK
4961 bss_param = nla_nest_start_noflag(msg,
4962 NL80211_STA_INFO_BSS_PARAM);
f4263c98
PS
4963 if (!bss_param)
4964 goto nla_put_failure;
4965
9360ffd1
DM
4966 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
4967 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
4968 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
4969 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
4970 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
4971 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
4972 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
4973 sinfo->bss_param.dtim_period) ||
4974 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
4975 sinfo->bss_param.beacon_interval))
4976 goto nla_put_failure;
f4263c98
PS
4977
4978 nla_nest_end(msg, bss_param);
4979 }
397c657a 4980 if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
9360ffd1
DM
4981 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
4982 sizeof(struct nl80211_sta_flag_update),
4983 &sinfo->sta_flags))
4984 goto nla_put_failure;
319090bf 4985
d686b920
JB
4986 PUT_SINFO_U64(T_OFFSET, t_offset);
4987 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
4988 PUT_SINFO_U64(BEACON_RX, rx_beacon);
a76b1942 4989 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
0d4e14a3
AB
4990 PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
4991 PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
81d5439d 4992 if (wiphy_ext_feature_isset(&rdev->wiphy,
9c06602b
BP
4993 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
4994 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
4995 PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
4996 }
319090bf
JB
4997
4998#undef PUT_SINFO
d686b920 4999#undef PUT_SINFO_U64
6de39808 5000
8689c051 5001 if (sinfo->pertid) {
6de39808
JB
5002 struct nlattr *tidsattr;
5003 int tid;
5004
ae0be8de
MK
5005 tidsattr = nla_nest_start_noflag(msg,
5006 NL80211_STA_INFO_TID_STATS);
6de39808
JB
5007 if (!tidsattr)
5008 goto nla_put_failure;
5009
5010 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
5011 struct cfg80211_tid_stats *tidstats;
5012 struct nlattr *tidattr;
5013
5014 tidstats = &sinfo->pertid[tid];
5015
5016 if (!tidstats->filled)
5017 continue;
5018
ae0be8de 5019 tidattr = nla_nest_start_noflag(msg, tid + 1);
6de39808
JB
5020 if (!tidattr)
5021 goto nla_put_failure;
5022
d686b920 5023#define PUT_TIDVAL_U64(attr, memb) do { \
6de39808 5024 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
d686b920
JB
5025 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
5026 tidstats->memb, NL80211_TID_STATS_PAD)) \
6de39808
JB
5027 goto nla_put_failure; \
5028 } while (0)
5029
d686b920
JB
5030 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
5031 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
5032 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
5033 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6de39808 5034
d686b920 5035#undef PUT_TIDVAL_U64
52539ca8
THJ
5036 if ((tidstats->filled &
5037 BIT(NL80211_TID_STATS_TXQ_STATS)) &&
5038 !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
5039 NL80211_TID_STATS_TXQ_STATS))
5040 goto nla_put_failure;
5041
6de39808
JB
5042 nla_nest_end(msg, tidattr);
5043 }
5044
5045 nla_nest_end(msg, tidsattr);
5046 }
5047
2ec600d6 5048 nla_nest_end(msg, sinfoattr);
fd5b74dc 5049
319090bf 5050 if (sinfo->assoc_req_ies_len &&
9360ffd1
DM
5051 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
5052 sinfo->assoc_req_ies))
5053 goto nla_put_failure;
50d3dfb7 5054
7ea3e110 5055 cfg80211_sinfo_release_content(sinfo);
053c095a
JB
5056 genlmsg_end(msg, hdr);
5057 return 0;
fd5b74dc
JB
5058
5059 nla_put_failure:
7ea3e110 5060 cfg80211_sinfo_release_content(sinfo);
bc3ed28c
TG
5061 genlmsg_cancel(msg, hdr);
5062 return -EMSGSIZE;
fd5b74dc
JB
5063}
5064
2ec600d6 5065static int nl80211_dump_station(struct sk_buff *skb,
bba95fef 5066 struct netlink_callback *cb)
2ec600d6 5067{
73887fd9 5068 struct station_info sinfo;
1b8ec87a 5069 struct cfg80211_registered_device *rdev;
97990a06 5070 struct wireless_dev *wdev;
2ec600d6 5071 u8 mac_addr[ETH_ALEN];
97990a06 5072 int sta_idx = cb->args[2];
2ec600d6 5073 int err;
2ec600d6 5074
ea90e0dc 5075 rtnl_lock();
5297c65c 5076 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 5077 if (err)
ea90e0dc 5078 goto out_err;
bba95fef 5079
97990a06
JB
5080 if (!wdev->netdev) {
5081 err = -EINVAL;
5082 goto out_err;
5083 }
5084
1b8ec87a 5085 if (!rdev->ops->dump_station) {
eec60b03 5086 err = -EOPNOTSUPP;
bba95fef
JB
5087 goto out_err;
5088 }
5089
bba95fef 5090 while (1) {
73887fd9 5091 memset(&sinfo, 0, sizeof(sinfo));
1b8ec87a 5092 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
73887fd9 5093 mac_addr, &sinfo);
bba95fef
JB
5094 if (err == -ENOENT)
5095 break;
5096 if (err)
3b85875a 5097 goto out_err;
bba95fef 5098
cf5ead82 5099 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
15e47304 5100 NETLINK_CB(cb->skb).portid,
bba95fef 5101 cb->nlh->nlmsg_seq, NLM_F_MULTI,
1b8ec87a 5102 rdev, wdev->netdev, mac_addr,
73887fd9 5103 &sinfo) < 0)
bba95fef
JB
5104 goto out;
5105
5106 sta_idx++;
5107 }
5108
bba95fef 5109 out:
97990a06 5110 cb->args[2] = sta_idx;
bba95fef 5111 err = skb->len;
bba95fef 5112 out_err:
ea90e0dc 5113 rtnl_unlock();
bba95fef
JB
5114
5115 return err;
2ec600d6 5116}
fd5b74dc 5117
5727ef1b
JB
5118static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
5119{
4c476991
JB
5120 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5121 struct net_device *dev = info->user_ptr[1];
73887fd9 5122 struct station_info sinfo;
fd5b74dc
JB
5123 struct sk_buff *msg;
5124 u8 *mac_addr = NULL;
4c476991 5125 int err;
fd5b74dc 5126
73887fd9 5127 memset(&sinfo, 0, sizeof(sinfo));
fd5b74dc 5128
73887fd9
JB
5129 if (!info->attrs[NL80211_ATTR_MAC])
5130 return -EINVAL;
fd5b74dc
JB
5131
5132 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5133
73887fd9
JB
5134 if (!rdev->ops->get_station)
5135 return -EOPNOTSUPP;
3b85875a 5136
73887fd9 5137 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
fd5b74dc 5138 if (err)
73887fd9 5139 return err;
2ec600d6 5140
fd2120ca 5141 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7ea3e110 5142 if (!msg) {
ba8f566a 5143 cfg80211_sinfo_release_content(&sinfo);
73887fd9 5144 return -ENOMEM;
7ea3e110 5145 }
fd5b74dc 5146
cf5ead82
JB
5147 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
5148 info->snd_portid, info->snd_seq, 0,
73887fd9 5149 rdev, dev, mac_addr, &sinfo) < 0) {
4c476991 5150 nlmsg_free(msg);
73887fd9 5151 return -ENOBUFS;
4c476991 5152 }
3b85875a 5153
73887fd9 5154 return genlmsg_reply(msg, info);
5727ef1b
JB
5155}
5156
77ee7c89
JB
5157int cfg80211_check_station_change(struct wiphy *wiphy,
5158 struct station_parameters *params,
5159 enum cfg80211_station_type statype)
5160{
e4208427
AB
5161 if (params->listen_interval != -1 &&
5162 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89 5163 return -EINVAL;
e4208427 5164
17b94247
AB
5165 if (params->support_p2p_ps != -1 &&
5166 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
5167 return -EINVAL;
5168
c72e1140 5169 if (params->aid &&
e4208427
AB
5170 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
5171 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
77ee7c89
JB
5172 return -EINVAL;
5173
5174 /* When you run into this, adjust the code below for the new flag */
5175 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
5176
5177 switch (statype) {
eef941e6
TP
5178 case CFG80211_STA_MESH_PEER_KERNEL:
5179 case CFG80211_STA_MESH_PEER_USER:
77ee7c89
JB
5180 /*
5181 * No ignoring the TDLS flag here -- the userspace mesh
5182 * code doesn't have the bug of including TDLS in the
5183 * mask everywhere.
5184 */
5185 if (params->sta_flags_mask &
5186 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5187 BIT(NL80211_STA_FLAG_MFP) |
5188 BIT(NL80211_STA_FLAG_AUTHORIZED)))
5189 return -EINVAL;
5190 break;
5191 case CFG80211_STA_TDLS_PEER_SETUP:
5192 case CFG80211_STA_TDLS_PEER_ACTIVE:
5193 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5194 return -EINVAL;
5195 /* ignore since it can't change */
5196 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
5197 break;
5198 default:
5199 /* disallow mesh-specific things */
5200 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
5201 return -EINVAL;
5202 if (params->local_pm)
5203 return -EINVAL;
5204 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5205 return -EINVAL;
5206 }
5207
5208 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
5209 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
5210 /* TDLS can't be set, ... */
5211 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
5212 return -EINVAL;
5213 /*
5214 * ... but don't bother the driver with it. This works around
5215 * a hostapd/wpa_supplicant issue -- it always includes the
5216 * TLDS_PEER flag in the mask even for AP mode.
5217 */
5218 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
5219 }
5220
47edb11b
AB
5221 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
5222 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
5223 /* reject other things that can't change */
5224 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
5225 return -EINVAL;
5226 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
5227 return -EINVAL;
5228 if (params->supported_rates)
5229 return -EINVAL;
c4cbaf79
LC
5230 if (params->ext_capab || params->ht_capa || params->vht_capa ||
5231 params->he_capa)
77ee7c89
JB
5232 return -EINVAL;
5233 }
5234
47edb11b
AB
5235 if (statype != CFG80211_STA_AP_CLIENT &&
5236 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
77ee7c89
JB
5237 if (params->vlan)
5238 return -EINVAL;
5239 }
5240
5241 switch (statype) {
5242 case CFG80211_STA_AP_MLME_CLIENT:
5243 /* Use this only for authorizing/unauthorizing a station */
5244 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
5245 return -EOPNOTSUPP;
5246 break;
5247 case CFG80211_STA_AP_CLIENT:
47edb11b 5248 case CFG80211_STA_AP_CLIENT_UNASSOC:
77ee7c89
JB
5249 /* accept only the listed bits */
5250 if (params->sta_flags_mask &
5251 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
5252 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5253 BIT(NL80211_STA_FLAG_ASSOCIATED) |
5254 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
5255 BIT(NL80211_STA_FLAG_WME) |
5256 BIT(NL80211_STA_FLAG_MFP)))
5257 return -EINVAL;
5258
5259 /* but authenticated/associated only if driver handles it */
5260 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
5261 params->sta_flags_mask &
5262 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5263 BIT(NL80211_STA_FLAG_ASSOCIATED)))
5264 return -EINVAL;
5265 break;
5266 case CFG80211_STA_IBSS:
5267 case CFG80211_STA_AP_STA:
5268 /* reject any changes other than AUTHORIZED */
5269 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
5270 return -EINVAL;
5271 break;
5272 case CFG80211_STA_TDLS_PEER_SETUP:
5273 /* reject any changes other than AUTHORIZED or WME */
5274 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
5275 BIT(NL80211_STA_FLAG_WME)))
5276 return -EINVAL;
5277 /* force (at least) rates when authorizing */
5278 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
5279 !params->supported_rates)
5280 return -EINVAL;
5281 break;
5282 case CFG80211_STA_TDLS_PEER_ACTIVE:
5283 /* reject any changes */
5284 return -EINVAL;
eef941e6 5285 case CFG80211_STA_MESH_PEER_KERNEL:
77ee7c89
JB
5286 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5287 return -EINVAL;
5288 break;
eef941e6 5289 case CFG80211_STA_MESH_PEER_USER:
42925040
CYY
5290 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
5291 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
77ee7c89
JB
5292 return -EINVAL;
5293 break;
5294 }
5295
06f7c88c
BL
5296 /*
5297 * Older kernel versions ignored this attribute entirely, so don't
5298 * reject attempts to update it but mark it as unused instead so the
5299 * driver won't look at the data.
5300 */
5301 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
5302 statype != CFG80211_STA_TDLS_PEER_SETUP)
5303 params->opmode_notif_used = false;
5304
77ee7c89
JB
5305 return 0;
5306}
5307EXPORT_SYMBOL(cfg80211_check_station_change);
5308
5727ef1b 5309/*
c258d2de 5310 * Get vlan interface making sure it is running and on the right wiphy.
5727ef1b 5311 */
80b99899
JB
5312static struct net_device *get_vlan(struct genl_info *info,
5313 struct cfg80211_registered_device *rdev)
5727ef1b 5314{
463d0183 5315 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
80b99899
JB
5316 struct net_device *v;
5317 int ret;
5318
5319 if (!vlanattr)
5320 return NULL;
5321
5322 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
5323 if (!v)
5324 return ERR_PTR(-ENODEV);
5325
5326 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
5327 ret = -EINVAL;
5328 goto error;
5727ef1b 5329 }
80b99899 5330
77ee7c89
JB
5331 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
5332 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5333 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
5334 ret = -EINVAL;
5335 goto error;
5336 }
5337
80b99899
JB
5338 if (!netif_running(v)) {
5339 ret = -ENETDOWN;
5340 goto error;
5341 }
5342
5343 return v;
5344 error:
5345 dev_put(v);
5346 return ERR_PTR(ret);
5727ef1b
JB
5347}
5348
94e860f1
JB
5349static const struct nla_policy
5350nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
df881293
JM
5351 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
5352 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
5353};
5354
ff276691
JB
5355static int nl80211_parse_sta_wme(struct genl_info *info,
5356 struct station_parameters *params)
df881293 5357{
df881293
JM
5358 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
5359 struct nlattr *nla;
5360 int err;
5361
df881293
JM
5362 /* parse WME attributes if present */
5363 if (!info->attrs[NL80211_ATTR_STA_WME])
5364 return 0;
5365
5366 nla = info->attrs[NL80211_ATTR_STA_WME];
8cb08174
JB
5367 err = nla_parse_nested_deprecated(tb, NL80211_STA_WME_MAX, nla,
5368 nl80211_sta_wme_policy,
5369 info->extack);
df881293
JM
5370 if (err)
5371 return err;
5372
5373 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
5374 params->uapsd_queues = nla_get_u8(
5375 tb[NL80211_STA_WME_UAPSD_QUEUES]);
5376 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
5377 return -EINVAL;
5378
5379 if (tb[NL80211_STA_WME_MAX_SP])
5380 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
5381
5382 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
5383 return -EINVAL;
5384
5385 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
5386
5387 return 0;
5388}
5389
c01fc9ad
SD
5390static int nl80211_parse_sta_channel_info(struct genl_info *info,
5391 struct station_parameters *params)
5392{
5393 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
5394 params->supported_channels =
5395 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
5396 params->supported_channels_len =
5397 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
5398 /*
5399 * Need to include at least one (first channel, number of
5400 * channels) tuple for each subband, and must have proper
5401 * tuples for the rest of the data as well.
5402 */
5403 if (params->supported_channels_len < 2)
5404 return -EINVAL;
5405 if (params->supported_channels_len % 2)
5406 return -EINVAL;
5407 }
5408
5409 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
5410 params->supported_oper_classes =
5411 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
5412 params->supported_oper_classes_len =
5413 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
5414 /*
5415 * The value of the Length field of the Supported Operating
5416 * Classes element is between 2 and 253.
5417 */
5418 if (params->supported_oper_classes_len < 2 ||
5419 params->supported_oper_classes_len > 253)
5420 return -EINVAL;
5421 }
5422 return 0;
5423}
5424
ff276691
JB
5425static int nl80211_set_station_tdls(struct genl_info *info,
5426 struct station_parameters *params)
5427{
c01fc9ad 5428 int err;
ff276691 5429 /* Dummy STA entry gets updated once the peer capabilities are known */
5e4b6f56
JM
5430 if (info->attrs[NL80211_ATTR_PEER_AID])
5431 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
ff276691
JB
5432 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
5433 params->ht_capa =
5434 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5435 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
5436 params->vht_capa =
5437 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
c4cbaf79
LC
5438 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
5439 params->he_capa =
5440 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5441 params->he_capa_len =
5442 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5443
5444 if (params->he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
5445 return -EINVAL;
5446 }
ff276691 5447
c01fc9ad
SD
5448 err = nl80211_parse_sta_channel_info(info, params);
5449 if (err)
5450 return err;
5451
ff276691
JB
5452 return nl80211_parse_sta_wme(info, params);
5453}
5454
e96d1cd2
ARN
5455static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
5456 struct station_parameters *params)
5457{
5458 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5459 int idx;
5460
5461 if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
5462 if (!rdev->ops->set_tx_power ||
5463 !wiphy_ext_feature_isset(&rdev->wiphy,
5464 NL80211_EXT_FEATURE_STA_TX_PWR))
5465 return -EOPNOTSUPP;
5466
5467 idx = NL80211_ATTR_STA_TX_POWER_SETTING;
5468 params->txpwr.type = nla_get_u8(info->attrs[idx]);
5469
5470 if (params->txpwr.type == NL80211_TX_POWER_LIMITED) {
5471 idx = NL80211_ATTR_STA_TX_POWER;
5472
5473 if (info->attrs[idx])
5474 params->txpwr.power =
5475 nla_get_s16(info->attrs[idx]);
5476 else
5477 return -EINVAL;
5478 }
5479 params->sta_modify_mask |= STATION_PARAM_APPLY_STA_TXPOWER;
5480 }
5481
5482 return 0;
5483}
5484
5727ef1b
JB
5485static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
5486{
4c476991 5487 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 5488 struct net_device *dev = info->user_ptr[1];
5727ef1b 5489 struct station_parameters params;
77ee7c89
JB
5490 u8 *mac_addr;
5491 int err;
5727ef1b
JB
5492
5493 memset(&params, 0, sizeof(params));
5494
77ee7c89
JB
5495 if (!rdev->ops->change_station)
5496 return -EOPNOTSUPP;
5497
e4208427
AB
5498 /*
5499 * AID and listen_interval properties can be set only for unassociated
5500 * station. Include these parameters here and will check them in
5501 * cfg80211_check_station_change().
5502 */
a9bc31e4
AB
5503 if (info->attrs[NL80211_ATTR_STA_AID])
5504 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
e4208427
AB
5505
5506 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
5507 params.listen_interval =
5508 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
5509 else
5510 params.listen_interval = -1;
5727ef1b 5511
ab0d76f6
JB
5512 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
5513 params.support_p2p_ps =
5514 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
5515 else
17b94247 5516 params.support_p2p_ps = -1;
17b94247 5517
5727ef1b
JB
5518 if (!info->attrs[NL80211_ATTR_MAC])
5519 return -EINVAL;
5520
5521 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5522
5523 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
5524 params.supported_rates =
5525 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5526 params.supported_rates_len =
5527 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5528 }
5529
9d62a986
JM
5530 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
5531 params.capability =
5532 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
5533 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
5534 }
5535
5536 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
5537 params.ext_capab =
5538 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5539 params.ext_capab_len =
5540 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5541 }
5542
bdd3ae3d 5543 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
5544 return -EINVAL;
5545
ab0d76f6 5546 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
2ec600d6 5547 params.plink_action =
f8bacc21 5548 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
2ec600d6 5549
f8bacc21 5550 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
9c3990aa 5551 params.plink_state =
f8bacc21 5552 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
ab0d76f6 5553 if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
7d27a0ba
MH
5554 params.peer_aid = nla_get_u16(
5555 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
f8bacc21
JB
5556 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
5557 }
9c3990aa 5558
ab0d76f6
JB
5559 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
5560 params.local_pm = nla_get_u32(
3b1c5a53
MP
5561 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
5562
06f7c88c
BL
5563 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
5564 params.opmode_notif_used = true;
5565 params.opmode_notif =
5566 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
5567 }
5568
36647055
THJ
5569 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
5570 params.airtime_weight =
5571 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
5572
5573 if (params.airtime_weight &&
5574 !wiphy_ext_feature_isset(&rdev->wiphy,
5575 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
5576 return -EOPNOTSUPP;
5577
e96d1cd2
ARN
5578 err = nl80211_parse_sta_txpower_setting(info, &params);
5579 if (err)
5580 return err;
5581
77ee7c89
JB
5582 /* Include parameters for TDLS peer (will check later) */
5583 err = nl80211_set_station_tdls(info, &params);
5584 if (err)
5585 return err;
5586
5587 params.vlan = get_vlan(info, rdev);
5588 if (IS_ERR(params.vlan))
5589 return PTR_ERR(params.vlan);
5590
a97f4424
JB
5591 switch (dev->ieee80211_ptr->iftype) {
5592 case NL80211_IFTYPE_AP:
5593 case NL80211_IFTYPE_AP_VLAN:
074ac8df 5594 case NL80211_IFTYPE_P2P_GO:
074ac8df 5595 case NL80211_IFTYPE_P2P_CLIENT:
a97f4424 5596 case NL80211_IFTYPE_STATION:
267335d6 5597 case NL80211_IFTYPE_ADHOC:
a97f4424 5598 case NL80211_IFTYPE_MESH_POINT:
a97f4424
JB
5599 break;
5600 default:
77ee7c89
JB
5601 err = -EOPNOTSUPP;
5602 goto out_put_vlan;
034d655e
JB
5603 }
5604
77ee7c89 5605 /* driver will call cfg80211_check_station_change() */
e35e4d28 5606 err = rdev_change_station(rdev, dev, mac_addr, &params);
5727ef1b 5607
77ee7c89 5608 out_put_vlan:
5727ef1b
JB
5609 if (params.vlan)
5610 dev_put(params.vlan);
3b85875a 5611
5727ef1b
JB
5612 return err;
5613}
5614
5615static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
5616{
4c476991 5617 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5727ef1b 5618 int err;
4c476991 5619 struct net_device *dev = info->user_ptr[1];
5727ef1b
JB
5620 struct station_parameters params;
5621 u8 *mac_addr = NULL;
bda95eb1
JB
5622 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
5623 BIT(NL80211_STA_FLAG_ASSOCIATED);
5727ef1b
JB
5624
5625 memset(&params, 0, sizeof(params));
5626
984c311b
JB
5627 if (!rdev->ops->add_station)
5628 return -EOPNOTSUPP;
5629
5727ef1b
JB
5630 if (!info->attrs[NL80211_ATTR_MAC])
5631 return -EINVAL;
5632
5727ef1b
JB
5633 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
5634 return -EINVAL;
5635
5636 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
5637 return -EINVAL;
5638
5e4b6f56
JM
5639 if (!info->attrs[NL80211_ATTR_STA_AID] &&
5640 !info->attrs[NL80211_ATTR_PEER_AID])
0e956c13
TLSC
5641 return -EINVAL;
5642
5727ef1b
JB
5643 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
5644 params.supported_rates =
5645 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5646 params.supported_rates_len =
5647 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
5648 params.listen_interval =
5649 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
51b50fbe 5650
17b94247 5651 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
ab0d76f6
JB
5652 params.support_p2p_ps =
5653 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
17b94247
AB
5654 } else {
5655 /*
5656 * if not specified, assume it's supported for P2P GO interface,
5657 * and is NOT supported for AP interface
5658 */
5659 params.support_p2p_ps =
5660 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
5661 }
5662
3d124ea2 5663 if (info->attrs[NL80211_ATTR_PEER_AID])
5e4b6f56 5664 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3d124ea2
JM
5665 else
5666 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
51b50fbe 5667
9d62a986
JM
5668 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
5669 params.capability =
5670 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
5671 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
5672 }
5673
5674 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
5675 params.ext_capab =
5676 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5677 params.ext_capab_len =
5678 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
5679 }
5680
36aedc90
JM
5681 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
5682 params.ht_capa =
5683 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
5727ef1b 5684
f461be3e
MP
5685 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
5686 params.vht_capa =
5687 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
5688
c4cbaf79
LC
5689 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
5690 params.he_capa =
5691 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5692 params.he_capa_len =
5693 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
5694
5695 /* max len is validated in nla policy */
5696 if (params.he_capa_len < NL80211_HE_MIN_CAPABILITY_LEN)
5697 return -EINVAL;
5698 }
5699
60f4a7b1
MK
5700 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
5701 params.opmode_notif_used = true;
5702 params.opmode_notif =
5703 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
5704 }
5705
ab0d76f6 5706 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
96b78dff 5707 params.plink_action =
f8bacc21 5708 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
96b78dff 5709
36647055
THJ
5710 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
5711 params.airtime_weight =
5712 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
5713
5714 if (params.airtime_weight &&
5715 !wiphy_ext_feature_isset(&rdev->wiphy,
5716 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
5717 return -EOPNOTSUPP;
5718
e96d1cd2
ARN
5719 err = nl80211_parse_sta_txpower_setting(info, &params);
5720 if (err)
5721 return err;
5722
c01fc9ad
SD
5723 err = nl80211_parse_sta_channel_info(info, &params);
5724 if (err)
5725 return err;
5726
ff276691
JB
5727 err = nl80211_parse_sta_wme(info, &params);
5728 if (err)
5729 return err;
bdd90d5e 5730
bdd3ae3d 5731 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
5727ef1b
JB
5732 return -EINVAL;
5733
496fcc29
JB
5734 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
5735 * as userspace might just pass through the capabilities from the IEs
5736 * directly, rather than enforcing this restriction and returning an
5737 * error in this case.
5738 */
5739 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
5740 params.ht_capa = NULL;
5741 params.vht_capa = NULL;
c4cbaf79
LC
5742
5743 /* HE requires WME */
5744 if (params.he_capa_len)
5745 return -EINVAL;
496fcc29
JB
5746 }
5747
77ee7c89
JB
5748 /* When you run into this, adjust the code below for the new flag */
5749 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7);
5750
bdd90d5e
JB
5751 switch (dev->ieee80211_ptr->iftype) {
5752 case NL80211_IFTYPE_AP:
5753 case NL80211_IFTYPE_AP_VLAN:
5754 case NL80211_IFTYPE_P2P_GO:
984c311b
JB
5755 /* ignore WME attributes if iface/sta is not capable */
5756 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
5757 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
5758 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
c75786c9 5759
bdd90d5e 5760 /* TDLS peers cannot be added */
3d124ea2
JM
5761 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5762 info->attrs[NL80211_ATTR_PEER_AID])
4319e193 5763 return -EINVAL;
bdd90d5e
JB
5764 /* but don't bother the driver with it */
5765 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3b9ce80c 5766
d582cffb
JB
5767 /* allow authenticated/associated only if driver handles it */
5768 if (!(rdev->wiphy.features &
5769 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
bda95eb1 5770 params.sta_flags_mask & auth_assoc)
d582cffb
JB
5771 return -EINVAL;
5772
bda95eb1
JB
5773 /* Older userspace, or userspace wanting to be compatible with
5774 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
5775 * and assoc flags in the mask, but assumes the station will be
5776 * added as associated anyway since this was the required driver
5777 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
5778 * introduced.
5779 * In order to not bother drivers with this quirk in the API
5780 * set the flags in both the mask and set for new stations in
5781 * this case.
5782 */
5783 if (!(params.sta_flags_mask & auth_assoc)) {
5784 params.sta_flags_mask |= auth_assoc;
5785 params.sta_flags_set |= auth_assoc;
5786 }
5787
bdd90d5e
JB
5788 /* must be last in here for error handling */
5789 params.vlan = get_vlan(info, rdev);
5790 if (IS_ERR(params.vlan))
5791 return PTR_ERR(params.vlan);
5792 break;
5793 case NL80211_IFTYPE_MESH_POINT:
984c311b
JB
5794 /* ignore uAPSD data */
5795 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5796
d582cffb
JB
5797 /* associated is disallowed */
5798 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
5799 return -EINVAL;
bdd90d5e 5800 /* TDLS peers cannot be added */
3d124ea2
JM
5801 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
5802 info->attrs[NL80211_ATTR_PEER_AID])
bdd90d5e
JB
5803 return -EINVAL;
5804 break;
5805 case NL80211_IFTYPE_STATION:
93d08f0b 5806 case NL80211_IFTYPE_P2P_CLIENT:
984c311b
JB
5807 /* ignore uAPSD data */
5808 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
5809
77ee7c89
JB
5810 /* these are disallowed */
5811 if (params.sta_flags_mask &
5812 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
5813 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
d582cffb 5814 return -EINVAL;
bdd90d5e
JB
5815 /* Only TDLS peers can be added */
5816 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
5817 return -EINVAL;
5818 /* Can only add if TDLS ... */
5819 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
5820 return -EOPNOTSUPP;
5821 /* ... with external setup is supported */
5822 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
5823 return -EOPNOTSUPP;
77ee7c89
JB
5824 /*
5825 * Older wpa_supplicant versions always mark the TDLS peer
5826 * as authorized, but it shouldn't yet be.
5827 */
5828 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
bdd90d5e
JB
5829 break;
5830 default:
5831 return -EOPNOTSUPP;
c75786c9
EP
5832 }
5833
bdd90d5e 5834 /* be aware of params.vlan when changing code here */
5727ef1b 5835
e35e4d28 5836 err = rdev_add_station(rdev, dev, mac_addr, &params);
5727ef1b 5837
5727ef1b
JB
5838 if (params.vlan)
5839 dev_put(params.vlan);
5727ef1b
JB
5840 return err;
5841}
5842
5843static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
5844{
4c476991
JB
5845 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5846 struct net_device *dev = info->user_ptr[1];
89c771e5
JM
5847 struct station_del_parameters params;
5848
5849 memset(&params, 0, sizeof(params));
5727ef1b
JB
5850
5851 if (info->attrs[NL80211_ATTR_MAC])
89c771e5 5852 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
5727ef1b 5853
e80cf853 5854 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
d5d9de02 5855 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
074ac8df 5856 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
4c476991
JB
5857 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5858 return -EINVAL;
5727ef1b 5859
4c476991
JB
5860 if (!rdev->ops->del_station)
5861 return -EOPNOTSUPP;
3b85875a 5862
98856866
JM
5863 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
5864 params.subtype =
5865 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
5866 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
5867 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
5868 return -EINVAL;
5869 } else {
5870 /* Default to Deauthentication frame */
5871 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
5872 }
5873
5874 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
5875 params.reason_code =
5876 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
5877 if (params.reason_code == 0)
5878 return -EINVAL; /* 0 is reserved */
5879 } else {
5880 /* Default to reason code 2 */
5881 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
5882 }
5883
89c771e5 5884 return rdev_del_station(rdev, dev, &params);
5727ef1b
JB
5885}
5886
15e47304 5887static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
2ec600d6
LCC
5888 int flags, struct net_device *dev,
5889 u8 *dst, u8 *next_hop,
5890 struct mpath_info *pinfo)
5891{
5892 void *hdr;
5893 struct nlattr *pinfoattr;
5894
1ef4c850 5895 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
2ec600d6
LCC
5896 if (!hdr)
5897 return -1;
5898
9360ffd1
DM
5899 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
5900 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
5901 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
5902 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
5903 goto nla_put_failure;
f5ea9120 5904
ae0be8de 5905 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MPATH_INFO);
2ec600d6
LCC
5906 if (!pinfoattr)
5907 goto nla_put_failure;
9360ffd1
DM
5908 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
5909 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
5910 pinfo->frame_qlen))
5911 goto nla_put_failure;
5912 if (((pinfo->filled & MPATH_INFO_SN) &&
5913 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
5914 ((pinfo->filled & MPATH_INFO_METRIC) &&
5915 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
5916 pinfo->metric)) ||
5917 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
5918 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
5919 pinfo->exptime)) ||
5920 ((pinfo->filled & MPATH_INFO_FLAGS) &&
5921 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
5922 pinfo->flags)) ||
5923 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
5924 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
5925 pinfo->discovery_timeout)) ||
5926 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
5927 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
cc241636
JH
5928 pinfo->discovery_retries)) ||
5929 ((pinfo->filled & MPATH_INFO_HOP_COUNT) &&
5930 nla_put_u8(msg, NL80211_MPATH_INFO_HOP_COUNT,
540bbcb9
JH
5931 pinfo->hop_count)) ||
5932 ((pinfo->filled & MPATH_INFO_PATH_CHANGE) &&
5933 nla_put_u32(msg, NL80211_MPATH_INFO_PATH_CHANGE,
5934 pinfo->path_change_count)))
9360ffd1 5935 goto nla_put_failure;
2ec600d6
LCC
5936
5937 nla_nest_end(msg, pinfoattr);
5938
053c095a
JB
5939 genlmsg_end(msg, hdr);
5940 return 0;
2ec600d6
LCC
5941
5942 nla_put_failure:
bc3ed28c
TG
5943 genlmsg_cancel(msg, hdr);
5944 return -EMSGSIZE;
2ec600d6
LCC
5945}
5946
5947static int nl80211_dump_mpath(struct sk_buff *skb,
bba95fef 5948 struct netlink_callback *cb)
2ec600d6 5949{
2ec600d6 5950 struct mpath_info pinfo;
1b8ec87a 5951 struct cfg80211_registered_device *rdev;
97990a06 5952 struct wireless_dev *wdev;
2ec600d6
LCC
5953 u8 dst[ETH_ALEN];
5954 u8 next_hop[ETH_ALEN];
97990a06 5955 int path_idx = cb->args[2];
2ec600d6 5956 int err;
2ec600d6 5957
ea90e0dc 5958 rtnl_lock();
5297c65c 5959 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 5960 if (err)
ea90e0dc 5961 goto out_err;
bba95fef 5962
1b8ec87a 5963 if (!rdev->ops->dump_mpath) {
eec60b03 5964 err = -EOPNOTSUPP;
bba95fef
JB
5965 goto out_err;
5966 }
5967
97990a06 5968 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
eec60b03 5969 err = -EOPNOTSUPP;
0448b5fc 5970 goto out_err;
eec60b03
JM
5971 }
5972
bba95fef 5973 while (1) {
1b8ec87a 5974 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
97990a06 5975 next_hop, &pinfo);
bba95fef 5976 if (err == -ENOENT)
2ec600d6 5977 break;
bba95fef 5978 if (err)
3b85875a 5979 goto out_err;
2ec600d6 5980
15e47304 5981 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
bba95fef 5982 cb->nlh->nlmsg_seq, NLM_F_MULTI,
97990a06 5983 wdev->netdev, dst, next_hop,
bba95fef
JB
5984 &pinfo) < 0)
5985 goto out;
2ec600d6 5986
bba95fef 5987 path_idx++;
2ec600d6 5988 }
2ec600d6 5989
bba95fef 5990 out:
97990a06 5991 cb->args[2] = path_idx;
bba95fef 5992 err = skb->len;
bba95fef 5993 out_err:
ea90e0dc 5994 rtnl_unlock();
bba95fef 5995 return err;
2ec600d6
LCC
5996}
5997
5998static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
5999{
4c476991 6000 struct cfg80211_registered_device *rdev = info->user_ptr[0];
2ec600d6 6001 int err;
4c476991 6002 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6003 struct mpath_info pinfo;
6004 struct sk_buff *msg;
6005 u8 *dst = NULL;
6006 u8 next_hop[ETH_ALEN];
6007
6008 memset(&pinfo, 0, sizeof(pinfo));
6009
6010 if (!info->attrs[NL80211_ATTR_MAC])
6011 return -EINVAL;
6012
6013 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6014
4c476991
JB
6015 if (!rdev->ops->get_mpath)
6016 return -EOPNOTSUPP;
2ec600d6 6017
4c476991
JB
6018 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6019 return -EOPNOTSUPP;
eec60b03 6020
e35e4d28 6021 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
2ec600d6 6022 if (err)
4c476991 6023 return err;
2ec600d6 6024
fd2120ca 6025 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2ec600d6 6026 if (!msg)
4c476991 6027 return -ENOMEM;
2ec600d6 6028
15e47304 6029 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
4c476991
JB
6030 dev, dst, next_hop, &pinfo) < 0) {
6031 nlmsg_free(msg);
6032 return -ENOBUFS;
6033 }
3b85875a 6034
4c476991 6035 return genlmsg_reply(msg, info);
2ec600d6
LCC
6036}
6037
6038static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
6039{
4c476991
JB
6040 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6041 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6042 u8 *dst = NULL;
6043 u8 *next_hop = NULL;
6044
6045 if (!info->attrs[NL80211_ATTR_MAC])
6046 return -EINVAL;
6047
6048 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
6049 return -EINVAL;
6050
6051 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6052 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
6053
4c476991
JB
6054 if (!rdev->ops->change_mpath)
6055 return -EOPNOTSUPP;
35a8efe1 6056
4c476991
JB
6057 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6058 return -EOPNOTSUPP;
2ec600d6 6059
e35e4d28 6060 return rdev_change_mpath(rdev, dev, dst, next_hop);
2ec600d6 6061}
4c476991 6062
2ec600d6
LCC
6063static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
6064{
4c476991
JB
6065 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6066 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6067 u8 *dst = NULL;
6068 u8 *next_hop = NULL;
6069
6070 if (!info->attrs[NL80211_ATTR_MAC])
6071 return -EINVAL;
6072
6073 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
6074 return -EINVAL;
6075
6076 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6077 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
6078
4c476991
JB
6079 if (!rdev->ops->add_mpath)
6080 return -EOPNOTSUPP;
35a8efe1 6081
4c476991
JB
6082 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6083 return -EOPNOTSUPP;
2ec600d6 6084
e35e4d28 6085 return rdev_add_mpath(rdev, dev, dst, next_hop);
2ec600d6
LCC
6086}
6087
6088static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
6089{
4c476991
JB
6090 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6091 struct net_device *dev = info->user_ptr[1];
2ec600d6
LCC
6092 u8 *dst = NULL;
6093
6094 if (info->attrs[NL80211_ATTR_MAC])
6095 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6096
4c476991
JB
6097 if (!rdev->ops->del_mpath)
6098 return -EOPNOTSUPP;
3b85875a 6099
e35e4d28 6100 return rdev_del_mpath(rdev, dev, dst);
2ec600d6
LCC
6101}
6102
66be7d2b
HR
6103static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
6104{
6105 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6106 int err;
6107 struct net_device *dev = info->user_ptr[1];
6108 struct mpath_info pinfo;
6109 struct sk_buff *msg;
6110 u8 *dst = NULL;
6111 u8 mpp[ETH_ALEN];
6112
6113 memset(&pinfo, 0, sizeof(pinfo));
6114
6115 if (!info->attrs[NL80211_ATTR_MAC])
6116 return -EINVAL;
6117
6118 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
6119
6120 if (!rdev->ops->get_mpp)
6121 return -EOPNOTSUPP;
6122
6123 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
6124 return -EOPNOTSUPP;
6125
6126 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
6127 if (err)
6128 return err;
6129
6130 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6131 if (!msg)
6132 return -ENOMEM;
6133
6134 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
6135 dev, dst, mpp, &pinfo) < 0) {
6136 nlmsg_free(msg);
6137 return -ENOBUFS;
6138 }
6139
6140 return genlmsg_reply(msg, info);
6141}
6142
6143static int nl80211_dump_mpp(struct sk_buff *skb,
6144 struct netlink_callback *cb)
6145{
6146 struct mpath_info pinfo;
6147 struct cfg80211_registered_device *rdev;
6148 struct wireless_dev *wdev;
6149 u8 dst[ETH_ALEN];
6150 u8 mpp[ETH_ALEN];
6151 int path_idx = cb->args[2];
6152 int err;
6153
ea90e0dc 6154 rtnl_lock();
5297c65c 6155 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
66be7d2b 6156 if (err)
ea90e0dc 6157 goto out_err;
66be7d2b
HR
6158
6159 if (!rdev->ops->dump_mpp) {
6160 err = -EOPNOTSUPP;
6161 goto out_err;
6162 }
6163
6164 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
6165 err = -EOPNOTSUPP;
6166 goto out_err;
6167 }
6168
6169 while (1) {
6170 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
6171 mpp, &pinfo);
6172 if (err == -ENOENT)
6173 break;
6174 if (err)
6175 goto out_err;
6176
6177 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
6178 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6179 wdev->netdev, dst, mpp,
6180 &pinfo) < 0)
6181 goto out;
6182
6183 path_idx++;
6184 }
6185
6186 out:
6187 cb->args[2] = path_idx;
6188 err = skb->len;
6189 out_err:
ea90e0dc 6190 rtnl_unlock();
66be7d2b
HR
6191 return err;
6192}
6193
9f1ba906
JM
6194static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
6195{
4c476991
JB
6196 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6197 struct net_device *dev = info->user_ptr[1];
c56589ed 6198 struct wireless_dev *wdev = dev->ieee80211_ptr;
9f1ba906 6199 struct bss_parameters params;
c56589ed 6200 int err;
9f1ba906
JM
6201
6202 memset(&params, 0, sizeof(params));
6203 /* default to not changing parameters */
6204 params.use_cts_prot = -1;
6205 params.use_short_preamble = -1;
6206 params.use_short_slot_time = -1;
fd8aaaf3 6207 params.ap_isolate = -1;
50b12f59 6208 params.ht_opmode = -1;
53cabad7
JB
6209 params.p2p_ctwindow = -1;
6210 params.p2p_opp_ps = -1;
9f1ba906
JM
6211
6212 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
6213 params.use_cts_prot =
6214 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
6215 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
6216 params.use_short_preamble =
6217 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
6218 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
6219 params.use_short_slot_time =
6220 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
90c97a04
JM
6221 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
6222 params.basic_rates =
6223 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
6224 params.basic_rates_len =
6225 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
6226 }
fd8aaaf3
FF
6227 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
6228 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
50b12f59
HS
6229 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
6230 params.ht_opmode =
6231 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
9f1ba906 6232
53cabad7
JB
6233 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
6234 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6235 return -EINVAL;
6236 params.p2p_ctwindow =
ab0d76f6 6237 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
53cabad7
JB
6238 if (params.p2p_ctwindow != 0 &&
6239 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
6240 return -EINVAL;
6241 }
6242
6243 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
6244 u8 tmp;
6245
6246 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6247 return -EINVAL;
6248 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
53cabad7
JB
6249 params.p2p_opp_ps = tmp;
6250 if (params.p2p_opp_ps &&
6251 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
6252 return -EINVAL;
6253 }
6254
4c476991
JB
6255 if (!rdev->ops->change_bss)
6256 return -EOPNOTSUPP;
9f1ba906 6257
074ac8df 6258 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
4c476991
JB
6259 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6260 return -EOPNOTSUPP;
3b85875a 6261
c56589ed
SW
6262 wdev_lock(wdev);
6263 err = rdev_change_bss(rdev, dev, &params);
6264 wdev_unlock(wdev);
6265
6266 return err;
9f1ba906
JM
6267}
6268
b2e1b302
LR
6269static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
6270{
b2e1b302 6271 char *data = NULL;
05050753 6272 bool is_indoor;
57b5ce07 6273 enum nl80211_user_reg_hint_type user_reg_hint_type;
05050753
I
6274 u32 owner_nlportid;
6275
80778f18
LR
6276 /*
6277 * You should only get this when cfg80211 hasn't yet initialized
6278 * completely when built-in to the kernel right between the time
6279 * window between nl80211_init() and regulatory_init(), if that is
6280 * even possible.
6281 */
458f4f9e 6282 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
fe33eb39 6283 return -EINPROGRESS;
80778f18 6284
57b5ce07
LR
6285 if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE])
6286 user_reg_hint_type =
6287 nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]);
6288 else
6289 user_reg_hint_type = NL80211_USER_REG_HINT_USER;
6290
6291 switch (user_reg_hint_type) {
6292 case NL80211_USER_REG_HINT_USER:
6293 case NL80211_USER_REG_HINT_CELL_BASE:
52616f2b
IP
6294 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6295 return -EINVAL;
6296
6297 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6298 return regulatory_hint_user(data, user_reg_hint_type);
6299 case NL80211_USER_REG_HINT_INDOOR:
05050753
I
6300 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
6301 owner_nlportid = info->snd_portid;
6302 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
6303 } else {
6304 owner_nlportid = 0;
6305 is_indoor = true;
6306 }
6307
6308 return regulatory_hint_indoor(is_indoor, owner_nlportid);
57b5ce07
LR
6309 default:
6310 return -EINVAL;
6311 }
b2e1b302
LR
6312}
6313
1ea4ff3e
JB
6314static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
6315{
6316 return reg_reload_regdb();
6317}
6318
24bdd9f4 6319static int nl80211_get_mesh_config(struct sk_buff *skb,
29cbe68c 6320 struct genl_info *info)
93da9cc1 6321{
4c476991 6322 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 6323 struct net_device *dev = info->user_ptr[1];
29cbe68c
JB
6324 struct wireless_dev *wdev = dev->ieee80211_ptr;
6325 struct mesh_config cur_params;
6326 int err = 0;
93da9cc1 6327 void *hdr;
6328 struct nlattr *pinfoattr;
6329 struct sk_buff *msg;
6330
29cbe68c
JB
6331 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
6332 return -EOPNOTSUPP;
6333
24bdd9f4 6334 if (!rdev->ops->get_mesh_config)
4c476991 6335 return -EOPNOTSUPP;
f3f92586 6336
29cbe68c
JB
6337 wdev_lock(wdev);
6338 /* If not connected, get default parameters */
6339 if (!wdev->mesh_id_len)
6340 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
6341 else
e35e4d28 6342 err = rdev_get_mesh_config(rdev, dev, &cur_params);
29cbe68c
JB
6343 wdev_unlock(wdev);
6344
93da9cc1 6345 if (err)
4c476991 6346 return err;
93da9cc1 6347
6348 /* Draw up a netlink message to send back */
fd2120ca 6349 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
6350 if (!msg)
6351 return -ENOMEM;
15e47304 6352 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
24bdd9f4 6353 NL80211_CMD_GET_MESH_CONFIG);
93da9cc1 6354 if (!hdr)
efe1cf0c 6355 goto out;
ae0be8de 6356 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MESH_CONFIG);
93da9cc1 6357 if (!pinfoattr)
6358 goto nla_put_failure;
9360ffd1
DM
6359 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6360 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
6361 cur_params.dot11MeshRetryTimeout) ||
6362 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
6363 cur_params.dot11MeshConfirmTimeout) ||
6364 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
6365 cur_params.dot11MeshHoldingTimeout) ||
6366 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
6367 cur_params.dot11MeshMaxPeerLinks) ||
6368 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
6369 cur_params.dot11MeshMaxRetries) ||
6370 nla_put_u8(msg, NL80211_MESHCONF_TTL,
6371 cur_params.dot11MeshTTL) ||
6372 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
6373 cur_params.element_ttl) ||
6374 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
6375 cur_params.auto_open_plinks) ||
7eab0f64
JL
6376 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
6377 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
9360ffd1
DM
6378 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
6379 cur_params.dot11MeshHWMPmaxPREQretries) ||
6380 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
6381 cur_params.path_refresh_time) ||
6382 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
6383 cur_params.min_discovery_timeout) ||
6384 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
6385 cur_params.dot11MeshHWMPactivePathTimeout) ||
6386 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
6387 cur_params.dot11MeshHWMPpreqMinInterval) ||
6388 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
6389 cur_params.dot11MeshHWMPperrMinInterval) ||
6390 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
6391 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
6392 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
6393 cur_params.dot11MeshHWMPRootMode) ||
6394 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
6395 cur_params.dot11MeshHWMPRannInterval) ||
6396 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
6397 cur_params.dot11MeshGateAnnouncementProtocol) ||
6398 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
6399 cur_params.dot11MeshForwarding) ||
335d5349 6400 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
70c33eaa
AN
6401 cur_params.rssi_threshold) ||
6402 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
ac1073a6
CYY
6403 cur_params.ht_opmode) ||
6404 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
6405 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
6406 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
728b19e5
CYY
6407 cur_params.dot11MeshHWMProotInterval) ||
6408 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
3b1c5a53
MP
6409 cur_params.dot11MeshHWMPconfirmationInterval) ||
6410 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
6411 cur_params.power_mode) ||
6412 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8e7c0538
CT
6413 cur_params.dot11MeshAwakeWindowDuration) ||
6414 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
01d66fbd
BC
6415 cur_params.plink_timeout) ||
6416 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
6417 cur_params.dot11MeshConnectedToMeshGate))
9360ffd1 6418 goto nla_put_failure;
93da9cc1 6419 nla_nest_end(msg, pinfoattr);
6420 genlmsg_end(msg, hdr);
4c476991 6421 return genlmsg_reply(msg, info);
93da9cc1 6422
3b85875a 6423 nla_put_failure:
efe1cf0c 6424 out:
d080e275 6425 nlmsg_free(msg);
4c476991 6426 return -ENOBUFS;
93da9cc1 6427}
6428
ab0d76f6
JB
6429static const struct nla_policy
6430nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
6431 [NL80211_MESHCONF_RETRY_TIMEOUT] =
6432 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6433 [NL80211_MESHCONF_CONFIRM_TIMEOUT] =
6434 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6435 [NL80211_MESHCONF_HOLDING_TIMEOUT] =
6436 NLA_POLICY_RANGE(NLA_U16, 1, 255),
6437 [NL80211_MESHCONF_MAX_PEER_LINKS] =
6438 NLA_POLICY_RANGE(NLA_U16, 0, 255),
6439 [NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
6440 [NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
6441 [NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
6442 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
6443 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
6444 NLA_POLICY_RANGE(NLA_U32, 1, 255),
93da9cc1 6445 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
6446 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
ab0d76f6 6447 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
93da9cc1 6448 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
6449 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
6450 NLA_POLICY_MIN(NLA_U16, 1),
6451 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
6452 NLA_POLICY_MIN(NLA_U16, 1),
6453 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
6454 NLA_POLICY_MIN(NLA_U16, 1),
6455 [NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
6456 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
6457 NLA_POLICY_MIN(NLA_U16, 1),
6458 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
6459 [NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
6460 [NL80211_MESHCONF_RSSI_THRESHOLD] =
6461 NLA_POLICY_RANGE(NLA_S32, -255, 0),
a4f606ea 6462 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
ac1073a6 6463 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
ab0d76f6
JB
6464 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
6465 NLA_POLICY_MIN(NLA_U16, 1),
6466 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
6467 NLA_POLICY_MIN(NLA_U16, 1),
6468 [NL80211_MESHCONF_POWER_MODE] =
6469 NLA_POLICY_RANGE(NLA_U32,
6470 NL80211_MESH_POWER_ACTIVE,
6471 NL80211_MESH_POWER_MAX),
3b1c5a53 6472 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8e7c0538 6473 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
01d66fbd 6474 [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
93da9cc1 6475};
6476
c80d545d
JC
6477static const struct nla_policy
6478 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
d299a1f2 6479 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
c80d545d
JC
6480 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
6481 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
15d5dda6 6482 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
6e16d90b 6483 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
bb2798d4 6484 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
3d7af878
JB
6485 [NL80211_MESH_SETUP_IE] =
6486 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
6487 IEEE80211_MAX_DATA_LEN),
b130e5ce 6488 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
c80d545d
JC
6489};
6490
24bdd9f4 6491static int nl80211_parse_mesh_config(struct genl_info *info,
bd90fdcc
JB
6492 struct mesh_config *cfg,
6493 u32 *mask_out)
93da9cc1 6494{
93da9cc1 6495 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
bd90fdcc 6496 u32 mask = 0;
9757235f 6497 u16 ht_opmode;
93da9cc1 6498
ab0d76f6
JB
6499#define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
6500do { \
6501 if (tb[attr]) { \
6502 cfg->param = fn(tb[attr]); \
6503 mask |= BIT((attr) - 1); \
6504 } \
ea54fba2 6505} while (0)
bd90fdcc 6506
24bdd9f4 6507 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
93da9cc1 6508 return -EINVAL;
8cb08174 6509 if (nla_parse_nested_deprecated(tb, NL80211_MESHCONF_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy, info->extack))
93da9cc1 6510 return -EINVAL;
6511
93da9cc1 6512 /* This makes sure that there aren't more than 32 mesh config
6513 * parameters (otherwise our bitfield scheme would not work.) */
6514 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
6515
6516 /* Fill in the params struct */
ab0d76f6
JB
6517 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
6518 NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
6519 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
6520 NL80211_MESHCONF_CONFIRM_TIMEOUT,
6521 nla_get_u16);
6522 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
6523 NL80211_MESHCONF_HOLDING_TIMEOUT,
6524 nla_get_u16);
6525 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
6526 NL80211_MESHCONF_MAX_PEER_LINKS,
6527 nla_get_u16);
6528 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
6529 NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
6530 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
6531 NL80211_MESHCONF_TTL, nla_get_u8);
6532 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
6533 NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
6534 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
6535 NL80211_MESHCONF_AUTO_OPEN_PLINKS,
6536 nla_get_u8);
ea54fba2 6537 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
ab0d76f6 6538 mask,
a4f606ea 6539 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
ab0d76f6
JB
6540 nla_get_u32);
6541 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
6542 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
6543 nla_get_u8);
6544 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
6545 NL80211_MESHCONF_PATH_REFRESH_TIME,
6546 nla_get_u32);
6547 if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
6548 (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
6549 return -EINVAL;
6550 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
6551 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
6552 nla_get_u16);
ea54fba2 6553 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
ab0d76f6 6554 mask,
a4f606ea 6555 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
ab0d76f6
JB
6556 nla_get_u32);
6557 if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
6558 (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
6559 cfg->dot11MeshHWMPactivePathTimeout > 65535))
6560 return -EINVAL;
6561 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
ea54fba2 6562 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
ab0d76f6
JB
6563 nla_get_u16);
6564 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
ea54fba2 6565 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
ab0d76f6 6566 nla_get_u16);
93da9cc1 6567 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6 6568 dot11MeshHWMPnetDiameterTraversalTime, mask,
a4f606ea 6569 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
ab0d76f6
JB
6570 nla_get_u16);
6571 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
6572 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
6573 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
6574 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
6575 nla_get_u16);
6576 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
ea54fba2 6577 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
ab0d76f6
JB
6578 nla_get_u8);
6579 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
6580 NL80211_MESHCONF_FORWARDING, nla_get_u8);
6581 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
6582 NL80211_MESHCONF_RSSI_THRESHOLD,
6583 nla_get_s32);
01d66fbd
BC
6584 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
6585 NL80211_MESHCONF_CONNECTED_TO_GATE,
6586 nla_get_u8);
9757235f
MH
6587 /*
6588 * Check HT operation mode based on
188f60ab 6589 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
9757235f
MH
6590 */
6591 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
6592 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
6593
6594 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
6595 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
6596 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
6597 return -EINVAL;
6598
188f60ab
BC
6599 /* NON_HT_STA bit is reserved, but some programs set it */
6600 ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
9757235f 6601
9757235f 6602 cfg->ht_opmode = ht_opmode;
fd551bac 6603 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
9757235f 6604 }
728b19e5 6605 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
ab0d76f6
JB
6606 dot11MeshHWMPactivePathToRootTimeout, mask,
6607 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
6608 nla_get_u32);
6609 if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
6610 (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
6611 cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
6612 return -EINVAL;
6613 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
6614 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
6615 nla_get_u16);
6616 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
6617 mask,
728b19e5 6618 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
ab0d76f6
JB
6619 nla_get_u16);
6620 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
6621 NL80211_MESHCONF_POWER_MODE, nla_get_u32);
6622 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
6623 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
6624 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
6625 NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
bd90fdcc
JB
6626 if (mask_out)
6627 *mask_out = mask;
c80d545d 6628
bd90fdcc
JB
6629 return 0;
6630
6631#undef FILL_IN_MESH_PARAM_IF_SET
6632}
6633
c80d545d
JC
6634static int nl80211_parse_mesh_setup(struct genl_info *info,
6635 struct mesh_setup *setup)
6636{
bb2798d4 6637 struct cfg80211_registered_device *rdev = info->user_ptr[0];
c80d545d
JC
6638 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
6639
6640 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
6641 return -EINVAL;
8cb08174 6642 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
6643 return -EINVAL;
6644
d299a1f2
JC
6645 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
6646 setup->sync_method =
6647 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
6648 IEEE80211_SYNC_METHOD_VENDOR :
6649 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
6650
c80d545d
JC
6651 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
6652 setup->path_sel_proto =
6653 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
6654 IEEE80211_PATH_PROTOCOL_VENDOR :
6655 IEEE80211_PATH_PROTOCOL_HWMP;
6656
6657 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
6658 setup->path_metric =
6659 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
6660 IEEE80211_PATH_METRIC_VENDOR :
6661 IEEE80211_PATH_METRIC_AIRTIME;
6662
581a8b0f 6663 if (tb[NL80211_MESH_SETUP_IE]) {
c80d545d 6664 struct nlattr *ieattr =
581a8b0f 6665 tb[NL80211_MESH_SETUP_IE];
581a8b0f
JC
6666 setup->ie = nla_data(ieattr);
6667 setup->ie_len = nla_len(ieattr);
c80d545d 6668 }
bb2798d4
TP
6669 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
6670 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
6671 return -EINVAL;
6672 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
b130e5ce
JC
6673 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
6674 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
bb2798d4
TP
6675 if (setup->is_secure)
6676 setup->user_mpm = true;
c80d545d 6677
6e16d90b
CT
6678 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
6679 if (!setup->user_mpm)
6680 return -EINVAL;
6681 setup->auth_id =
6682 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
6683 }
6684
c80d545d
JC
6685 return 0;
6686}
6687
24bdd9f4 6688static int nl80211_update_mesh_config(struct sk_buff *skb,
29cbe68c 6689 struct genl_info *info)
bd90fdcc
JB
6690{
6691 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6692 struct net_device *dev = info->user_ptr[1];
29cbe68c 6693 struct wireless_dev *wdev = dev->ieee80211_ptr;
bd90fdcc
JB
6694 struct mesh_config cfg;
6695 u32 mask;
6696 int err;
6697
29cbe68c
JB
6698 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
6699 return -EOPNOTSUPP;
6700
24bdd9f4 6701 if (!rdev->ops->update_mesh_config)
bd90fdcc
JB
6702 return -EOPNOTSUPP;
6703
24bdd9f4 6704 err = nl80211_parse_mesh_config(info, &cfg, &mask);
bd90fdcc
JB
6705 if (err)
6706 return err;
6707
29cbe68c
JB
6708 wdev_lock(wdev);
6709 if (!wdev->mesh_id_len)
6710 err = -ENOLINK;
6711
6712 if (!err)
e35e4d28 6713 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
29cbe68c
JB
6714
6715 wdev_unlock(wdev);
6716
6717 return err;
93da9cc1 6718}
6719
ad30ca2c
AN
6720static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
6721 struct sk_buff *msg)
f130347c 6722{
f130347c
LR
6723 struct nlattr *nl_reg_rules;
6724 unsigned int i;
f130347c 6725
458f4f9e
JB
6726 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
6727 (regdom->dfs_region &&
6728 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
ad30ca2c 6729 goto nla_put_failure;
458f4f9e 6730
ae0be8de 6731 nl_reg_rules = nla_nest_start_noflag(msg, NL80211_ATTR_REG_RULES);
f130347c 6732 if (!nl_reg_rules)
ad30ca2c 6733 goto nla_put_failure;
f130347c 6734
458f4f9e 6735 for (i = 0; i < regdom->n_reg_rules; i++) {
f130347c
LR
6736 struct nlattr *nl_reg_rule;
6737 const struct ieee80211_reg_rule *reg_rule;
6738 const struct ieee80211_freq_range *freq_range;
6739 const struct ieee80211_power_rule *power_rule;
97524820 6740 unsigned int max_bandwidth_khz;
f130347c 6741
458f4f9e 6742 reg_rule = &regdom->reg_rules[i];
f130347c
LR
6743 freq_range = &reg_rule->freq_range;
6744 power_rule = &reg_rule->power_rule;
6745
ae0be8de 6746 nl_reg_rule = nla_nest_start_noflag(msg, i);
f130347c 6747 if (!nl_reg_rule)
ad30ca2c 6748 goto nla_put_failure;
f130347c 6749
97524820
JD
6750 max_bandwidth_khz = freq_range->max_bandwidth_khz;
6751 if (!max_bandwidth_khz)
6752 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
6753 reg_rule);
6754
9360ffd1
DM
6755 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
6756 reg_rule->flags) ||
6757 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
6758 freq_range->start_freq_khz) ||
6759 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
6760 freq_range->end_freq_khz) ||
6761 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
97524820 6762 max_bandwidth_khz) ||
9360ffd1
DM
6763 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
6764 power_rule->max_antenna_gain) ||
6765 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
089027e5
JD
6766 power_rule->max_eirp) ||
6767 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
6768 reg_rule->dfs_cac_ms))
ad30ca2c 6769 goto nla_put_failure;
f130347c
LR
6770
6771 nla_nest_end(msg, nl_reg_rule);
6772 }
6773
6774 nla_nest_end(msg, nl_reg_rules);
ad30ca2c
AN
6775 return 0;
6776
6777nla_put_failure:
6778 return -EMSGSIZE;
6779}
6780
6781static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
6782{
6783 const struct ieee80211_regdomain *regdom = NULL;
6784 struct cfg80211_registered_device *rdev;
6785 struct wiphy *wiphy = NULL;
6786 struct sk_buff *msg;
6787 void *hdr;
6788
6789 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6790 if (!msg)
6791 return -ENOBUFS;
6792
6793 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
6794 NL80211_CMD_GET_REG);
6795 if (!hdr)
6796 goto put_failure;
6797
6798 if (info->attrs[NL80211_ATTR_WIPHY]) {
1bdd716c
AN
6799 bool self_managed;
6800
ad30ca2c
AN
6801 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
6802 if (IS_ERR(rdev)) {
6803 nlmsg_free(msg);
6804 return PTR_ERR(rdev);
6805 }
6806
6807 wiphy = &rdev->wiphy;
1bdd716c
AN
6808 self_managed = wiphy->regulatory_flags &
6809 REGULATORY_WIPHY_SELF_MANAGED;
ad30ca2c
AN
6810 regdom = get_wiphy_regdom(wiphy);
6811
1bdd716c
AN
6812 /* a self-managed-reg device must have a private regdom */
6813 if (WARN_ON(!regdom && self_managed)) {
6814 nlmsg_free(msg);
6815 return -EINVAL;
6816 }
6817
ad30ca2c
AN
6818 if (regdom &&
6819 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6820 goto nla_put_failure;
6821 }
6822
6823 if (!wiphy && reg_last_request_cell_base() &&
6824 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6825 NL80211_USER_REG_HINT_CELL_BASE))
6826 goto nla_put_failure;
6827
6828 rcu_read_lock();
6829
6830 if (!regdom)
6831 regdom = rcu_dereference(cfg80211_regdomain);
6832
6833 if (nl80211_put_regdom(regdom, msg))
6834 goto nla_put_failure_rcu;
6835
6836 rcu_read_unlock();
f130347c
LR
6837
6838 genlmsg_end(msg, hdr);
5fe231e8 6839 return genlmsg_reply(msg, info);
f130347c 6840
458f4f9e
JB
6841nla_put_failure_rcu:
6842 rcu_read_unlock();
f130347c 6843nla_put_failure:
efe1cf0c 6844put_failure:
d080e275 6845 nlmsg_free(msg);
5fe231e8 6846 return -EMSGSIZE;
f130347c
LR
6847}
6848
ad30ca2c
AN
6849static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
6850 u32 seq, int flags, struct wiphy *wiphy,
6851 const struct ieee80211_regdomain *regdom)
6852{
6853 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
6854 NL80211_CMD_GET_REG);
6855
6856 if (!hdr)
6857 return -1;
6858
0a833c29 6859 genl_dump_check_consistent(cb, hdr);
ad30ca2c
AN
6860
6861 if (nl80211_put_regdom(regdom, msg))
6862 goto nla_put_failure;
6863
6864 if (!wiphy && reg_last_request_cell_base() &&
6865 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
6866 NL80211_USER_REG_HINT_CELL_BASE))
6867 goto nla_put_failure;
6868
6869 if (wiphy &&
6870 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
6871 goto nla_put_failure;
6872
1bdd716c
AN
6873 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
6874 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
6875 goto nla_put_failure;
6876
053c095a
JB
6877 genlmsg_end(msg, hdr);
6878 return 0;
ad30ca2c
AN
6879
6880nla_put_failure:
6881 genlmsg_cancel(msg, hdr);
6882 return -EMSGSIZE;
6883}
6884
6885static int nl80211_get_reg_dump(struct sk_buff *skb,
6886 struct netlink_callback *cb)
6887{
6888 const struct ieee80211_regdomain *regdom = NULL;
6889 struct cfg80211_registered_device *rdev;
6890 int err, reg_idx, start = cb->args[2];
6891
6892 rtnl_lock();
6893
6894 if (cfg80211_regdomain && start == 0) {
6895 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6896 NLM_F_MULTI, NULL,
6897 rtnl_dereference(cfg80211_regdomain));
6898 if (err < 0)
6899 goto out_err;
6900 }
6901
6902 /* the global regdom is idx 0 */
6903 reg_idx = 1;
6904 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
6905 regdom = get_wiphy_regdom(&rdev->wiphy);
6906 if (!regdom)
6907 continue;
6908
6909 if (++reg_idx <= start)
6910 continue;
6911
6912 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
6913 NLM_F_MULTI, &rdev->wiphy, regdom);
6914 if (err < 0) {
6915 reg_idx--;
6916 break;
6917 }
6918 }
6919
6920 cb->args[2] = reg_idx;
6921 err = skb->len;
6922out_err:
6923 rtnl_unlock();
6924 return err;
6925}
6926
b6863036
JB
6927#ifdef CONFIG_CFG80211_CRDA_SUPPORT
6928static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
6929 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
6930 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
6931 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
6932 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
6933 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
6934 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
6935 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
6936};
6937
6938static int parse_reg_rule(struct nlattr *tb[],
6939 struct ieee80211_reg_rule *reg_rule)
6940{
6941 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
6942 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
6943
6944 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
6945 return -EINVAL;
6946 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
6947 return -EINVAL;
6948 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
6949 return -EINVAL;
6950 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
6951 return -EINVAL;
6952 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
6953 return -EINVAL;
6954
6955 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
6956
6957 freq_range->start_freq_khz =
6958 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
6959 freq_range->end_freq_khz =
6960 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
6961 freq_range->max_bandwidth_khz =
6962 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
6963
6964 power_rule->max_eirp =
6965 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
6966
6967 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
6968 power_rule->max_antenna_gain =
6969 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
6970
6971 if (tb[NL80211_ATTR_DFS_CAC_TIME])
6972 reg_rule->dfs_cac_ms =
6973 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
6974
6975 return 0;
6976}
6977
b2e1b302
LR
6978static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
6979{
6980 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
6981 struct nlattr *nl_reg_rule;
ea372c54
JB
6982 char *alpha2;
6983 int rem_reg_rules, r;
391d132c 6984 u32 num_rules = 0, rule_idx = 0;
4c7d3982 6985 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
ea372c54 6986 struct ieee80211_regdomain *rd;
b2e1b302
LR
6987
6988 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
6989 return -EINVAL;
6990
6991 if (!info->attrs[NL80211_ATTR_REG_RULES])
6992 return -EINVAL;
6993
6994 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
6995
8b60b078
LR
6996 if (info->attrs[NL80211_ATTR_DFS_REGION])
6997 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
6998
b2e1b302 6999 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7000 rem_reg_rules) {
b2e1b302
LR
7001 num_rules++;
7002 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
4776c6e7 7003 return -EINVAL;
b2e1b302
LR
7004 }
7005
e438768f
LR
7006 if (!reg_is_valid_request(alpha2))
7007 return -EINVAL;
7008
391d132c 7009 rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
6913b49a
JB
7010 if (!rd)
7011 return -ENOMEM;
b2e1b302
LR
7012
7013 rd->n_reg_rules = num_rules;
7014 rd->alpha2[0] = alpha2[0];
7015 rd->alpha2[1] = alpha2[1];
7016
8b60b078
LR
7017 /*
7018 * Disable DFS master mode if the DFS region was
7019 * not supported or known on this kernel.
7020 */
7021 if (reg_supported_dfs_region(dfs_region))
7022 rd->dfs_region = dfs_region;
7023
b2e1b302 7024 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1a919318 7025 rem_reg_rules) {
8cb08174
JB
7026 r = nla_parse_nested_deprecated(tb, NL80211_REG_RULE_ATTR_MAX,
7027 nl_reg_rule, reg_rule_policy,
7028 info->extack);
ae811e21
JB
7029 if (r)
7030 goto bad_reg;
b2e1b302
LR
7031 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
7032 if (r)
7033 goto bad_reg;
7034
7035 rule_idx++;
7036
d0e18f83
LR
7037 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
7038 r = -EINVAL;
b2e1b302 7039 goto bad_reg;
d0e18f83 7040 }
b2e1b302
LR
7041 }
7042
06627990
JB
7043 /* set_regdom takes ownership of rd */
7044 return set_regdom(rd, REGD_SOURCE_CRDA);
d2372b31 7045 bad_reg:
b2e1b302 7046 kfree(rd);
d0e18f83 7047 return r;
b2e1b302 7048}
b6863036 7049#endif /* CONFIG_CFG80211_CRDA_SUPPORT */
b2e1b302 7050
83f5e2cf
JB
7051static int validate_scan_freqs(struct nlattr *freqs)
7052{
7053 struct nlattr *attr1, *attr2;
7054 int n_channels = 0, tmp1, tmp2;
7055
d7f13f74
SD
7056 nla_for_each_nested(attr1, freqs, tmp1)
7057 if (nla_len(attr1) != sizeof(u32))
7058 return 0;
7059
83f5e2cf
JB
7060 nla_for_each_nested(attr1, freqs, tmp1) {
7061 n_channels++;
7062 /*
7063 * Some hardware has a limited channel list for
7064 * scanning, and it is pretty much nonsensical
7065 * to scan for a channel twice, so disallow that
7066 * and don't require drivers to check that the
7067 * channel list they get isn't longer than what
7068 * they can scan, as long as they can scan all
7069 * the channels they registered at once.
7070 */
7071 nla_for_each_nested(attr2, freqs, tmp2)
7072 if (attr1 != attr2 &&
7073 nla_get_u32(attr1) == nla_get_u32(attr2))
7074 return 0;
7075 }
7076
7077 return n_channels;
7078}
7079
57fbcce3 7080static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
38de03d2 7081{
57fbcce3 7082 return b < NUM_NL80211_BANDS && wiphy->bands[b];
38de03d2
AS
7083}
7084
7085static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
7086 struct cfg80211_bss_selection *bss_select)
7087{
7088 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
7089 struct nlattr *nest;
7090 int err;
7091 bool found = false;
7092 int i;
7093
7094 /* only process one nested attribute */
7095 nest = nla_data(nla);
7096 if (!nla_ok(nest, nla_len(nest)))
7097 return -EINVAL;
7098
8cb08174
JB
7099 err = nla_parse_nested_deprecated(attr, NL80211_BSS_SELECT_ATTR_MAX,
7100 nest, nl80211_bss_select_policy,
7101 NULL);
38de03d2
AS
7102 if (err)
7103 return err;
7104
7105 /* only one attribute may be given */
7106 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
7107 if (attr[i]) {
7108 if (found)
7109 return -EINVAL;
7110 found = true;
7111 }
7112 }
7113
7114 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
7115
7116 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
7117 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
7118
7119 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
7120 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
7121 bss_select->param.band_pref =
7122 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
7123 if (!is_band_valid(wiphy, bss_select->param.band_pref))
7124 return -EINVAL;
7125 }
7126
7127 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
7128 struct nl80211_bss_select_rssi_adjust *adj_param;
7129
7130 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
7131 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
7132 bss_select->param.adjust.band = adj_param->band;
7133 bss_select->param.adjust.delta = adj_param->delta;
7134 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
7135 return -EINVAL;
7136 }
7137
7138 /* user-space did not provide behaviour attribute */
7139 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
7140 return -EINVAL;
7141
7142 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
7143 return -EINVAL;
7144
7145 return 0;
7146}
7147
9bb7e0f2
JB
7148int nl80211_parse_random_mac(struct nlattr **attrs,
7149 u8 *mac_addr, u8 *mac_addr_mask)
ad2b26ab
JB
7150{
7151 int i;
7152
7153 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
d2beae10
JP
7154 eth_zero_addr(mac_addr);
7155 eth_zero_addr(mac_addr_mask);
ad2b26ab
JB
7156 mac_addr[0] = 0x2;
7157 mac_addr_mask[0] = 0x3;
7158
7159 return 0;
7160 }
7161
7162 /* need both or none */
7163 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
7164 return -EINVAL;
7165
7166 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
7167 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
7168
7169 /* don't allow or configure an mcast address */
7170 if (!is_multicast_ether_addr(mac_addr_mask) ||
7171 is_multicast_ether_addr(mac_addr))
7172 return -EINVAL;
7173
7174 /*
7175 * allow users to pass a MAC address that has bits set outside
7176 * of the mask, but don't bother drivers with having to deal
7177 * with such bits
7178 */
7179 for (i = 0; i < ETH_ALEN; i++)
7180 mac_addr[i] &= mac_addr_mask[i];
7181
7182 return 0;
7183}
7184
34373d12
VT
7185static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev)
7186{
7187 ASSERT_WDEV_LOCK(wdev);
7188
7189 if (!cfg80211_beaconing_iface_active(wdev))
7190 return true;
7191
7192 if (!(wdev->chandef.chan->flags & IEEE80211_CHAN_RADAR))
7193 return true;
7194
7195 return regulatory_pre_cac_allowed(wdev->wiphy);
7196}
7197
db0a4ad8
JB
7198static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
7199 enum nl80211_ext_feature_index feat)
7200{
7201 if (!(flags & flag))
7202 return true;
7203 if (wiphy_ext_feature_isset(wiphy, feat))
7204 return true;
7205 return false;
7206}
7207
2d23d073
RZ
7208static int
7209nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
7210 void *request, struct nlattr **attrs,
7211 bool is_sched_scan)
7212{
7213 u8 *mac_addr, *mac_addr_mask;
7214 u32 *flags;
7215 enum nl80211_feature_flags randomness_flag;
7216
7217 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
7218 return 0;
7219
7220 if (is_sched_scan) {
7221 struct cfg80211_sched_scan_request *req = request;
7222
7223 randomness_flag = wdev ?
7224 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
7225 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7226 flags = &req->flags;
7227 mac_addr = req->mac_addr;
7228 mac_addr_mask = req->mac_addr_mask;
7229 } else {
7230 struct cfg80211_scan_request *req = request;
7231
7232 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
7233 flags = &req->flags;
7234 mac_addr = req->mac_addr;
7235 mac_addr_mask = req->mac_addr_mask;
7236 }
7237
7238 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
7239
5037a009
SD
7240 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7241 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
db0a4ad8
JB
7242 !nl80211_check_scan_feat(wiphy, *flags,
7243 NL80211_SCAN_FLAG_LOW_SPAN,
7244 NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
7245 !nl80211_check_scan_feat(wiphy, *flags,
7246 NL80211_SCAN_FLAG_LOW_POWER,
7247 NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
7248 !nl80211_check_scan_feat(wiphy, *flags,
7249 NL80211_SCAN_FLAG_HIGH_ACCURACY,
7250 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
7251 !nl80211_check_scan_feat(wiphy, *flags,
7252 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
7253 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
7254 !nl80211_check_scan_feat(wiphy, *flags,
7255 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
7256 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
7257 !nl80211_check_scan_feat(wiphy, *flags,
7258 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
7259 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
7260 !nl80211_check_scan_feat(wiphy, *flags,
7261 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
2e076f19
JB
7262 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
7263 !nl80211_check_scan_feat(wiphy, *flags,
7264 NL80211_SCAN_FLAG_RANDOM_SN,
7265 NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
7266 !nl80211_check_scan_feat(wiphy, *flags,
7267 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
7268 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
2d23d073
RZ
7269 return -EOPNOTSUPP;
7270
7271 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7272 int err;
7273
7274 if (!(wiphy->features & randomness_flag) ||
7275 (wdev && wdev->current_bss))
7276 return -EOPNOTSUPP;
7277
7278 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
7279 if (err)
7280 return err;
7281 }
7282
2d23d073
RZ
7283 return 0;
7284}
7285
2a519311
JB
7286static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
7287{
4c476991 7288 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fd014284 7289 struct wireless_dev *wdev = info->user_ptr[1];
2a519311 7290 struct cfg80211_scan_request *request;
2a519311
JB
7291 struct nlattr *attr;
7292 struct wiphy *wiphy;
83f5e2cf 7293 int err, tmp, n_ssids = 0, n_channels, i;
70692ad2 7294 size_t ie_len;
2a519311 7295
79c97e97 7296 wiphy = &rdev->wiphy;
2a519311 7297
cb3b7d87
AB
7298 if (wdev->iftype == NL80211_IFTYPE_NAN)
7299 return -EOPNOTSUPP;
7300
4c476991
JB
7301 if (!rdev->ops->scan)
7302 return -EOPNOTSUPP;
2a519311 7303
f9d15d16 7304 if (rdev->scan_req || rdev->scan_msg) {
f9f47529
JB
7305 err = -EBUSY;
7306 goto unlock;
7307 }
2a519311
JB
7308
7309 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
83f5e2cf
JB
7310 n_channels = validate_scan_freqs(
7311 info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
f9f47529
JB
7312 if (!n_channels) {
7313 err = -EINVAL;
7314 goto unlock;
7315 }
2a519311 7316 } else {
bdfbec2d 7317 n_channels = ieee80211_get_num_supported_channels(wiphy);
2a519311
JB
7318 }
7319
7320 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
7321 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
7322 n_ssids++;
7323
f9f47529
JB
7324 if (n_ssids > wiphy->max_scan_ssids) {
7325 err = -EINVAL;
7326 goto unlock;
7327 }
2a519311 7328
70692ad2
JM
7329 if (info->attrs[NL80211_ATTR_IE])
7330 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
7331 else
7332 ie_len = 0;
7333
f9f47529
JB
7334 if (ie_len > wiphy->max_scan_ie_len) {
7335 err = -EINVAL;
7336 goto unlock;
7337 }
18a83659 7338
2a519311 7339 request = kzalloc(sizeof(*request)
a2cd43c5
LC
7340 + sizeof(*request->ssids) * n_ssids
7341 + sizeof(*request->channels) * n_channels
70692ad2 7342 + ie_len, GFP_KERNEL);
f9f47529
JB
7343 if (!request) {
7344 err = -ENOMEM;
7345 goto unlock;
7346 }
2a519311 7347
2a519311 7348 if (n_ssids)
5ba63533 7349 request->ssids = (void *)&request->channels[n_channels];
2a519311 7350 request->n_ssids = n_ssids;
70692ad2 7351 if (ie_len) {
13874e4b 7352 if (n_ssids)
70692ad2
JM
7353 request->ie = (void *)(request->ssids + n_ssids);
7354 else
7355 request->ie = (void *)(request->channels + n_channels);
7356 }
2a519311 7357
584991dc 7358 i = 0;
2a519311
JB
7359 if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
7360 /* user specified, bail out if channel not found */
2a519311 7361 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
584991dc
JB
7362 struct ieee80211_channel *chan;
7363
7364 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
7365
7366 if (!chan) {
2a519311
JB
7367 err = -EINVAL;
7368 goto out_free;
7369 }
584991dc
JB
7370
7371 /* ignore disabled channels */
7372 if (chan->flags & IEEE80211_CHAN_DISABLED)
7373 continue;
7374
7375 request->channels[i] = chan;
2a519311
JB
7376 i++;
7377 }
7378 } else {
57fbcce3 7379 enum nl80211_band band;
34850ab2 7380
2a519311 7381 /* all channels */
57fbcce3 7382 for (band = 0; band < NUM_NL80211_BANDS; band++) {
2a519311 7383 int j;
7a087e74 7384
2a519311
JB
7385 if (!wiphy->bands[band])
7386 continue;
7387 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
584991dc
JB
7388 struct ieee80211_channel *chan;
7389
7390 chan = &wiphy->bands[band]->channels[j];
7391
7392 if (chan->flags & IEEE80211_CHAN_DISABLED)
7393 continue;
7394
7395 request->channels[i] = chan;
2a519311
JB
7396 i++;
7397 }
7398 }
7399 }
7400
584991dc
JB
7401 if (!i) {
7402 err = -EINVAL;
7403 goto out_free;
7404 }
7405
7406 request->n_channels = i;
7407
34373d12
VT
7408 wdev_lock(wdev);
7409 if (!cfg80211_off_channel_oper_allowed(wdev)) {
7410 struct ieee80211_channel *chan;
7411
7412 if (request->n_channels != 1) {
7413 wdev_unlock(wdev);
7414 err = -EBUSY;
7415 goto out_free;
7416 }
7417
7418 chan = request->channels[0];
7419 if (chan->center_freq != wdev->chandef.chan->center_freq) {
7420 wdev_unlock(wdev);
7421 err = -EBUSY;
7422 goto out_free;
7423 }
7424 }
7425 wdev_unlock(wdev);
7426
2a519311 7427 i = 0;
13874e4b 7428 if (n_ssids) {
2a519311 7429 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
57a27e1d 7430 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
2a519311
JB
7431 err = -EINVAL;
7432 goto out_free;
7433 }
57a27e1d 7434 request->ssids[i].ssid_len = nla_len(attr);
2a519311 7435 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
2a519311
JB
7436 i++;
7437 }
7438 }
7439
70692ad2
JM
7440 if (info->attrs[NL80211_ATTR_IE]) {
7441 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
de95a54b
JB
7442 memcpy((void *)request->ie,
7443 nla_data(info->attrs[NL80211_ATTR_IE]),
70692ad2
JM
7444 request->ie_len);
7445 }
7446
57fbcce3 7447 for (i = 0; i < NUM_NL80211_BANDS; i++)
a401d2bb
JB
7448 if (wiphy->bands[i])
7449 request->rates[i] =
7450 (1 << wiphy->bands[i]->n_bitrates) - 1;
34850ab2
JB
7451
7452 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
7453 nla_for_each_nested(attr,
7454 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
7455 tmp) {
57fbcce3 7456 enum nl80211_band band = nla_type(attr);
34850ab2 7457
57fbcce3 7458 if (band < 0 || band >= NUM_NL80211_BANDS) {
34850ab2
JB
7459 err = -EINVAL;
7460 goto out_free;
7461 }
1b09cd82
FF
7462
7463 if (!wiphy->bands[band])
7464 continue;
7465
34850ab2
JB
7466 err = ieee80211_get_ratemask(wiphy->bands[band],
7467 nla_data(attr),
7468 nla_len(attr),
7469 &request->rates[band]);
7470 if (err)
7471 goto out_free;
7472 }
7473 }
7474
1d76250b
AS
7475 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
7476 if (!wiphy_ext_feature_isset(wiphy,
7477 NL80211_EXT_FEATURE_SET_SCAN_DWELL)) {
7478 err = -EOPNOTSUPP;
7479 goto out_free;
7480 }
7481
7482 request->duration =
7483 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
7484 request->duration_mandatory =
7485 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
7486 }
7487
2d23d073
RZ
7488 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
7489 false);
7490 if (err)
7491 goto out_free;
ed473771 7492
e9f935e3
RM
7493 request->no_cck =
7494 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
7495
2fa436b3
VK
7496 /* Initial implementation used NL80211_ATTR_MAC to set the specific
7497 * BSSID to scan for. This was problematic because that same attribute
7498 * was already used for another purpose (local random MAC address). The
7499 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
7500 * compatibility with older userspace components, also use the
7501 * NL80211_ATTR_MAC value here if it can be determined to be used for
7502 * the specific BSSID use case instead of the random MAC address
7503 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
7504 */
7505 if (info->attrs[NL80211_ATTR_BSSID])
7506 memcpy(request->bssid,
7507 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
7508 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
7509 info->attrs[NL80211_ATTR_MAC])
818965d3
JM
7510 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
7511 ETH_ALEN);
7512 else
7513 eth_broadcast_addr(request->bssid);
7514
fd014284 7515 request->wdev = wdev;
79c97e97 7516 request->wiphy = &rdev->wiphy;
15d6030b 7517 request->scan_start = jiffies;
2a519311 7518
79c97e97 7519 rdev->scan_req = request;
e35e4d28 7520 err = rdev_scan(rdev, request);
2a519311 7521
463d0183 7522 if (!err) {
fd014284
JB
7523 nl80211_send_scan_start(rdev, wdev);
7524 if (wdev->netdev)
7525 dev_hold(wdev->netdev);
4c476991 7526 } else {
2a519311 7527 out_free:
79c97e97 7528 rdev->scan_req = NULL;
2a519311
JB
7529 kfree(request);
7530 }
3b85875a 7531
f9f47529 7532 unlock:
2a519311
JB
7533 return err;
7534}
7535
91d3ab46
VK
7536static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
7537{
7538 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7539 struct wireless_dev *wdev = info->user_ptr[1];
7540
7541 if (!rdev->ops->abort_scan)
7542 return -EOPNOTSUPP;
7543
7544 if (rdev->scan_msg)
7545 return 0;
7546
7547 if (!rdev->scan_req)
7548 return -ENOENT;
7549
7550 rdev_abort_scan(rdev, wdev);
7551 return 0;
7552}
7553
3b06d277
AS
7554static int
7555nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
7556 struct cfg80211_sched_scan_request *request,
7557 struct nlattr **attrs)
7558{
7559 int tmp, err, i = 0;
7560 struct nlattr *attr;
7561
7562 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
7563 u32 interval;
7564
7565 /*
7566 * If scan plans are not specified,
5a88de53 7567 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
3b06d277
AS
7568 * case one scan plan will be set with the specified scan
7569 * interval and infinite number of iterations.
7570 */
3b06d277
AS
7571 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
7572 if (!interval)
7573 return -EINVAL;
7574
7575 request->scan_plans[0].interval =
7576 DIV_ROUND_UP(interval, MSEC_PER_SEC);
7577 if (!request->scan_plans[0].interval)
7578 return -EINVAL;
7579
7580 if (request->scan_plans[0].interval >
7581 wiphy->max_sched_scan_plan_interval)
7582 request->scan_plans[0].interval =
7583 wiphy->max_sched_scan_plan_interval;
7584
7585 return 0;
7586 }
7587
7588 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
7589 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
7590
7591 if (WARN_ON(i >= n_plans))
7592 return -EINVAL;
7593
8cb08174
JB
7594 err = nla_parse_nested_deprecated(plan,
7595 NL80211_SCHED_SCAN_PLAN_MAX,
7596 attr, nl80211_plan_policy,
7597 NULL);
3b06d277
AS
7598 if (err)
7599 return err;
7600
7601 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
7602 return -EINVAL;
7603
7604 request->scan_plans[i].interval =
7605 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
7606 if (!request->scan_plans[i].interval ||
7607 request->scan_plans[i].interval >
7608 wiphy->max_sched_scan_plan_interval)
7609 return -EINVAL;
7610
7611 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
7612 request->scan_plans[i].iterations =
7613 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
7614 if (!request->scan_plans[i].iterations ||
7615 (request->scan_plans[i].iterations >
7616 wiphy->max_sched_scan_plan_iterations))
7617 return -EINVAL;
7618 } else if (i < n_plans - 1) {
7619 /*
7620 * All scan plans but the last one must specify
7621 * a finite number of iterations
7622 */
7623 return -EINVAL;
7624 }
7625
7626 i++;
7627 }
7628
7629 /*
7630 * The last scan plan must not specify the number of
7631 * iterations, it is supposed to run infinitely
7632 */
7633 if (request->scan_plans[n_plans - 1].iterations)
7634 return -EINVAL;
7635
7636 return 0;
7637}
7638
1e1b11b6 7639static int
7640nl80211_parse_sched_scan_per_band_rssi(struct wiphy *wiphy,
7641 struct cfg80211_match_set *match_sets,
7642 struct nlattr *tb_band_rssi,
7643 s32 rssi_thold)
7644{
7645 struct nlattr *attr;
7646 int i, tmp, ret = 0;
7647
7648 if (!wiphy_ext_feature_isset(wiphy,
7649 NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD)) {
7650 if (tb_band_rssi)
7651 ret = -EOPNOTSUPP;
7652 else
7653 for (i = 0; i < NUM_NL80211_BANDS; i++)
7654 match_sets->per_band_rssi_thold[i] =
7655 NL80211_SCAN_RSSI_THOLD_OFF;
7656 return ret;
7657 }
7658
7659 for (i = 0; i < NUM_NL80211_BANDS; i++)
7660 match_sets->per_band_rssi_thold[i] = rssi_thold;
7661
7662 nla_for_each_nested(attr, tb_band_rssi, tmp) {
7663 enum nl80211_band band = nla_type(attr);
7664
7665 if (band < 0 || band >= NUM_NL80211_BANDS)
7666 return -EINVAL;
7667
7668 match_sets->per_band_rssi_thold[band] = nla_get_s32(attr);
7669 }
7670
7671 return 0;
7672}
7673
256da02d 7674static struct cfg80211_sched_scan_request *
ad2b26ab 7675nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
aad1e812 7676 struct nlattr **attrs, int max_match_sets)
807f8a8c
LC
7677{
7678 struct cfg80211_sched_scan_request *request;
807f8a8c 7679 struct nlattr *attr;
3b06d277 7680 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
57fbcce3 7681 enum nl80211_band band;
807f8a8c 7682 size_t ie_len;
a1f1c21c 7683 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
ea73cbce 7684 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
807f8a8c 7685
256da02d 7686 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c 7687 n_channels = validate_scan_freqs(
256da02d 7688 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
807f8a8c 7689 if (!n_channels)
256da02d 7690 return ERR_PTR(-EINVAL);
807f8a8c 7691 } else {
bdfbec2d 7692 n_channels = ieee80211_get_num_supported_channels(wiphy);
807f8a8c
LC
7693 }
7694
256da02d
LC
7695 if (attrs[NL80211_ATTR_SCAN_SSIDS])
7696 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c
LC
7697 tmp)
7698 n_ssids++;
7699
93b6aa69 7700 if (n_ssids > wiphy->max_sched_scan_ssids)
256da02d 7701 return ERR_PTR(-EINVAL);
807f8a8c 7702
ea73cbce
JB
7703 /*
7704 * First, count the number of 'real' matchsets. Due to an issue with
7705 * the old implementation, matchsets containing only the RSSI attribute
7706 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
7707 * RSSI for all matchsets, rather than their own matchset for reporting
7708 * all APs with a strong RSSI. This is needed to be compatible with
7709 * older userspace that treated a matchset with only the RSSI as the
7710 * global RSSI for all other matchsets - if there are other matchsets.
7711 */
256da02d 7712 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7713 nla_for_each_nested(attr,
256da02d 7714 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
ea73cbce
JB
7715 tmp) {
7716 struct nlattr *rssi;
7717
8cb08174
JB
7718 err = nla_parse_nested_deprecated(tb,
7719 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
7720 attr,
7721 nl80211_match_policy,
7722 NULL);
ea73cbce 7723 if (err)
256da02d 7724 return ERR_PTR(err);
3007e352
AVS
7725
7726 /* SSID and BSSID are mutually exclusive */
7727 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
7728 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
7729 return ERR_PTR(-EINVAL);
7730
ea73cbce 7731 /* add other standalone attributes here */
3007e352
AVS
7732 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
7733 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
ea73cbce
JB
7734 n_match_sets++;
7735 continue;
7736 }
7737 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7738 if (rssi)
7739 default_match_rssi = nla_get_s32(rssi);
7740 }
7741 }
7742
7743 /* However, if there's no other matchset, add the RSSI one */
7744 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
7745 n_match_sets = 1;
a1f1c21c 7746
aad1e812 7747 if (n_match_sets > max_match_sets)
256da02d 7748 return ERR_PTR(-EINVAL);
a1f1c21c 7749
256da02d
LC
7750 if (attrs[NL80211_ATTR_IE])
7751 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
807f8a8c
LC
7752 else
7753 ie_len = 0;
7754
5a865bad 7755 if (ie_len > wiphy->max_sched_scan_ie_len)
256da02d 7756 return ERR_PTR(-EINVAL);
c10841ca 7757
3b06d277
AS
7758 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
7759 /*
7760 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
7761 * each scan plan already specifies its own interval
7762 */
7763 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
7764 return ERR_PTR(-EINVAL);
7765
7766 nla_for_each_nested(attr,
7767 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
7768 n_plans++;
7769 } else {
7770 /*
7771 * The scan interval attribute is kept for backward
7772 * compatibility. If no scan plans are specified and sched scan
7773 * interval is specified, one scan plan will be set with this
7774 * scan interval and infinite number of iterations.
7775 */
7776 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
7777 return ERR_PTR(-EINVAL);
7778
7779 n_plans = 1;
7780 }
7781
7782 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
7783 return ERR_PTR(-EINVAL);
7784
bf95ecdb 7785 if (!wiphy_ext_feature_isset(
7786 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
7787 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
7788 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
7789 return ERR_PTR(-EINVAL);
7790
807f8a8c 7791 request = kzalloc(sizeof(*request)
a2cd43c5 7792 + sizeof(*request->ssids) * n_ssids
a1f1c21c 7793 + sizeof(*request->match_sets) * n_match_sets
3b06d277 7794 + sizeof(*request->scan_plans) * n_plans
a2cd43c5 7795 + sizeof(*request->channels) * n_channels
807f8a8c 7796 + ie_len, GFP_KERNEL);
256da02d
LC
7797 if (!request)
7798 return ERR_PTR(-ENOMEM);
807f8a8c
LC
7799
7800 if (n_ssids)
7801 request->ssids = (void *)&request->channels[n_channels];
7802 request->n_ssids = n_ssids;
7803 if (ie_len) {
13874e4b 7804 if (n_ssids)
807f8a8c
LC
7805 request->ie = (void *)(request->ssids + n_ssids);
7806 else
7807 request->ie = (void *)(request->channels + n_channels);
7808 }
7809
a1f1c21c
LC
7810 if (n_match_sets) {
7811 if (request->ie)
7812 request->match_sets = (void *)(request->ie + ie_len);
13874e4b 7813 else if (n_ssids)
a1f1c21c
LC
7814 request->match_sets =
7815 (void *)(request->ssids + n_ssids);
7816 else
7817 request->match_sets =
7818 (void *)(request->channels + n_channels);
7819 }
7820 request->n_match_sets = n_match_sets;
7821
3b06d277
AS
7822 if (n_match_sets)
7823 request->scan_plans = (void *)(request->match_sets +
7824 n_match_sets);
7825 else if (request->ie)
7826 request->scan_plans = (void *)(request->ie + ie_len);
7827 else if (n_ssids)
7828 request->scan_plans = (void *)(request->ssids + n_ssids);
7829 else
7830 request->scan_plans = (void *)(request->channels + n_channels);
7831
7832 request->n_scan_plans = n_plans;
7833
807f8a8c 7834 i = 0;
256da02d 7835 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
807f8a8c
LC
7836 /* user specified, bail out if channel not found */
7837 nla_for_each_nested(attr,
256da02d 7838 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
807f8a8c
LC
7839 tmp) {
7840 struct ieee80211_channel *chan;
7841
7842 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
7843
7844 if (!chan) {
7845 err = -EINVAL;
7846 goto out_free;
7847 }
7848
7849 /* ignore disabled channels */
7850 if (chan->flags & IEEE80211_CHAN_DISABLED)
7851 continue;
7852
7853 request->channels[i] = chan;
7854 i++;
7855 }
7856 } else {
7857 /* all channels */
57fbcce3 7858 for (band = 0; band < NUM_NL80211_BANDS; band++) {
807f8a8c 7859 int j;
7a087e74 7860
807f8a8c
LC
7861 if (!wiphy->bands[band])
7862 continue;
7863 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
7864 struct ieee80211_channel *chan;
7865
7866 chan = &wiphy->bands[band]->channels[j];
7867
7868 if (chan->flags & IEEE80211_CHAN_DISABLED)
7869 continue;
7870
7871 request->channels[i] = chan;
7872 i++;
7873 }
7874 }
7875 }
7876
7877 if (!i) {
7878 err = -EINVAL;
7879 goto out_free;
7880 }
7881
7882 request->n_channels = i;
7883
7884 i = 0;
13874e4b 7885 if (n_ssids) {
256da02d 7886 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
807f8a8c 7887 tmp) {
57a27e1d 7888 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
807f8a8c
LC
7889 err = -EINVAL;
7890 goto out_free;
7891 }
57a27e1d 7892 request->ssids[i].ssid_len = nla_len(attr);
807f8a8c
LC
7893 memcpy(request->ssids[i].ssid, nla_data(attr),
7894 nla_len(attr));
807f8a8c
LC
7895 i++;
7896 }
7897 }
7898
a1f1c21c 7899 i = 0;
256da02d 7900 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
a1f1c21c 7901 nla_for_each_nested(attr,
256da02d 7902 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
a1f1c21c 7903 tmp) {
3007e352 7904 struct nlattr *ssid, *bssid, *rssi;
a1f1c21c 7905
8cb08174
JB
7906 err = nla_parse_nested_deprecated(tb,
7907 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
7908 attr,
7909 nl80211_match_policy,
7910 NULL);
ae811e21
JB
7911 if (err)
7912 goto out_free;
4a4ab0d7 7913 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
3007e352 7914 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
d39f3b4f
JB
7915
7916 if (!ssid && !bssid) {
7917 i++;
7918 continue;
7919 }
7920
7921 if (WARN_ON(i >= n_match_sets)) {
7922 /* this indicates a programming error,
7923 * the loop above should have verified
7924 * things properly
7925 */
7926 err = -EINVAL;
7927 goto out_free;
7928 }
7929
7930 if (ssid) {
7931 if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
ea73cbce
JB
7932 err = -EINVAL;
7933 goto out_free;
7934 }
d39f3b4f
JB
7935 memcpy(request->match_sets[i].ssid.ssid,
7936 nla_data(ssid), nla_len(ssid));
7937 request->match_sets[i].ssid.ssid_len =
7938 nla_len(ssid);
7939 }
7940 if (bssid) {
7941 if (nla_len(bssid) != ETH_ALEN) {
7942 err = -EINVAL;
7943 goto out_free;
a1f1c21c 7944 }
d39f3b4f
JB
7945 memcpy(request->match_sets[i].bssid,
7946 nla_data(bssid), ETH_ALEN);
7947 }
3007e352 7948
d39f3b4f
JB
7949 /* special attribute - old implementation w/a */
7950 request->match_sets[i].rssi_thold = default_match_rssi;
7951 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
7952 if (rssi)
ea73cbce 7953 request->match_sets[i].rssi_thold =
d39f3b4f 7954 nla_get_s32(rssi);
1e1b11b6 7955
7956 /* Parse per band RSSI attribute */
7957 err = nl80211_parse_sched_scan_per_band_rssi(wiphy,
7958 &request->match_sets[i],
7959 tb[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI],
7960 request->match_sets[i].rssi_thold);
7961 if (err)
7962 goto out_free;
7963
a1f1c21c
LC
7964 i++;
7965 }
ea73cbce
JB
7966
7967 /* there was no other matchset, so the RSSI one is alone */
f89f46cf 7968 if (i == 0 && n_match_sets)
ea73cbce
JB
7969 request->match_sets[0].rssi_thold = default_match_rssi;
7970
7971 request->min_rssi_thold = INT_MAX;
7972 for (i = 0; i < n_match_sets; i++)
7973 request->min_rssi_thold =
7974 min(request->match_sets[i].rssi_thold,
7975 request->min_rssi_thold);
7976 } else {
7977 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
a1f1c21c
LC
7978 }
7979
9900e484
JB
7980 if (ie_len) {
7981 request->ie_len = ie_len;
807f8a8c 7982 memcpy((void *)request->ie,
256da02d 7983 nla_data(attrs[NL80211_ATTR_IE]),
807f8a8c
LC
7984 request->ie_len);
7985 }
7986
2d23d073
RZ
7987 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
7988 if (err)
7989 goto out_free;
ed473771 7990
9c748934
LC
7991 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
7992 request->delay =
7993 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
7994
bf95ecdb 7995 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
7996 request->relative_rssi = nla_get_s8(
7997 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
7998 request->relative_rssi_set = true;
7999 }
8000
8001 if (request->relative_rssi_set &&
8002 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
8003 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
8004
8005 rssi_adjust = nla_data(
8006 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
8007 request->rssi_adjust.band = rssi_adjust->band;
8008 request->rssi_adjust.delta = rssi_adjust->delta;
8009 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
8010 err = -EINVAL;
8011 goto out_free;
8012 }
8013 }
8014
3b06d277
AS
8015 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
8016 if (err)
8017 goto out_free;
8018
15d6030b 8019 request->scan_start = jiffies;
807f8a8c 8020
256da02d 8021 return request;
807f8a8c
LC
8022
8023out_free:
8024 kfree(request);
256da02d
LC
8025 return ERR_PTR(err);
8026}
8027
8028static int nl80211_start_sched_scan(struct sk_buff *skb,
8029 struct genl_info *info)
8030{
8031 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8032 struct net_device *dev = info->user_ptr[1];
ad2b26ab 8033 struct wireless_dev *wdev = dev->ieee80211_ptr;
31a60ed1 8034 struct cfg80211_sched_scan_request *sched_scan_req;
ca986ad9 8035 bool want_multi;
256da02d
LC
8036 int err;
8037
ca986ad9 8038 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
256da02d
LC
8039 return -EOPNOTSUPP;
8040
ca986ad9
AVS
8041 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
8042 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
8043 if (err)
8044 return err;
256da02d 8045
31a60ed1 8046 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
aad1e812
AVS
8047 info->attrs,
8048 rdev->wiphy.max_match_sets);
31a60ed1
JR
8049
8050 err = PTR_ERR_OR_ZERO(sched_scan_req);
256da02d
LC
8051 if (err)
8052 goto out_err;
8053
ca986ad9
AVS
8054 /* leave request id zero for legacy request
8055 * or if driver does not support multi-scheduled scan
8056 */
8057 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1) {
8058 while (!sched_scan_req->reqid)
b60ad348 8059 sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
ca986ad9
AVS
8060 }
8061
31a60ed1 8062 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
256da02d
LC
8063 if (err)
8064 goto out_free;
8065
31a60ed1
JR
8066 sched_scan_req->dev = dev;
8067 sched_scan_req->wiphy = &rdev->wiphy;
8068
93a1e86c
JR
8069 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
8070 sched_scan_req->owner_nlportid = info->snd_portid;
8071
ca986ad9 8072 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
256da02d 8073
96b08fd6 8074 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
256da02d
LC
8075 return 0;
8076
8077out_free:
31a60ed1 8078 kfree(sched_scan_req);
256da02d 8079out_err:
807f8a8c
LC
8080 return err;
8081}
8082
8083static int nl80211_stop_sched_scan(struct sk_buff *skb,
8084 struct genl_info *info)
8085{
ca986ad9 8086 struct cfg80211_sched_scan_request *req;
807f8a8c 8087 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ca986ad9 8088 u64 cookie;
807f8a8c 8089
ca986ad9 8090 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
807f8a8c
LC
8091 return -EOPNOTSUPP;
8092
ca986ad9
AVS
8093 if (info->attrs[NL80211_ATTR_COOKIE]) {
8094 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
8095 return __cfg80211_stop_sched_scan(rdev, cookie, false);
8096 }
8097
8098 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
8099 struct cfg80211_sched_scan_request,
8100 list);
8101 if (!req || req->reqid ||
8102 (req->owner_nlportid &&
8103 req->owner_nlportid != info->snd_portid))
8104 return -ENOENT;
8105
8106 return cfg80211_stop_sched_scan_req(rdev, req, false);
807f8a8c
LC
8107}
8108
04f39047
SW
8109static int nl80211_start_radar_detection(struct sk_buff *skb,
8110 struct genl_info *info)
8111{
8112 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8113 struct net_device *dev = info->user_ptr[1];
8114 struct wireless_dev *wdev = dev->ieee80211_ptr;
13cf6dec 8115 struct wiphy *wiphy = wdev->wiphy;
04f39047 8116 struct cfg80211_chan_def chandef;
55f7435c 8117 enum nl80211_dfs_regions dfs_region;
31559f35 8118 unsigned int cac_time_ms;
04f39047
SW
8119 int err;
8120
13cf6dec 8121 dfs_region = reg_get_dfs_region(wiphy);
55f7435c
LR
8122 if (dfs_region == NL80211_DFS_UNSET)
8123 return -EINVAL;
8124
04f39047
SW
8125 err = nl80211_parse_chandef(rdev, info, &chandef);
8126 if (err)
8127 return err;
8128
ff311bc1
SW
8129 if (netif_carrier_ok(dev))
8130 return -EBUSY;
8131
04f39047
SW
8132 if (wdev->cac_started)
8133 return -EBUSY;
8134
13cf6dec 8135 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
04f39047
SW
8136 if (err < 0)
8137 return err;
8138
8139 if (err == 0)
8140 return -EINVAL;
8141
13cf6dec 8142 if (!cfg80211_chandef_dfs_usable(wiphy, &chandef))
04f39047
SW
8143 return -EINVAL;
8144
13cf6dec
DL
8145 /* CAC start is offloaded to HW and can't be started manually */
8146 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD))
8147 return -EOPNOTSUPP;
8148
04f39047
SW
8149 if (!rdev->ops->start_radar_detection)
8150 return -EOPNOTSUPP;
8151
31559f35
JD
8152 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
8153 if (WARN_ON(!cac_time_ms))
8154 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
8155
a1056b1b 8156 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms);
04f39047 8157 if (!err) {
9e0e2961 8158 wdev->chandef = chandef;
04f39047
SW
8159 wdev->cac_started = true;
8160 wdev->cac_start_time = jiffies;
31559f35 8161 wdev->cac_time_ms = cac_time_ms;
04f39047 8162 }
04f39047
SW
8163 return err;
8164}
8165
30c63115
S
8166static int nl80211_notify_radar_detection(struct sk_buff *skb,
8167 struct genl_info *info)
8168{
8169 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8170 struct net_device *dev = info->user_ptr[1];
8171 struct wireless_dev *wdev = dev->ieee80211_ptr;
8172 struct wiphy *wiphy = wdev->wiphy;
8173 struct cfg80211_chan_def chandef;
8174 enum nl80211_dfs_regions dfs_region;
8175 int err;
8176
8177 dfs_region = reg_get_dfs_region(wiphy);
8178 if (dfs_region == NL80211_DFS_UNSET) {
8179 GENL_SET_ERR_MSG(info,
8180 "DFS Region is not set. Unexpected Radar indication");
8181 return -EINVAL;
8182 }
8183
8184 err = nl80211_parse_chandef(rdev, info, &chandef);
8185 if (err) {
8186 GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
8187 return err;
8188 }
8189
8190 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
8191 if (err < 0) {
8192 GENL_SET_ERR_MSG(info, "chandef is invalid");
8193 return err;
8194 }
8195
8196 if (err == 0) {
8197 GENL_SET_ERR_MSG(info,
8198 "Unexpected Radar indication for chandef/iftype");
8199 return -EINVAL;
8200 }
8201
8202 /* Do not process this notification if radar is already detected
8203 * by kernel on this channel, and return success.
8204 */
8205 if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
8206 return 0;
8207
8208 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
8209
8210 cfg80211_sched_dfs_chan_update(rdev);
8211
a680fe46 8212 rdev->radar_chandef = chandef;
30c63115
S
8213
8214 /* Propagate this notification to other radios as well */
8215 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
8216
8217 return 0;
8218}
8219
16ef1fe2
SW
8220static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
8221{
8222 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8223 struct net_device *dev = info->user_ptr[1];
8224 struct wireless_dev *wdev = dev->ieee80211_ptr;
8225 struct cfg80211_csa_settings params;
8226 /* csa_attrs is defined static to avoid waste of stack size - this
8227 * function is called under RTNL lock, so this should not be a problem.
8228 */
8229 static struct nlattr *csa_attrs[NL80211_ATTR_MAX+1];
16ef1fe2 8230 int err;
ee4bc9e7 8231 bool need_new_beacon = false;
8d9de16f 8232 bool need_handle_dfs_flag = true;
9a774c78 8233 int len, i;
252e07ca 8234 u32 cs_count;
16ef1fe2
SW
8235
8236 if (!rdev->ops->channel_switch ||
8237 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
8238 return -EOPNOTSUPP;
8239
ee4bc9e7
SW
8240 switch (dev->ieee80211_ptr->iftype) {
8241 case NL80211_IFTYPE_AP:
8242 case NL80211_IFTYPE_P2P_GO:
8243 need_new_beacon = true;
8d9de16f
BB
8244 /* For all modes except AP the handle_dfs flag needs to be
8245 * supplied to tell the kernel that userspace will handle radar
8246 * events when they happen. Otherwise a switch to a channel
8247 * requiring DFS will be rejected.
8248 */
8249 need_handle_dfs_flag = false;
ee4bc9e7
SW
8250
8251 /* useless if AP is not running */
8252 if (!wdev->beacon_interval)
1ff79dfa 8253 return -ENOTCONN;
ee4bc9e7
SW
8254 break;
8255 case NL80211_IFTYPE_ADHOC:
1ff79dfa
JB
8256 if (!wdev->ssid_len)
8257 return -ENOTCONN;
8258 break;
c6da674a 8259 case NL80211_IFTYPE_MESH_POINT:
1ff79dfa
JB
8260 if (!wdev->mesh_id_len)
8261 return -ENOTCONN;
ee4bc9e7
SW
8262 break;
8263 default:
16ef1fe2 8264 return -EOPNOTSUPP;
ee4bc9e7 8265 }
16ef1fe2
SW
8266
8267 memset(&params, 0, sizeof(params));
c177db2d 8268 params.beacon_csa.ftm_responder = -1;
16ef1fe2
SW
8269
8270 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
8271 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
8272 return -EINVAL;
8273
8274 /* only important for AP, IBSS and mesh create IEs internally */
d0a361a5 8275 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
16ef1fe2
SW
8276 return -EINVAL;
8277
252e07ca
LC
8278 /* Even though the attribute is u32, the specification says
8279 * u8, so let's make sure we don't overflow.
8280 */
8281 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
8282 if (cs_count > 255)
8283 return -EINVAL;
8284
8285 params.count = cs_count;
16ef1fe2 8286
ee4bc9e7
SW
8287 if (!need_new_beacon)
8288 goto skip_beacons;
8289
81e54d08 8290 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after);
16ef1fe2
SW
8291 if (err)
8292 return err;
8293
8cb08174
JB
8294 err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
8295 info->attrs[NL80211_ATTR_CSA_IES],
8296 nl80211_policy, info->extack);
16ef1fe2
SW
8297 if (err)
8298 return err;
8299
81e54d08 8300 err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa);
16ef1fe2
SW
8301 if (err)
8302 return err;
8303
8304 if (!csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON])
8305 return -EINVAL;
8306
9a774c78
AO
8307 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
8308 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
8309 return -EINVAL;
8310
9a774c78
AO
8311 params.n_counter_offsets_beacon = len / sizeof(u16);
8312 if (rdev->wiphy.max_num_csa_counters &&
8313 (params.n_counter_offsets_beacon >
8314 rdev->wiphy.max_num_csa_counters))
16ef1fe2
SW
8315 return -EINVAL;
8316
9a774c78
AO
8317 params.counter_offsets_beacon =
8318 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_BEACON]);
8319
8320 /* sanity checks - counters should fit and be the same */
8321 for (i = 0; i < params.n_counter_offsets_beacon; i++) {
8322 u16 offset = params.counter_offsets_beacon[i];
8323
8324 if (offset >= params.beacon_csa.tail_len)
8325 return -EINVAL;
8326
8327 if (params.beacon_csa.tail[offset] != params.count)
8328 return -EINVAL;
8329 }
8330
16ef1fe2 8331 if (csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]) {
9a774c78
AO
8332 len = nla_len(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
8333 if (!len || (len % sizeof(u16)))
16ef1fe2
SW
8334 return -EINVAL;
8335
9a774c78
AO
8336 params.n_counter_offsets_presp = len / sizeof(u16);
8337 if (rdev->wiphy.max_num_csa_counters &&
ad5987b4 8338 (params.n_counter_offsets_presp >
9a774c78 8339 rdev->wiphy.max_num_csa_counters))
16ef1fe2 8340 return -EINVAL;
9a774c78
AO
8341
8342 params.counter_offsets_presp =
8343 nla_data(csa_attrs[NL80211_ATTR_CSA_C_OFF_PRESP]);
8344
8345 /* sanity checks - counters should fit and be the same */
8346 for (i = 0; i < params.n_counter_offsets_presp; i++) {
8347 u16 offset = params.counter_offsets_presp[i];
8348
8349 if (offset >= params.beacon_csa.probe_resp_len)
8350 return -EINVAL;
8351
8352 if (params.beacon_csa.probe_resp[offset] !=
8353 params.count)
8354 return -EINVAL;
8355 }
16ef1fe2
SW
8356 }
8357
ee4bc9e7 8358skip_beacons:
16ef1fe2
SW
8359 err = nl80211_parse_chandef(rdev, info, &params.chandef);
8360 if (err)
8361 return err;
8362
923b352f
AN
8363 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
8364 wdev->iftype))
16ef1fe2
SW
8365 return -EINVAL;
8366
2beb6dab
LC
8367 err = cfg80211_chandef_dfs_required(wdev->wiphy,
8368 &params.chandef,
8369 wdev->iftype);
8370 if (err < 0)
8371 return err;
8372
8d9de16f 8373 if (err > 0) {
2beb6dab 8374 params.radar_required = true;
8d9de16f
BB
8375 if (need_handle_dfs_flag &&
8376 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
8377 return -EINVAL;
8378 }
8379 }
16ef1fe2 8380
16ef1fe2
SW
8381 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
8382 params.block_tx = true;
8383
c56589ed
SW
8384 wdev_lock(wdev);
8385 err = rdev_channel_switch(rdev, dev, &params);
8386 wdev_unlock(wdev);
8387
8388 return err;
16ef1fe2
SW
8389}
8390
9720bb3a
JB
8391static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
8392 u32 seq, int flags,
2a519311 8393 struct cfg80211_registered_device *rdev,
48ab905d
JB
8394 struct wireless_dev *wdev,
8395 struct cfg80211_internal_bss *intbss)
2a519311 8396{
48ab905d 8397 struct cfg80211_bss *res = &intbss->pub;
9caf0364 8398 const struct cfg80211_bss_ies *ies;
2a519311
JB
8399 void *hdr;
8400 struct nlattr *bss;
48ab905d
JB
8401
8402 ASSERT_WDEV_LOCK(wdev);
2a519311 8403
15e47304 8404 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
2a519311
JB
8405 NL80211_CMD_NEW_SCAN_RESULTS);
8406 if (!hdr)
8407 return -1;
8408
0a833c29 8409 genl_dump_check_consistent(cb, hdr);
9720bb3a 8410
97990a06
JB
8411 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
8412 goto nla_put_failure;
8413 if (wdev->netdev &&
9360ffd1
DM
8414 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
8415 goto nla_put_failure;
2dad624e
ND
8416 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
8417 NL80211_ATTR_PAD))
97990a06 8418 goto nla_put_failure;
2a519311 8419
ae0be8de 8420 bss = nla_nest_start_noflag(msg, NL80211_ATTR_BSS);
2a519311
JB
8421 if (!bss)
8422 goto nla_put_failure;
9360ffd1 8423 if ((!is_zero_ether_addr(res->bssid) &&
9caf0364 8424 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
9360ffd1 8425 goto nla_put_failure;
9caf0364
JB
8426
8427 rcu_read_lock();
0e227084
JB
8428 /* indicate whether we have probe response data or not */
8429 if (rcu_access_pointer(res->proberesp_ies) &&
8430 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
8431 goto fail_unlock_rcu;
8432
8433 /* this pointer prefers to be pointed to probe response data
8434 * but is always valid
8435 */
9caf0364 8436 ies = rcu_dereference(res->ies);
8cef2c9d 8437 if (ies) {
2dad624e
ND
8438 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
8439 NL80211_BSS_PAD))
8cef2c9d 8440 goto fail_unlock_rcu;
8cef2c9d
JB
8441 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
8442 ies->len, ies->data))
8443 goto fail_unlock_rcu;
9caf0364 8444 }
0e227084
JB
8445
8446 /* and this pointer is always (unless driver didn't know) beacon data */
9caf0364 8447 ies = rcu_dereference(res->beacon_ies);
0e227084 8448 if (ies && ies->from_beacon) {
2dad624e
ND
8449 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
8450 NL80211_BSS_PAD))
8cef2c9d
JB
8451 goto fail_unlock_rcu;
8452 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
8453 ies->len, ies->data))
8454 goto fail_unlock_rcu;
9caf0364
JB
8455 }
8456 rcu_read_unlock();
8457
9360ffd1
DM
8458 if (res->beacon_interval &&
8459 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
8460 goto nla_put_failure;
8461 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
8462 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
dcd6eac1 8463 nla_put_u32(msg, NL80211_BSS_CHAN_WIDTH, res->scan_width) ||
9360ffd1
DM
8464 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
8465 jiffies_to_msecs(jiffies - intbss->ts)))
8466 goto nla_put_failure;
2a519311 8467
1d76250b
AS
8468 if (intbss->parent_tsf &&
8469 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
8470 intbss->parent_tsf, NL80211_BSS_PAD) ||
8471 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
8472 intbss->parent_bssid)))
8473 goto nla_put_failure;
8474
6e19bc4b 8475 if (intbss->ts_boottime &&
2dad624e
ND
8476 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
8477 intbss->ts_boottime, NL80211_BSS_PAD))
6e19bc4b
DS
8478 goto nla_put_failure;
8479
983dafaa
SD
8480 if (!nl80211_put_signal(msg, intbss->pub.chains,
8481 intbss->pub.chain_signal,
8482 NL80211_BSS_CHAIN_SIGNAL))
8483 goto nla_put_failure;
8484
77965c97 8485 switch (rdev->wiphy.signal_type) {
2a519311 8486 case CFG80211_SIGNAL_TYPE_MBM:
9360ffd1
DM
8487 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal))
8488 goto nla_put_failure;
2a519311
JB
8489 break;
8490 case CFG80211_SIGNAL_TYPE_UNSPEC:
9360ffd1
DM
8491 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal))
8492 goto nla_put_failure;
2a519311
JB
8493 break;
8494 default:
8495 break;
8496 }
8497
48ab905d 8498 switch (wdev->iftype) {
074ac8df 8499 case NL80211_IFTYPE_P2P_CLIENT:
48ab905d 8500 case NL80211_IFTYPE_STATION:
9360ffd1
DM
8501 if (intbss == wdev->current_bss &&
8502 nla_put_u32(msg, NL80211_BSS_STATUS,
8503 NL80211_BSS_STATUS_ASSOCIATED))
8504 goto nla_put_failure;
48ab905d
JB
8505 break;
8506 case NL80211_IFTYPE_ADHOC:
9360ffd1
DM
8507 if (intbss == wdev->current_bss &&
8508 nla_put_u32(msg, NL80211_BSS_STATUS,
8509 NL80211_BSS_STATUS_IBSS_JOINED))
8510 goto nla_put_failure;
48ab905d
JB
8511 break;
8512 default:
8513 break;
8514 }
8515
2a519311
JB
8516 nla_nest_end(msg, bss);
8517
053c095a
JB
8518 genlmsg_end(msg, hdr);
8519 return 0;
2a519311 8520
8cef2c9d
JB
8521 fail_unlock_rcu:
8522 rcu_read_unlock();
2a519311
JB
8523 nla_put_failure:
8524 genlmsg_cancel(msg, hdr);
8525 return -EMSGSIZE;
8526}
8527
97990a06 8528static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
2a519311 8529{
48ab905d 8530 struct cfg80211_registered_device *rdev;
2a519311 8531 struct cfg80211_internal_bss *scan;
48ab905d 8532 struct wireless_dev *wdev;
97990a06 8533 int start = cb->args[2], idx = 0;
2a519311
JB
8534 int err;
8535
ea90e0dc 8536 rtnl_lock();
5297c65c 8537 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
ea90e0dc
JB
8538 if (err) {
8539 rtnl_unlock();
67748893 8540 return err;
ea90e0dc 8541 }
2a519311 8542
48ab905d
JB
8543 wdev_lock(wdev);
8544 spin_lock_bh(&rdev->bss_lock);
d1e23c94
DK
8545
8546 /*
8547 * dump_scan will be called multiple times to break up the scan results
8548 * into multiple messages. It is unlikely that any more bss-es will be
8549 * expired after the first call, so only call only call this on the
8550 * first dump_scan invocation.
8551 */
8552 if (start == 0)
8553 cfg80211_bss_expire(rdev);
48ab905d 8554
9720bb3a
JB
8555 cb->seq = rdev->bss_generation;
8556
48ab905d 8557 list_for_each_entry(scan, &rdev->bss_list, list) {
2a519311
JB
8558 if (++idx <= start)
8559 continue;
9720bb3a 8560 if (nl80211_send_bss(skb, cb,
2a519311 8561 cb->nlh->nlmsg_seq, NLM_F_MULTI,
48ab905d 8562 rdev, wdev, scan) < 0) {
2a519311 8563 idx--;
67748893 8564 break;
2a519311
JB
8565 }
8566 }
8567
48ab905d
JB
8568 spin_unlock_bh(&rdev->bss_lock);
8569 wdev_unlock(wdev);
2a519311 8570
97990a06 8571 cb->args[2] = idx;
ea90e0dc 8572 rtnl_unlock();
2a519311 8573
67748893 8574 return skb->len;
2a519311
JB
8575}
8576
15e47304 8577static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
11f78ac3
JB
8578 int flags, struct net_device *dev,
8579 bool allow_radio_stats,
8580 struct survey_info *survey)
61fa713c
HS
8581{
8582 void *hdr;
8583 struct nlattr *infoattr;
8584
11f78ac3
JB
8585 /* skip radio stats if userspace didn't request them */
8586 if (!survey->channel && !allow_radio_stats)
8587 return 0;
8588
15e47304 8589 hdr = nl80211hdr_put(msg, portid, seq, flags,
61fa713c
HS
8590 NL80211_CMD_NEW_SURVEY_RESULTS);
8591 if (!hdr)
8592 return -ENOMEM;
8593
9360ffd1
DM
8594 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
8595 goto nla_put_failure;
61fa713c 8596
ae0be8de 8597 infoattr = nla_nest_start_noflag(msg, NL80211_ATTR_SURVEY_INFO);
61fa713c
HS
8598 if (!infoattr)
8599 goto nla_put_failure;
8600
11f78ac3
JB
8601 if (survey->channel &&
8602 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
9360ffd1
DM
8603 survey->channel->center_freq))
8604 goto nla_put_failure;
8605
8606 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
8607 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
8608 goto nla_put_failure;
8609 if ((survey->filled & SURVEY_INFO_IN_USE) &&
8610 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
8611 goto nla_put_failure;
4ed20beb 8612 if ((survey->filled & SURVEY_INFO_TIME) &&
2dad624e
ND
8613 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
8614 survey->time, NL80211_SURVEY_INFO_PAD))
9360ffd1 8615 goto nla_put_failure;
4ed20beb 8616 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
2dad624e
ND
8617 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
8618 survey->time_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 8619 goto nla_put_failure;
4ed20beb 8620 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
2dad624e
ND
8621 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
8622 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
9360ffd1 8623 goto nla_put_failure;
4ed20beb 8624 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
2dad624e
ND
8625 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
8626 survey->time_rx, NL80211_SURVEY_INFO_PAD))
9360ffd1 8627 goto nla_put_failure;
4ed20beb 8628 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
2dad624e
ND
8629 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
8630 survey->time_tx, NL80211_SURVEY_INFO_PAD))
9360ffd1 8631 goto nla_put_failure;
052536ab 8632 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
2dad624e
ND
8633 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
8634 survey->time_scan, NL80211_SURVEY_INFO_PAD))
052536ab 8635 goto nla_put_failure;
61fa713c
HS
8636
8637 nla_nest_end(msg, infoattr);
8638
053c095a
JB
8639 genlmsg_end(msg, hdr);
8640 return 0;
61fa713c
HS
8641
8642 nla_put_failure:
8643 genlmsg_cancel(msg, hdr);
8644 return -EMSGSIZE;
8645}
8646
11f78ac3 8647static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
61fa713c 8648{
c90c39da 8649 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
61fa713c 8650 struct survey_info survey;
1b8ec87a 8651 struct cfg80211_registered_device *rdev;
97990a06
JB
8652 struct wireless_dev *wdev;
8653 int survey_idx = cb->args[2];
61fa713c 8654 int res;
11f78ac3 8655 bool radio_stats;
61fa713c 8656
ea90e0dc 8657 rtnl_lock();
5297c65c 8658 res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev);
67748893 8659 if (res)
ea90e0dc 8660 goto out_err;
61fa713c 8661
11f78ac3 8662 /* prepare_wdev_dump parsed the attributes */
c90c39da 8663 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
11f78ac3 8664
97990a06
JB
8665 if (!wdev->netdev) {
8666 res = -EINVAL;
8667 goto out_err;
8668 }
8669
1b8ec87a 8670 if (!rdev->ops->dump_survey) {
61fa713c
HS
8671 res = -EOPNOTSUPP;
8672 goto out_err;
8673 }
8674
8675 while (1) {
1b8ec87a 8676 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
61fa713c
HS
8677 if (res == -ENOENT)
8678 break;
8679 if (res)
8680 goto out_err;
8681
11f78ac3
JB
8682 /* don't send disabled channels, but do send non-channel data */
8683 if (survey.channel &&
8684 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
180cdc79
LR
8685 survey_idx++;
8686 continue;
8687 }
8688
61fa713c 8689 if (nl80211_send_survey(skb,
15e47304 8690 NETLINK_CB(cb->skb).portid,
61fa713c 8691 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11f78ac3 8692 wdev->netdev, radio_stats, &survey) < 0)
61fa713c
HS
8693 goto out;
8694 survey_idx++;
8695 }
8696
8697 out:
97990a06 8698 cb->args[2] = survey_idx;
61fa713c
HS
8699 res = skb->len;
8700 out_err:
ea90e0dc 8701 rtnl_unlock();
61fa713c
HS
8702 return res;
8703}
8704
b23aa676
SO
8705static bool nl80211_valid_wpa_versions(u32 wpa_versions)
8706{
8707 return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
8708 NL80211_WPA_VERSION_2));
8709}
8710
636a5d36
JM
8711static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
8712{
4c476991
JB
8713 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8714 struct net_device *dev = info->user_ptr[1];
19957bb3 8715 struct ieee80211_channel *chan;
11b6b5a4
JM
8716 const u8 *bssid, *ssid, *ie = NULL, *auth_data = NULL;
8717 int err, ssid_len, ie_len = 0, auth_data_len = 0;
19957bb3 8718 enum nl80211_auth_type auth_type;
fffd0934 8719 struct key_parse key;
d5cdfacb 8720 bool local_state_change;
636a5d36 8721
f4a11bb0
JB
8722 if (!info->attrs[NL80211_ATTR_MAC])
8723 return -EINVAL;
8724
1778092e
JM
8725 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
8726 return -EINVAL;
8727
19957bb3
JB
8728 if (!info->attrs[NL80211_ATTR_SSID])
8729 return -EINVAL;
8730
8731 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
8732 return -EINVAL;
8733
fffd0934
JB
8734 err = nl80211_parse_key(info, &key);
8735 if (err)
8736 return err;
8737
8738 if (key.idx >= 0) {
e31b8213
JB
8739 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
8740 return -EINVAL;
fffd0934
JB
8741 if (!key.p.key || !key.p.key_len)
8742 return -EINVAL;
8743 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
8744 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
8745 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
8746 key.p.key_len != WLAN_KEY_LEN_WEP104))
8747 return -EINVAL;
b6b5555b 8748 if (key.idx > 3)
fffd0934
JB
8749 return -EINVAL;
8750 } else {
8751 key.p.key_len = 0;
8752 key.p.key = NULL;
8753 }
8754
afea0b7a
JB
8755 if (key.idx >= 0) {
8756 int i;
8757 bool ok = false;
7a087e74 8758
afea0b7a
JB
8759 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
8760 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
8761 ok = true;
8762 break;
8763 }
8764 }
4c476991
JB
8765 if (!ok)
8766 return -EINVAL;
afea0b7a
JB
8767 }
8768
4c476991
JB
8769 if (!rdev->ops->auth)
8770 return -EOPNOTSUPP;
636a5d36 8771
074ac8df 8772 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8773 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8774 return -EOPNOTSUPP;
eec60b03 8775
19957bb3 8776 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
664834de
JM
8777 chan = nl80211_get_valid_chan(&rdev->wiphy,
8778 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8779 if (!chan)
4c476991 8780 return -EINVAL;
636a5d36 8781
19957bb3
JB
8782 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8783 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
8784
8785 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
8786 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8787 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8788 }
8789
19957bb3 8790 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e 8791 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
4c476991 8792 return -EINVAL;
636a5d36 8793
63181060
JM
8794 if ((auth_type == NL80211_AUTHTYPE_SAE ||
8795 auth_type == NL80211_AUTHTYPE_FILS_SK ||
8796 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
8797 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
11b6b5a4 8798 !info->attrs[NL80211_ATTR_AUTH_DATA])
e39e5b5e
JM
8799 return -EINVAL;
8800
11b6b5a4 8801 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
63181060
JM
8802 if (auth_type != NL80211_AUTHTYPE_SAE &&
8803 auth_type != NL80211_AUTHTYPE_FILS_SK &&
8804 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
8805 auth_type != NL80211_AUTHTYPE_FILS_PK)
e39e5b5e 8806 return -EINVAL;
11b6b5a4
JM
8807 auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
8808 auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
e39e5b5e 8809 /* need to include at least Auth Transaction and Status Code */
11b6b5a4 8810 if (auth_data_len < 4)
e39e5b5e
JM
8811 return -EINVAL;
8812 }
8813
d5cdfacb
JM
8814 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
8815
95de817b
JB
8816 /*
8817 * Since we no longer track auth state, ignore
8818 * requests to only change local state.
8819 */
8820 if (local_state_change)
8821 return 0;
8822
91bf9b26
JB
8823 wdev_lock(dev->ieee80211_ptr);
8824 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
8825 ssid, ssid_len, ie, ie_len,
8826 key.p.key, key.p.key_len, key.idx,
11b6b5a4 8827 auth_data, auth_data_len);
91bf9b26
JB
8828 wdev_unlock(dev->ieee80211_ptr);
8829 return err;
636a5d36
JM
8830}
8831
64bf3d4b
DK
8832static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
8833 struct genl_info *info)
8834{
8835 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
8836 GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
8837 return -EINVAL;
8838 }
8839
8840 if (!rdev->ops->tx_control_port ||
8841 !wiphy_ext_feature_isset(&rdev->wiphy,
8842 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
8843 return -EOPNOTSUPP;
8844
8845 return 0;
8846}
8847
c0692b8f
JB
8848static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
8849 struct genl_info *info,
3dc27d25
JB
8850 struct cfg80211_crypto_settings *settings,
8851 int cipher_limit)
b23aa676 8852{
c0b2bbd8
JB
8853 memset(settings, 0, sizeof(*settings));
8854
b23aa676
SO
8855 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
8856
c0692b8f
JB
8857 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
8858 u16 proto;
7a087e74 8859
c0692b8f
JB
8860 proto = nla_get_u16(
8861 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
8862 settings->control_port_ethertype = cpu_to_be16(proto);
8863 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
8864 proto != ETH_P_PAE)
8865 return -EINVAL;
8866 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
8867 settings->control_port_no_encrypt = true;
8868 } else
8869 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
8870
64bf3d4b
DK
8871 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
8872 int r = validate_pae_over_nl80211(rdev, info);
8873
8874 if (r < 0)
8875 return r;
8876
8877 settings->control_port_over_nl80211 = true;
8878 }
8879
b23aa676
SO
8880 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
8881 void *data;
8882 int len, i;
8883
8884 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
8885 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
8886 settings->n_ciphers_pairwise = len / sizeof(u32);
8887
8888 if (len % sizeof(u32))
8889 return -EINVAL;
8890
3dc27d25 8891 if (settings->n_ciphers_pairwise > cipher_limit)
b23aa676
SO
8892 return -EINVAL;
8893
8894 memcpy(settings->ciphers_pairwise, data, len);
8895
8896 for (i = 0; i < settings->n_ciphers_pairwise; i++)
38ba3c57
JM
8897 if (!cfg80211_supported_cipher_suite(
8898 &rdev->wiphy,
b23aa676
SO
8899 settings->ciphers_pairwise[i]))
8900 return -EINVAL;
8901 }
8902
8903 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
8904 settings->cipher_group =
8905 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
38ba3c57
JM
8906 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
8907 settings->cipher_group))
b23aa676
SO
8908 return -EINVAL;
8909 }
8910
8911 if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) {
8912 settings->wpa_versions =
8913 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
8914 if (!nl80211_valid_wpa_versions(settings->wpa_versions))
8915 return -EINVAL;
8916 }
8917
8918 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
8919 void *data;
6d30240e 8920 int len;
b23aa676
SO
8921
8922 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
8923 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
8924 settings->n_akm_suites = len / sizeof(u32);
8925
8926 if (len % sizeof(u32))
8927 return -EINVAL;
8928
1b9ca027
JM
8929 if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES)
8930 return -EINVAL;
8931
b23aa676 8932 memcpy(settings->akm_suites, data, len);
b23aa676
SO
8933 }
8934
91b5ab62
EP
8935 if (info->attrs[NL80211_ATTR_PMK]) {
8936 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
8937 return -EINVAL;
8938 if (!wiphy_ext_feature_isset(&rdev->wiphy,
8939 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK))
8940 return -EINVAL;
8941 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
8942 }
8943
b23aa676
SO
8944 return 0;
8945}
8946
636a5d36
JM
8947static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
8948{
4c476991
JB
8949 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8950 struct net_device *dev = info->user_ptr[1];
f444de05 8951 struct ieee80211_channel *chan;
f62fab73
JB
8952 struct cfg80211_assoc_request req = {};
8953 const u8 *bssid, *ssid;
8954 int err, ssid_len = 0;
636a5d36 8955
bad29297
AZ
8956 if (dev->ieee80211_ptr->conn_owner_nlportid &&
8957 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
8958 return -EPERM;
8959
f4a11bb0 8960 if (!info->attrs[NL80211_ATTR_MAC] ||
19957bb3
JB
8961 !info->attrs[NL80211_ATTR_SSID] ||
8962 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
f4a11bb0
JB
8963 return -EINVAL;
8964
4c476991
JB
8965 if (!rdev->ops->assoc)
8966 return -EOPNOTSUPP;
636a5d36 8967
074ac8df 8968 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
8969 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
8970 return -EOPNOTSUPP;
eec60b03 8971
19957bb3 8972 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 8973
664834de
JM
8974 chan = nl80211_get_valid_chan(&rdev->wiphy,
8975 info->attrs[NL80211_ATTR_WIPHY_FREQ]);
8976 if (!chan)
4c476991 8977 return -EINVAL;
636a5d36 8978
19957bb3
JB
8979 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
8980 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
636a5d36
JM
8981
8982 if (info->attrs[NL80211_ATTR_IE]) {
f62fab73
JB
8983 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
8984 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
8985 }
8986
dc6382ce 8987 if (info->attrs[NL80211_ATTR_USE_MFP]) {
4f5dadce 8988 enum nl80211_mfp mfp =
dc6382ce 8989 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
4f5dadce 8990 if (mfp == NL80211_MFP_REQUIRED)
f62fab73 8991 req.use_mfp = true;
4c476991
JB
8992 else if (mfp != NL80211_MFP_NO)
8993 return -EINVAL;
dc6382ce
JM
8994 }
8995
3e5d7649 8996 if (info->attrs[NL80211_ATTR_PREV_BSSID])
f62fab73 8997 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
3e5d7649 8998
7e7c8926 8999 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
f62fab73 9000 req.flags |= ASSOC_REQ_DISABLE_HT;
7e7c8926
BG
9001
9002 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
f62fab73
JB
9003 memcpy(&req.ht_capa_mask,
9004 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9005 sizeof(req.ht_capa_mask));
7e7c8926
BG
9006
9007 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
f62fab73 9008 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
7e7c8926 9009 return -EINVAL;
f62fab73
JB
9010 memcpy(&req.ht_capa,
9011 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9012 sizeof(req.ht_capa));
7e7c8926
BG
9013 }
9014
ee2aca34 9015 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
f62fab73 9016 req.flags |= ASSOC_REQ_DISABLE_VHT;
ee2aca34
JB
9017
9018 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
f62fab73
JB
9019 memcpy(&req.vht_capa_mask,
9020 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
9021 sizeof(req.vht_capa_mask));
ee2aca34
JB
9022
9023 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
f62fab73 9024 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
ee2aca34 9025 return -EINVAL;
f62fab73
JB
9026 memcpy(&req.vht_capa,
9027 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
9028 sizeof(req.vht_capa));
ee2aca34
JB
9029 }
9030
bab5ab7d 9031 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
9032 if (!((rdev->wiphy.features &
9033 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
9034 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
9035 !wiphy_ext_feature_isset(&rdev->wiphy,
9036 NL80211_EXT_FEATURE_RRM))
bab5ab7d
AK
9037 return -EINVAL;
9038 req.flags |= ASSOC_REQ_USE_RRM;
9039 }
9040
348bd456
JM
9041 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
9042 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
9043 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
9044 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
9045 return -EINVAL;
9046 req.fils_nonces =
9047 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
9048 }
9049
f62fab73 9050 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
91bf9b26
JB
9051 if (!err) {
9052 wdev_lock(dev->ieee80211_ptr);
bd2522b1 9053
f62fab73
JB
9054 err = cfg80211_mlme_assoc(rdev, dev, chan, bssid,
9055 ssid, ssid_len, &req);
bd2522b1
AZ
9056
9057 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9058 dev->ieee80211_ptr->conn_owner_nlportid =
9059 info->snd_portid;
9060 memcpy(dev->ieee80211_ptr->disconnect_bssid,
9061 bssid, ETH_ALEN);
9062 }
9063
91bf9b26
JB
9064 wdev_unlock(dev->ieee80211_ptr);
9065 }
636a5d36 9066
636a5d36
JM
9067 return err;
9068}
9069
9070static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
9071{
4c476991
JB
9072 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9073 struct net_device *dev = info->user_ptr[1];
19957bb3 9074 const u8 *ie = NULL, *bssid;
91bf9b26 9075 int ie_len = 0, err;
19957bb3 9076 u16 reason_code;
d5cdfacb 9077 bool local_state_change;
636a5d36 9078
bad29297
AZ
9079 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9080 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9081 return -EPERM;
9082
f4a11bb0
JB
9083 if (!info->attrs[NL80211_ATTR_MAC])
9084 return -EINVAL;
9085
9086 if (!info->attrs[NL80211_ATTR_REASON_CODE])
9087 return -EINVAL;
9088
4c476991
JB
9089 if (!rdev->ops->deauth)
9090 return -EOPNOTSUPP;
636a5d36 9091
074ac8df 9092 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9093 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9094 return -EOPNOTSUPP;
eec60b03 9095
19957bb3 9096 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 9097
19957bb3
JB
9098 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
9099 if (reason_code == 0) {
f4a11bb0 9100 /* Reason Code 0 is reserved */
4c476991 9101 return -EINVAL;
255e737e 9102 }
636a5d36
JM
9103
9104 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
9105 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9106 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9107 }
9108
d5cdfacb
JM
9109 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
9110
91bf9b26
JB
9111 wdev_lock(dev->ieee80211_ptr);
9112 err = cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
9113 local_state_change);
9114 wdev_unlock(dev->ieee80211_ptr);
9115 return err;
636a5d36
JM
9116}
9117
9118static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
9119{
4c476991
JB
9120 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9121 struct net_device *dev = info->user_ptr[1];
19957bb3 9122 const u8 *ie = NULL, *bssid;
91bf9b26 9123 int ie_len = 0, err;
19957bb3 9124 u16 reason_code;
d5cdfacb 9125 bool local_state_change;
636a5d36 9126
bad29297
AZ
9127 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9128 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9129 return -EPERM;
9130
f4a11bb0
JB
9131 if (!info->attrs[NL80211_ATTR_MAC])
9132 return -EINVAL;
9133
9134 if (!info->attrs[NL80211_ATTR_REASON_CODE])
9135 return -EINVAL;
9136
4c476991
JB
9137 if (!rdev->ops->disassoc)
9138 return -EOPNOTSUPP;
636a5d36 9139
074ac8df 9140 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9141 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9142 return -EOPNOTSUPP;
eec60b03 9143
19957bb3 9144 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
636a5d36 9145
19957bb3
JB
9146 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
9147 if (reason_code == 0) {
f4a11bb0 9148 /* Reason Code 0 is reserved */
4c476991 9149 return -EINVAL;
255e737e 9150 }
636a5d36
JM
9151
9152 if (info->attrs[NL80211_ATTR_IE]) {
19957bb3
JB
9153 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9154 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
636a5d36
JM
9155 }
9156
d5cdfacb
JM
9157 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
9158
91bf9b26
JB
9159 wdev_lock(dev->ieee80211_ptr);
9160 err = cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
9161 local_state_change);
9162 wdev_unlock(dev->ieee80211_ptr);
9163 return err;
636a5d36
JM
9164}
9165
dd5b4cc7
FF
9166static bool
9167nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
57fbcce3 9168 int mcast_rate[NUM_NL80211_BANDS],
dd5b4cc7
FF
9169 int rateval)
9170{
9171 struct wiphy *wiphy = &rdev->wiphy;
9172 bool found = false;
9173 int band, i;
9174
57fbcce3 9175 for (band = 0; band < NUM_NL80211_BANDS; band++) {
dd5b4cc7
FF
9176 struct ieee80211_supported_band *sband;
9177
9178 sband = wiphy->bands[band];
9179 if (!sband)
9180 continue;
9181
9182 for (i = 0; i < sband->n_bitrates; i++) {
9183 if (sband->bitrates[i].bitrate == rateval) {
9184 mcast_rate[band] = i + 1;
9185 found = true;
9186 break;
9187 }
9188 }
9189 }
9190
9191 return found;
9192}
9193
04a773ad
JB
9194static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
9195{
4c476991
JB
9196 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9197 struct net_device *dev = info->user_ptr[1];
04a773ad
JB
9198 struct cfg80211_ibss_params ibss;
9199 struct wiphy *wiphy;
fffd0934 9200 struct cfg80211_cached_keys *connkeys = NULL;
04a773ad
JB
9201 int err;
9202
8e30bc55
JB
9203 memset(&ibss, 0, sizeof(ibss));
9204
683b6d3b 9205 if (!info->attrs[NL80211_ATTR_SSID] ||
04a773ad
JB
9206 !nla_len(info->attrs[NL80211_ATTR_SSID]))
9207 return -EINVAL;
9208
8e30bc55
JB
9209 ibss.beacon_interval = 100;
9210
12d20fc9 9211 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
8e30bc55
JB
9212 ibss.beacon_interval =
9213 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 9214
0c317a02
PK
9215 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
9216 ibss.beacon_interval);
12d20fc9
PK
9217 if (err)
9218 return err;
8e30bc55 9219
4c476991
JB
9220 if (!rdev->ops->join_ibss)
9221 return -EOPNOTSUPP;
04a773ad 9222
4c476991
JB
9223 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
9224 return -EOPNOTSUPP;
04a773ad 9225
79c97e97 9226 wiphy = &rdev->wiphy;
04a773ad 9227
39193498 9228 if (info->attrs[NL80211_ATTR_MAC]) {
04a773ad 9229 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
39193498
JB
9230
9231 if (!is_valid_ether_addr(ibss.bssid))
9232 return -EINVAL;
9233 }
04a773ad
JB
9234 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9235 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
9236
9237 if (info->attrs[NL80211_ATTR_IE]) {
9238 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9239 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9240 }
9241
683b6d3b
JB
9242 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
9243 if (err)
9244 return err;
04a773ad 9245
174e0cd2
IP
9246 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
9247 NL80211_IFTYPE_ADHOC))
54858ee5
AS
9248 return -EINVAL;
9249
2f301ab2 9250 switch (ibss.chandef.width) {
bf372645
SW
9251 case NL80211_CHAN_WIDTH_5:
9252 case NL80211_CHAN_WIDTH_10:
2f301ab2
SW
9253 case NL80211_CHAN_WIDTH_20_NOHT:
9254 break;
9255 case NL80211_CHAN_WIDTH_20:
9256 case NL80211_CHAN_WIDTH_40:
ffc11991
JD
9257 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
9258 return -EINVAL;
9259 break;
9260 case NL80211_CHAN_WIDTH_80:
9261 case NL80211_CHAN_WIDTH_80P80:
9262 case NL80211_CHAN_WIDTH_160:
9263 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
9264 return -EINVAL;
9265 if (!wiphy_ext_feature_isset(&rdev->wiphy,
9266 NL80211_EXT_FEATURE_VHT_IBSS))
9267 return -EINVAL;
9268 break;
2f301ab2 9269 default:
c04d6150 9270 return -EINVAL;
2f301ab2 9271 }
db9c64cf 9272
04a773ad 9273 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
fffd0934
JB
9274 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
9275
fbd2c8dc
TP
9276 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
9277 u8 *rates =
9278 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9279 int n_rates =
9280 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
9281 struct ieee80211_supported_band *sband =
683b6d3b 9282 wiphy->bands[ibss.chandef.chan->band];
fbd2c8dc 9283
34850ab2
JB
9284 err = ieee80211_get_ratemask(sband, rates, n_rates,
9285 &ibss.basic_rates);
9286 if (err)
9287 return err;
fbd2c8dc 9288 }
dd5b4cc7 9289
803768f5
SW
9290 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9291 memcpy(&ibss.ht_capa_mask,
9292 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9293 sizeof(ibss.ht_capa_mask));
9294
9295 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
9296 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9297 return -EINVAL;
9298 memcpy(&ibss.ht_capa,
9299 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9300 sizeof(ibss.ht_capa));
9301 }
9302
dd5b4cc7
FF
9303 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
9304 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
9305 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
9306 return -EINVAL;
fbd2c8dc 9307
4c476991 9308 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
de7044ee
SM
9309 bool no_ht = false;
9310
768075eb 9311 connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
4c476991
JB
9312 if (IS_ERR(connkeys))
9313 return PTR_ERR(connkeys);
de7044ee 9314
3d9d1d66
JB
9315 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
9316 no_ht) {
5e950a78 9317 kzfree(connkeys);
de7044ee
SM
9318 return -EINVAL;
9319 }
4c476991 9320 }
04a773ad 9321
267335d6
AQ
9322 ibss.control_port =
9323 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
9324
c3bfe1f6
DK
9325 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
9326 int r = validate_pae_over_nl80211(rdev, info);
9327
d350a0f4
JB
9328 if (r < 0) {
9329 kzfree(connkeys);
c3bfe1f6 9330 return r;
d350a0f4 9331 }
c3bfe1f6
DK
9332
9333 ibss.control_port_over_nl80211 = true;
9334 }
9335
5336fa88
SW
9336 ibss.userspace_handles_dfs =
9337 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
9338
f8d16d3e
DK
9339 wdev_lock(dev->ieee80211_ptr);
9340 err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
fffd0934 9341 if (err)
b47f610b 9342 kzfree(connkeys);
f8d16d3e
DK
9343 else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
9344 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
9345 wdev_unlock(dev->ieee80211_ptr);
9346
04a773ad
JB
9347 return err;
9348}
9349
9350static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
9351{
4c476991
JB
9352 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9353 struct net_device *dev = info->user_ptr[1];
04a773ad 9354
4c476991
JB
9355 if (!rdev->ops->leave_ibss)
9356 return -EOPNOTSUPP;
04a773ad 9357
4c476991
JB
9358 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
9359 return -EOPNOTSUPP;
04a773ad 9360
4c476991 9361 return cfg80211_leave_ibss(rdev, dev, false);
04a773ad
JB
9362}
9363
f4e583c8
AQ
9364static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
9365{
9366 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9367 struct net_device *dev = info->user_ptr[1];
57fbcce3 9368 int mcast_rate[NUM_NL80211_BANDS];
f4e583c8
AQ
9369 u32 nla_rate;
9370 int err;
9371
9372 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
876dc930
BVB
9373 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
9374 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
f4e583c8
AQ
9375 return -EOPNOTSUPP;
9376
9377 if (!rdev->ops->set_mcast_rate)
9378 return -EOPNOTSUPP;
9379
9380 memset(mcast_rate, 0, sizeof(mcast_rate));
9381
9382 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
9383 return -EINVAL;
9384
9385 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
9386 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
9387 return -EINVAL;
9388
a1056b1b 9389 err = rdev_set_mcast_rate(rdev, dev, mcast_rate);
f4e583c8
AQ
9390
9391 return err;
9392}
9393
ad7e718c
JB
9394static struct sk_buff *
9395__cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
6c09e791
AK
9396 struct wireless_dev *wdev, int approxlen,
9397 u32 portid, u32 seq, enum nl80211_commands cmd,
567ffc35
JB
9398 enum nl80211_attrs attr,
9399 const struct nl80211_vendor_cmd_info *info,
9400 gfp_t gfp)
ad7e718c
JB
9401{
9402 struct sk_buff *skb;
9403 void *hdr;
9404 struct nlattr *data;
9405
9406 skb = nlmsg_new(approxlen + 100, gfp);
9407 if (!skb)
9408 return NULL;
9409
9410 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
9411 if (!hdr) {
9412 kfree_skb(skb);
9413 return NULL;
9414 }
9415
9416 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
9417 goto nla_put_failure;
567ffc35
JB
9418
9419 if (info) {
9420 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
9421 info->vendor_id))
9422 goto nla_put_failure;
9423 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
9424 info->subcmd))
9425 goto nla_put_failure;
9426 }
9427
6c09e791 9428 if (wdev) {
2dad624e
ND
9429 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
9430 wdev_id(wdev), NL80211_ATTR_PAD))
6c09e791
AK
9431 goto nla_put_failure;
9432 if (wdev->netdev &&
9433 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
9434 wdev->netdev->ifindex))
9435 goto nla_put_failure;
9436 }
9437
ae0be8de 9438 data = nla_nest_start_noflag(skb, attr);
76e1fb4b
JB
9439 if (!data)
9440 goto nla_put_failure;
ad7e718c
JB
9441
9442 ((void **)skb->cb)[0] = rdev;
9443 ((void **)skb->cb)[1] = hdr;
9444 ((void **)skb->cb)[2] = data;
9445
9446 return skb;
9447
9448 nla_put_failure:
9449 kfree_skb(skb);
9450 return NULL;
9451}
f4e583c8 9452
e03ad6ea 9453struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
6c09e791 9454 struct wireless_dev *wdev,
e03ad6ea
JB
9455 enum nl80211_commands cmd,
9456 enum nl80211_attrs attr,
55c1fdf0 9457 unsigned int portid,
e03ad6ea
JB
9458 int vendor_event_idx,
9459 int approxlen, gfp_t gfp)
9460{
f26cbf40 9461 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
e03ad6ea
JB
9462 const struct nl80211_vendor_cmd_info *info;
9463
9464 switch (cmd) {
9465 case NL80211_CMD_TESTMODE:
9466 if (WARN_ON(vendor_event_idx != -1))
9467 return NULL;
9468 info = NULL;
9469 break;
9470 case NL80211_CMD_VENDOR:
9471 if (WARN_ON(vendor_event_idx < 0 ||
9472 vendor_event_idx >= wiphy->n_vendor_events))
9473 return NULL;
9474 info = &wiphy->vendor_events[vendor_event_idx];
9475 break;
9476 default:
9477 WARN_ON(1);
9478 return NULL;
9479 }
9480
55c1fdf0 9481 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0,
e03ad6ea
JB
9482 cmd, attr, info, gfp);
9483}
9484EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
9485
9486void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
9487{
9488 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
9489 void *hdr = ((void **)skb->cb)[1];
55c1fdf0 9490 struct nlmsghdr *nlhdr = nlmsg_hdr(skb);
e03ad6ea
JB
9491 struct nlattr *data = ((void **)skb->cb)[2];
9492 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
9493
bd8c78e7
JB
9494 /* clear CB data for netlink core to own from now on */
9495 memset(skb->cb, 0, sizeof(skb->cb));
9496
e03ad6ea
JB
9497 nla_nest_end(skb, data);
9498 genlmsg_end(skb, hdr);
9499
55c1fdf0
JB
9500 if (nlhdr->nlmsg_pid) {
9501 genlmsg_unicast(wiphy_net(&rdev->wiphy), skb,
9502 nlhdr->nlmsg_pid);
9503 } else {
9504 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
9505 mcgrp = NL80211_MCGRP_VENDOR;
e03ad6ea 9506
55c1fdf0
JB
9507 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
9508 skb, 0, mcgrp, gfp);
9509 }
e03ad6ea
JB
9510}
9511EXPORT_SYMBOL(__cfg80211_send_event_skb);
9512
aff89a9b 9513#ifdef CONFIG_NL80211_TESTMODE
aff89a9b
JB
9514static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
9515{
4c476991 9516 struct cfg80211_registered_device *rdev = info->user_ptr[0];
fc73f11f
DS
9517 struct wireless_dev *wdev =
9518 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
aff89a9b
JB
9519 int err;
9520
fc73f11f
DS
9521 if (!rdev->ops->testmode_cmd)
9522 return -EOPNOTSUPP;
9523
9524 if (IS_ERR(wdev)) {
9525 err = PTR_ERR(wdev);
9526 if (err != -EINVAL)
9527 return err;
9528 wdev = NULL;
9529 } else if (wdev->wiphy != &rdev->wiphy) {
9530 return -EINVAL;
9531 }
9532
aff89a9b
JB
9533 if (!info->attrs[NL80211_ATTR_TESTDATA])
9534 return -EINVAL;
9535
ad7e718c 9536 rdev->cur_cmd_info = info;
fc73f11f 9537 err = rdev_testmode_cmd(rdev, wdev,
aff89a9b
JB
9538 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
9539 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
ad7e718c 9540 rdev->cur_cmd_info = NULL;
aff89a9b 9541
aff89a9b
JB
9542 return err;
9543}
9544
71063f0e
WYG
9545static int nl80211_testmode_dump(struct sk_buff *skb,
9546 struct netlink_callback *cb)
9547{
00918d33 9548 struct cfg80211_registered_device *rdev;
71063f0e
WYG
9549 int err;
9550 long phy_idx;
9551 void *data = NULL;
9552 int data_len = 0;
9553
5fe231e8
JB
9554 rtnl_lock();
9555
71063f0e
WYG
9556 if (cb->args[0]) {
9557 /*
9558 * 0 is a valid index, but not valid for args[0],
9559 * so we need to offset by 1.
9560 */
9561 phy_idx = cb->args[0] - 1;
a4956dca
LC
9562
9563 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
9564 if (!rdev) {
9565 err = -ENOENT;
9566 goto out_err;
9567 }
71063f0e 9568 } else {
c90c39da
JB
9569 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
9570
8cb08174
JB
9571 err = nlmsg_parse_deprecated(cb->nlh,
9572 GENL_HDRLEN + nl80211_fam.hdrsize,
9573 attrbuf, nl80211_fam.maxattr,
9574 nl80211_policy, NULL);
71063f0e 9575 if (err)
5fe231e8 9576 goto out_err;
00918d33 9577
c90c39da 9578 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
2bd7e35d 9579 if (IS_ERR(rdev)) {
5fe231e8
JB
9580 err = PTR_ERR(rdev);
9581 goto out_err;
00918d33 9582 }
2bd7e35d 9583 phy_idx = rdev->wiphy_idx;
2bd7e35d 9584
c90c39da
JB
9585 if (attrbuf[NL80211_ATTR_TESTDATA])
9586 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
71063f0e
WYG
9587 }
9588
9589 if (cb->args[1]) {
9590 data = nla_data((void *)cb->args[1]);
9591 data_len = nla_len((void *)cb->args[1]);
9592 }
9593
00918d33 9594 if (!rdev->ops->testmode_dump) {
71063f0e
WYG
9595 err = -EOPNOTSUPP;
9596 goto out_err;
9597 }
9598
9599 while (1) {
15e47304 9600 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
71063f0e
WYG
9601 cb->nlh->nlmsg_seq, NLM_F_MULTI,
9602 NL80211_CMD_TESTMODE);
9603 struct nlattr *tmdata;
9604
cb35fba3
DC
9605 if (!hdr)
9606 break;
9607
9360ffd1 9608 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
71063f0e
WYG
9609 genlmsg_cancel(skb, hdr);
9610 break;
9611 }
9612
ae0be8de 9613 tmdata = nla_nest_start_noflag(skb, NL80211_ATTR_TESTDATA);
71063f0e
WYG
9614 if (!tmdata) {
9615 genlmsg_cancel(skb, hdr);
9616 break;
9617 }
e35e4d28 9618 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
71063f0e
WYG
9619 nla_nest_end(skb, tmdata);
9620
9621 if (err == -ENOBUFS || err == -ENOENT) {
9622 genlmsg_cancel(skb, hdr);
9623 break;
9624 } else if (err) {
9625 genlmsg_cancel(skb, hdr);
9626 goto out_err;
9627 }
9628
9629 genlmsg_end(skb, hdr);
9630 }
9631
9632 err = skb->len;
9633 /* see above */
9634 cb->args[0] = phy_idx + 1;
9635 out_err:
5fe231e8 9636 rtnl_unlock();
71063f0e
WYG
9637 return err;
9638}
aff89a9b
JB
9639#endif
9640
b23aa676
SO
9641static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
9642{
4c476991
JB
9643 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9644 struct net_device *dev = info->user_ptr[1];
b23aa676
SO
9645 struct cfg80211_connect_params connect;
9646 struct wiphy *wiphy;
fffd0934 9647 struct cfg80211_cached_keys *connkeys = NULL;
b23aa676
SO
9648 int err;
9649
9650 memset(&connect, 0, sizeof(connect));
9651
b23aa676
SO
9652 if (!info->attrs[NL80211_ATTR_SSID] ||
9653 !nla_len(info->attrs[NL80211_ATTR_SSID]))
9654 return -EINVAL;
9655
9656 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
9657 connect.auth_type =
9658 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
e39e5b5e
JM
9659 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
9660 NL80211_CMD_CONNECT))
b23aa676
SO
9661 return -EINVAL;
9662 } else
9663 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
9664
9665 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
9666
3a00df57
AS
9667 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
9668 !wiphy_ext_feature_isset(&rdev->wiphy,
9669 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
9670 return -EINVAL;
9671 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
9672
c0692b8f 9673 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
3dc27d25 9674 NL80211_MAX_NR_CIPHER_SUITES);
b23aa676
SO
9675 if (err)
9676 return err;
b23aa676 9677
074ac8df 9678 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9679 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9680 return -EOPNOTSUPP;
b23aa676 9681
79c97e97 9682 wiphy = &rdev->wiphy;
b23aa676 9683
4486ea98
BS
9684 connect.bg_scan_period = -1;
9685 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
9686 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
9687 connect.bg_scan_period =
9688 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
9689 }
9690
b23aa676
SO
9691 if (info->attrs[NL80211_ATTR_MAC])
9692 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
1df4a510
JM
9693 else if (info->attrs[NL80211_ATTR_MAC_HINT])
9694 connect.bssid_hint =
9695 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
b23aa676
SO
9696 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
9697 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
9698
9699 if (info->attrs[NL80211_ATTR_IE]) {
9700 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9701 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9702 }
9703
cee00a95
JM
9704 if (info->attrs[NL80211_ATTR_USE_MFP]) {
9705 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
65026002
EG
9706 if (connect.mfp == NL80211_MFP_OPTIONAL &&
9707 !wiphy_ext_feature_isset(&rdev->wiphy,
9708 NL80211_EXT_FEATURE_MFP_OPTIONAL))
9709 return -EOPNOTSUPP;
cee00a95
JM
9710 } else {
9711 connect.mfp = NL80211_MFP_NO;
9712 }
9713
ba6fbacf
JM
9714 if (info->attrs[NL80211_ATTR_PREV_BSSID])
9715 connect.prev_bssid =
9716 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
9717
b23aa676 9718 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
664834de
JM
9719 connect.channel = nl80211_get_valid_chan(
9720 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ]);
9721 if (!connect.channel)
1df4a510
JM
9722 return -EINVAL;
9723 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
664834de
JM
9724 connect.channel_hint = nl80211_get_valid_chan(
9725 wiphy, info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
9726 if (!connect.channel_hint)
4c476991 9727 return -EINVAL;
b23aa676
SO
9728 }
9729
fffd0934 9730 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
768075eb 9731 connkeys = nl80211_parse_connkeys(rdev, info, NULL);
4c476991
JB
9732 if (IS_ERR(connkeys))
9733 return PTR_ERR(connkeys);
fffd0934
JB
9734 }
9735
7e7c8926
BG
9736 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
9737 connect.flags |= ASSOC_REQ_DISABLE_HT;
9738
9739 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
9740 memcpy(&connect.ht_capa_mask,
9741 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
9742 sizeof(connect.ht_capa_mask));
9743
9744 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
b4e4f47e 9745 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
b47f610b 9746 kzfree(connkeys);
7e7c8926 9747 return -EINVAL;
b4e4f47e 9748 }
7e7c8926
BG
9749 memcpy(&connect.ht_capa,
9750 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
9751 sizeof(connect.ht_capa));
9752 }
9753
ee2aca34
JB
9754 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
9755 connect.flags |= ASSOC_REQ_DISABLE_VHT;
9756
9757 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
9758 memcpy(&connect.vht_capa_mask,
9759 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
9760 sizeof(connect.vht_capa_mask));
9761
9762 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
9763 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
b47f610b 9764 kzfree(connkeys);
ee2aca34
JB
9765 return -EINVAL;
9766 }
9767 memcpy(&connect.vht_capa,
9768 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
9769 sizeof(connect.vht_capa));
9770 }
9771
bab5ab7d 9772 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
0c9ca11b
BL
9773 if (!((rdev->wiphy.features &
9774 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
9775 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
9776 !wiphy_ext_feature_isset(&rdev->wiphy,
9777 NL80211_EXT_FEATURE_RRM)) {
707554b4 9778 kzfree(connkeys);
bab5ab7d 9779 return -EINVAL;
707554b4 9780 }
bab5ab7d
AK
9781 connect.flags |= ASSOC_REQ_USE_RRM;
9782 }
9783
34d50519 9784 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
57fbcce3 9785 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
34d50519
LD
9786 kzfree(connkeys);
9787 return -EOPNOTSUPP;
9788 }
9789
38de03d2
AS
9790 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
9791 /* bss selection makes no sense if bssid is set */
9792 if (connect.bssid) {
9793 kzfree(connkeys);
9794 return -EINVAL;
9795 }
9796
9797 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
9798 wiphy, &connect.bss_select);
9799 if (err) {
9800 kzfree(connkeys);
9801 return err;
9802 }
9803 }
9804
a3caf744
VK
9805 if (wiphy_ext_feature_isset(&rdev->wiphy,
9806 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
9807 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
9808 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
9809 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
9810 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9811 connect.fils_erp_username =
9812 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9813 connect.fils_erp_username_len =
9814 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9815 connect.fils_erp_realm =
9816 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9817 connect.fils_erp_realm_len =
9818 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9819 connect.fils_erp_next_seq_num =
9820 nla_get_u16(
9821 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
9822 connect.fils_erp_rrk =
9823 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9824 connect.fils_erp_rrk_len =
9825 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9826 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
9827 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
9828 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
9829 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9830 kzfree(connkeys);
9831 return -EINVAL;
9832 }
9833
40cbfa90
SD
9834 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
9835 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
2f0605a6 9836 kzfree(connkeys);
40cbfa90
SD
9837 GENL_SET_ERR_MSG(info,
9838 "external auth requires connection ownership");
9839 return -EINVAL;
9840 }
9841 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
9842 }
9843
83739b03 9844 wdev_lock(dev->ieee80211_ptr);
bd2522b1 9845
4ce2bd9c
JM
9846 err = cfg80211_connect(rdev, dev, &connect, connkeys,
9847 connect.prev_bssid);
fffd0934 9848 if (err)
b47f610b 9849 kzfree(connkeys);
bd2522b1
AZ
9850
9851 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
9852 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
9853 if (connect.bssid)
9854 memcpy(dev->ieee80211_ptr->disconnect_bssid,
9855 connect.bssid, ETH_ALEN);
9856 else
9857 memset(dev->ieee80211_ptr->disconnect_bssid,
9858 0, ETH_ALEN);
9859 }
9860
9861 wdev_unlock(dev->ieee80211_ptr);
9862
b23aa676
SO
9863 return err;
9864}
9865
088e8df8 9866static int nl80211_update_connect_params(struct sk_buff *skb,
9867 struct genl_info *info)
9868{
9869 struct cfg80211_connect_params connect = {};
9870 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9871 struct net_device *dev = info->user_ptr[1];
9872 struct wireless_dev *wdev = dev->ieee80211_ptr;
7f9a3e15
VK
9873 bool fils_sk_offload;
9874 u32 auth_type;
088e8df8 9875 u32 changed = 0;
9876 int ret;
9877
9878 if (!rdev->ops->update_connect_params)
9879 return -EOPNOTSUPP;
9880
9881 if (info->attrs[NL80211_ATTR_IE]) {
088e8df8 9882 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
9883 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9884 changed |= UPDATE_ASSOC_IES;
9885 }
9886
7f9a3e15
VK
9887 fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
9888 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
9889
9890 /*
9891 * when driver supports fils-sk offload all attributes must be
9892 * provided. So the else covers "fils-sk-not-all" and
9893 * "no-fils-sk-any".
9894 */
9895 if (fils_sk_offload &&
9896 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
9897 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
9898 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
9899 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9900 connect.fils_erp_username =
9901 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9902 connect.fils_erp_username_len =
9903 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
9904 connect.fils_erp_realm =
9905 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9906 connect.fils_erp_realm_len =
9907 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
9908 connect.fils_erp_next_seq_num =
9909 nla_get_u16(
9910 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
9911 connect.fils_erp_rrk =
9912 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9913 connect.fils_erp_rrk_len =
9914 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
9915 changed |= UPDATE_FILS_ERP_INFO;
9916 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
9917 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
9918 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
9919 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
9920 return -EINVAL;
9921 }
9922
9923 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
9924 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
9925 if (!nl80211_valid_auth_type(rdev, auth_type,
9926 NL80211_CMD_CONNECT))
9927 return -EINVAL;
9928
9929 if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
9930 fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
9931 return -EINVAL;
9932
9933 connect.auth_type = auth_type;
9934 changed |= UPDATE_AUTH_TYPE;
9935 }
9936
088e8df8 9937 wdev_lock(dev->ieee80211_ptr);
9938 if (!wdev->current_bss)
9939 ret = -ENOLINK;
9940 else
9941 ret = rdev_update_connect_params(rdev, dev, &connect, changed);
9942 wdev_unlock(dev->ieee80211_ptr);
9943
9944 return ret;
9945}
9946
b23aa676
SO
9947static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
9948{
4c476991
JB
9949 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9950 struct net_device *dev = info->user_ptr[1];
b23aa676 9951 u16 reason;
83739b03 9952 int ret;
b23aa676 9953
bad29297
AZ
9954 if (dev->ieee80211_ptr->conn_owner_nlportid &&
9955 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
9956 return -EPERM;
9957
b23aa676
SO
9958 if (!info->attrs[NL80211_ATTR_REASON_CODE])
9959 reason = WLAN_REASON_DEAUTH_LEAVING;
9960 else
9961 reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
9962
9963 if (reason == 0)
9964 return -EINVAL;
9965
074ac8df 9966 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
9967 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
9968 return -EOPNOTSUPP;
b23aa676 9969
83739b03
JB
9970 wdev_lock(dev->ieee80211_ptr);
9971 ret = cfg80211_disconnect(rdev, dev, reason, true);
9972 wdev_unlock(dev->ieee80211_ptr);
9973 return ret;
b23aa676
SO
9974}
9975
463d0183
JB
9976static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
9977{
4c476991 9978 struct cfg80211_registered_device *rdev = info->user_ptr[0];
463d0183
JB
9979 struct net *net;
9980 int err;
463d0183 9981
4b681c82
VK
9982 if (info->attrs[NL80211_ATTR_PID]) {
9983 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
9984
9985 net = get_net_ns_by_pid(pid);
9986 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
9987 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
463d0183 9988
4b681c82
VK
9989 net = get_net_ns_by_fd(fd);
9990 } else {
9991 return -EINVAL;
9992 }
463d0183 9993
4c476991
JB
9994 if (IS_ERR(net))
9995 return PTR_ERR(net);
463d0183
JB
9996
9997 err = 0;
9998
9999 /* check if anything to do */
4c476991
JB
10000 if (!net_eq(wiphy_net(&rdev->wiphy), net))
10001 err = cfg80211_switch_netns(rdev, net);
463d0183 10002
463d0183 10003 put_net(net);
463d0183
JB
10004 return err;
10005}
10006
67fbb16b
SO
10007static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info)
10008{
4c476991 10009 struct cfg80211_registered_device *rdev = info->user_ptr[0];
67fbb16b
SO
10010 int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev,
10011 struct cfg80211_pmksa *pmksa) = NULL;
4c476991 10012 struct net_device *dev = info->user_ptr[1];
67fbb16b
SO
10013 struct cfg80211_pmksa pmksa;
10014
10015 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
10016
67fbb16b
SO
10017 if (!info->attrs[NL80211_ATTR_PMKID])
10018 return -EINVAL;
10019
67fbb16b 10020 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
a3caf744
VK
10021
10022 if (info->attrs[NL80211_ATTR_MAC]) {
10023 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
10024 } else if (info->attrs[NL80211_ATTR_SSID] &&
10025 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
10026 (info->genlhdr->cmd == NL80211_CMD_DEL_PMKSA ||
10027 info->attrs[NL80211_ATTR_PMK])) {
10028 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10029 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10030 pmksa.cache_id =
10031 nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
10032 } else {
10033 return -EINVAL;
10034 }
10035 if (info->attrs[NL80211_ATTR_PMK]) {
10036 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
10037 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
10038 }
67fbb16b 10039
074ac8df 10040 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
6c900360
LD
10041 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
10042 !(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP &&
10043 wiphy_ext_feature_isset(&rdev->wiphy,
10044 NL80211_EXT_FEATURE_AP_PMKSA_CACHING)))
4c476991 10045 return -EOPNOTSUPP;
67fbb16b
SO
10046
10047 switch (info->genlhdr->cmd) {
10048 case NL80211_CMD_SET_PMKSA:
10049 rdev_ops = rdev->ops->set_pmksa;
10050 break;
10051 case NL80211_CMD_DEL_PMKSA:
10052 rdev_ops = rdev->ops->del_pmksa;
10053 break;
10054 default:
10055 WARN_ON(1);
10056 break;
10057 }
10058
4c476991
JB
10059 if (!rdev_ops)
10060 return -EOPNOTSUPP;
67fbb16b 10061
4c476991 10062 return rdev_ops(&rdev->wiphy, dev, &pmksa);
67fbb16b
SO
10063}
10064
10065static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
10066{
4c476991
JB
10067 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10068 struct net_device *dev = info->user_ptr[1];
67fbb16b 10069
074ac8df 10070 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10071 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10072 return -EOPNOTSUPP;
67fbb16b 10073
4c476991
JB
10074 if (!rdev->ops->flush_pmksa)
10075 return -EOPNOTSUPP;
67fbb16b 10076
e35e4d28 10077 return rdev_flush_pmksa(rdev, dev);
67fbb16b
SO
10078}
10079
109086ce
AN
10080static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
10081{
10082 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10083 struct net_device *dev = info->user_ptr[1];
10084 u8 action_code, dialog_token;
df942e7b 10085 u32 peer_capability = 0;
109086ce
AN
10086 u16 status_code;
10087 u8 *peer;
31fa97c5 10088 bool initiator;
109086ce
AN
10089
10090 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
10091 !rdev->ops->tdls_mgmt)
10092 return -EOPNOTSUPP;
10093
10094 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
10095 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
10096 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
10097 !info->attrs[NL80211_ATTR_IE] ||
10098 !info->attrs[NL80211_ATTR_MAC])
10099 return -EINVAL;
10100
10101 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
10102 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
10103 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
10104 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
31fa97c5 10105 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
df942e7b
SDU
10106 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
10107 peer_capability =
10108 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
109086ce 10109
e35e4d28 10110 return rdev_tdls_mgmt(rdev, dev, peer, action_code,
df942e7b 10111 dialog_token, status_code, peer_capability,
31fa97c5 10112 initiator,
e35e4d28
HG
10113 nla_data(info->attrs[NL80211_ATTR_IE]),
10114 nla_len(info->attrs[NL80211_ATTR_IE]));
109086ce
AN
10115}
10116
10117static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
10118{
10119 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10120 struct net_device *dev = info->user_ptr[1];
10121 enum nl80211_tdls_operation operation;
10122 u8 *peer;
10123
10124 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
10125 !rdev->ops->tdls_oper)
10126 return -EOPNOTSUPP;
10127
10128 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
10129 !info->attrs[NL80211_ATTR_MAC])
10130 return -EINVAL;
10131
10132 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
10133 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
10134
e35e4d28 10135 return rdev_tdls_oper(rdev, dev, peer, operation);
109086ce
AN
10136}
10137
9588bbd5
JM
10138static int nl80211_remain_on_channel(struct sk_buff *skb,
10139 struct genl_info *info)
10140{
4c476991 10141 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10142 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 10143 struct cfg80211_chan_def chandef;
34373d12 10144 const struct cfg80211_chan_def *compat_chandef;
9588bbd5
JM
10145 struct sk_buff *msg;
10146 void *hdr;
10147 u64 cookie;
683b6d3b 10148 u32 duration;
9588bbd5
JM
10149 int err;
10150
10151 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
10152 !info->attrs[NL80211_ATTR_DURATION])
10153 return -EINVAL;
10154
10155 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
10156
ebf348fc
JB
10157 if (!rdev->ops->remain_on_channel ||
10158 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
10159 return -EOPNOTSUPP;
10160
9588bbd5 10161 /*
ebf348fc
JB
10162 * We should be on that channel for at least a minimum amount of
10163 * time (10ms) but no longer than the driver supports.
9588bbd5 10164 */
ebf348fc 10165 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
a293911d 10166 duration > rdev->wiphy.max_remain_on_channel_duration)
9588bbd5
JM
10167 return -EINVAL;
10168
683b6d3b
JB
10169 err = nl80211_parse_chandef(rdev, info, &chandef);
10170 if (err)
10171 return err;
9588bbd5 10172
34373d12
VT
10173 wdev_lock(wdev);
10174 if (!cfg80211_off_channel_oper_allowed(wdev) &&
10175 !cfg80211_chandef_identical(&wdev->chandef, &chandef)) {
10176 compat_chandef = cfg80211_chandef_compatible(&wdev->chandef,
10177 &chandef);
10178 if (compat_chandef != &chandef) {
10179 wdev_unlock(wdev);
10180 return -EBUSY;
10181 }
10182 }
10183 wdev_unlock(wdev);
10184
9588bbd5 10185 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
10186 if (!msg)
10187 return -ENOMEM;
9588bbd5 10188
15e47304 10189 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
9588bbd5 10190 NL80211_CMD_REMAIN_ON_CHANNEL);
cb35fba3
DC
10191 if (!hdr) {
10192 err = -ENOBUFS;
9588bbd5
JM
10193 goto free_msg;
10194 }
10195
683b6d3b
JB
10196 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
10197 duration, &cookie);
9588bbd5
JM
10198
10199 if (err)
10200 goto free_msg;
10201
2dad624e
ND
10202 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10203 NL80211_ATTR_PAD))
9360ffd1 10204 goto nla_put_failure;
9588bbd5
JM
10205
10206 genlmsg_end(msg, hdr);
4c476991
JB
10207
10208 return genlmsg_reply(msg, info);
9588bbd5
JM
10209
10210 nla_put_failure:
10211 err = -ENOBUFS;
10212 free_msg:
10213 nlmsg_free(msg);
9588bbd5
JM
10214 return err;
10215}
10216
10217static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
10218 struct genl_info *info)
10219{
4c476991 10220 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10221 struct wireless_dev *wdev = info->user_ptr[1];
9588bbd5 10222 u64 cookie;
9588bbd5
JM
10223
10224 if (!info->attrs[NL80211_ATTR_COOKIE])
10225 return -EINVAL;
10226
4c476991
JB
10227 if (!rdev->ops->cancel_remain_on_channel)
10228 return -EOPNOTSUPP;
9588bbd5 10229
9588bbd5
JM
10230 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10231
e35e4d28 10232 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
9588bbd5
JM
10233}
10234
13ae75b1
JM
10235static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
10236 struct genl_info *info)
10237{
13ae75b1 10238 struct cfg80211_bitrate_mask mask;
a7c7fbff 10239 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 10240 struct net_device *dev = info->user_ptr[1];
a7c7fbff 10241 int err;
13ae75b1 10242
4c476991
JB
10243 if (!rdev->ops->set_bitrate_mask)
10244 return -EOPNOTSUPP;
13ae75b1 10245
a7c7fbff
PK
10246 err = nl80211_parse_tx_bitrate_mask(info, &mask);
10247 if (err)
10248 return err;
13ae75b1 10249
e35e4d28 10250 return rdev_set_bitrate_mask(rdev, dev, NULL, &mask);
13ae75b1
JM
10251}
10252
2e161f78 10253static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 10254{
4c476991 10255 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10256 struct wireless_dev *wdev = info->user_ptr[1];
2e161f78 10257 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
026331c4
JM
10258
10259 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
10260 return -EINVAL;
10261
2e161f78
JB
10262 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
10263 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
026331c4 10264
71bbc994
JB
10265 switch (wdev->iftype) {
10266 case NL80211_IFTYPE_STATION:
10267 case NL80211_IFTYPE_ADHOC:
10268 case NL80211_IFTYPE_P2P_CLIENT:
10269 case NL80211_IFTYPE_AP:
10270 case NL80211_IFTYPE_AP_VLAN:
10271 case NL80211_IFTYPE_MESH_POINT:
10272 case NL80211_IFTYPE_P2P_GO:
98104fde 10273 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 10274 break;
cb3b7d87 10275 case NL80211_IFTYPE_NAN:
71bbc994 10276 default:
4c476991 10277 return -EOPNOTSUPP;
71bbc994 10278 }
026331c4
JM
10279
10280 /* not much point in registering if we can't reply */
4c476991
JB
10281 if (!rdev->ops->mgmt_tx)
10282 return -EOPNOTSUPP;
026331c4 10283
15e47304 10284 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
026331c4
JM
10285 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
10286 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]));
026331c4
JM
10287}
10288
2e161f78 10289static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
026331c4 10290{
4c476991 10291 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10292 struct wireless_dev *wdev = info->user_ptr[1];
683b6d3b 10293 struct cfg80211_chan_def chandef;
026331c4 10294 int err;
d64d373f 10295 void *hdr = NULL;
026331c4 10296 u64 cookie;
e247bd90 10297 struct sk_buff *msg = NULL;
b176e629
AO
10298 struct cfg80211_mgmt_tx_params params = {
10299 .dont_wait_for_ack =
10300 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
10301 };
026331c4 10302
683b6d3b 10303 if (!info->attrs[NL80211_ATTR_FRAME])
026331c4
JM
10304 return -EINVAL;
10305
4c476991
JB
10306 if (!rdev->ops->mgmt_tx)
10307 return -EOPNOTSUPP;
026331c4 10308
71bbc994 10309 switch (wdev->iftype) {
ea141b75
AQ
10310 case NL80211_IFTYPE_P2P_DEVICE:
10311 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
10312 return -EINVAL;
71bbc994
JB
10313 case NL80211_IFTYPE_STATION:
10314 case NL80211_IFTYPE_ADHOC:
10315 case NL80211_IFTYPE_P2P_CLIENT:
10316 case NL80211_IFTYPE_AP:
10317 case NL80211_IFTYPE_AP_VLAN:
10318 case NL80211_IFTYPE_MESH_POINT:
10319 case NL80211_IFTYPE_P2P_GO:
10320 break;
cb3b7d87 10321 case NL80211_IFTYPE_NAN:
71bbc994 10322 default:
4c476991 10323 return -EOPNOTSUPP;
71bbc994 10324 }
026331c4 10325
f7ca38df 10326 if (info->attrs[NL80211_ATTR_DURATION]) {
7c4ef712 10327 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
f7ca38df 10328 return -EINVAL;
b176e629 10329 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
ebf348fc
JB
10330
10331 /*
10332 * We should wait on the channel for at least a minimum amount
10333 * of time (10ms) but no longer than the driver supports.
10334 */
b176e629
AO
10335 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
10336 params.wait > rdev->wiphy.max_remain_on_channel_duration)
ebf348fc 10337 return -EINVAL;
f7ca38df
JB
10338 }
10339
b176e629 10340 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
f7ca38df 10341
b176e629 10342 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
7c4ef712
JB
10343 return -EINVAL;
10344
b176e629 10345 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
e9f935e3 10346
ea141b75
AQ
10347 /* get the channel if any has been specified, otherwise pass NULL to
10348 * the driver. The latter will use the current one
10349 */
10350 chandef.chan = NULL;
10351 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
10352 err = nl80211_parse_chandef(rdev, info, &chandef);
10353 if (err)
10354 return err;
10355 }
10356
b176e629 10357 if (!chandef.chan && params.offchan)
ea141b75 10358 return -EINVAL;
026331c4 10359
34373d12
VT
10360 wdev_lock(wdev);
10361 if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
10362 wdev_unlock(wdev);
10363 return -EBUSY;
10364 }
10365 wdev_unlock(wdev);
10366
34d22ce2
AO
10367 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
10368 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
10369
10370 if (info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]) {
10371 int len = nla_len(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
10372 int i;
10373
10374 if (len % sizeof(u16))
10375 return -EINVAL;
10376
10377 params.n_csa_offsets = len / sizeof(u16);
10378 params.csa_offsets =
10379 nla_data(info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX]);
10380
10381 /* check that all the offsets fit the frame */
10382 for (i = 0; i < params.n_csa_offsets; i++) {
10383 if (params.csa_offsets[i] >= params.len)
10384 return -EINVAL;
10385 }
10386 }
10387
b176e629 10388 if (!params.dont_wait_for_ack) {
e247bd90
JB
10389 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
10390 if (!msg)
10391 return -ENOMEM;
026331c4 10392
15e47304 10393 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
e247bd90 10394 NL80211_CMD_FRAME);
cb35fba3
DC
10395 if (!hdr) {
10396 err = -ENOBUFS;
e247bd90
JB
10397 goto free_msg;
10398 }
026331c4 10399 }
e247bd90 10400
b176e629
AO
10401 params.chan = chandef.chan;
10402 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
026331c4
JM
10403 if (err)
10404 goto free_msg;
10405
e247bd90 10406 if (msg) {
2dad624e
ND
10407 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
10408 NL80211_ATTR_PAD))
9360ffd1 10409 goto nla_put_failure;
026331c4 10410
e247bd90
JB
10411 genlmsg_end(msg, hdr);
10412 return genlmsg_reply(msg, info);
10413 }
10414
10415 return 0;
026331c4
JM
10416
10417 nla_put_failure:
10418 err = -ENOBUFS;
10419 free_msg:
10420 nlmsg_free(msg);
026331c4
JM
10421 return err;
10422}
10423
f7ca38df
JB
10424static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
10425{
10426 struct cfg80211_registered_device *rdev = info->user_ptr[0];
71bbc994 10427 struct wireless_dev *wdev = info->user_ptr[1];
f7ca38df
JB
10428 u64 cookie;
10429
10430 if (!info->attrs[NL80211_ATTR_COOKIE])
10431 return -EINVAL;
10432
10433 if (!rdev->ops->mgmt_tx_cancel_wait)
10434 return -EOPNOTSUPP;
10435
71bbc994
JB
10436 switch (wdev->iftype) {
10437 case NL80211_IFTYPE_STATION:
10438 case NL80211_IFTYPE_ADHOC:
10439 case NL80211_IFTYPE_P2P_CLIENT:
10440 case NL80211_IFTYPE_AP:
10441 case NL80211_IFTYPE_AP_VLAN:
10442 case NL80211_IFTYPE_P2P_GO:
98104fde 10443 case NL80211_IFTYPE_P2P_DEVICE:
71bbc994 10444 break;
cb3b7d87 10445 case NL80211_IFTYPE_NAN:
71bbc994 10446 default:
f7ca38df 10447 return -EOPNOTSUPP;
71bbc994 10448 }
f7ca38df
JB
10449
10450 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10451
e35e4d28 10452 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
f7ca38df
JB
10453}
10454
ffb9eb3d
KV
10455static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
10456{
4c476991 10457 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d 10458 struct wireless_dev *wdev;
4c476991 10459 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
10460 u8 ps_state;
10461 bool state;
10462 int err;
10463
4c476991
JB
10464 if (!info->attrs[NL80211_ATTR_PS_STATE])
10465 return -EINVAL;
ffb9eb3d
KV
10466
10467 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
10468
ffb9eb3d
KV
10469 wdev = dev->ieee80211_ptr;
10470
4c476991
JB
10471 if (!rdev->ops->set_power_mgmt)
10472 return -EOPNOTSUPP;
ffb9eb3d
KV
10473
10474 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
10475
10476 if (state == wdev->ps)
4c476991 10477 return 0;
ffb9eb3d 10478
e35e4d28 10479 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
4c476991
JB
10480 if (!err)
10481 wdev->ps = state;
ffb9eb3d
KV
10482 return err;
10483}
10484
10485static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
10486{
4c476991 10487 struct cfg80211_registered_device *rdev = info->user_ptr[0];
ffb9eb3d
KV
10488 enum nl80211_ps_state ps_state;
10489 struct wireless_dev *wdev;
4c476991 10490 struct net_device *dev = info->user_ptr[1];
ffb9eb3d
KV
10491 struct sk_buff *msg;
10492 void *hdr;
10493 int err;
10494
ffb9eb3d
KV
10495 wdev = dev->ieee80211_ptr;
10496
4c476991
JB
10497 if (!rdev->ops->set_power_mgmt)
10498 return -EOPNOTSUPP;
ffb9eb3d
KV
10499
10500 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4c476991
JB
10501 if (!msg)
10502 return -ENOMEM;
ffb9eb3d 10503
15e47304 10504 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ffb9eb3d
KV
10505 NL80211_CMD_GET_POWER_SAVE);
10506 if (!hdr) {
4c476991 10507 err = -ENOBUFS;
ffb9eb3d
KV
10508 goto free_msg;
10509 }
10510
10511 if (wdev->ps)
10512 ps_state = NL80211_PS_ENABLED;
10513 else
10514 ps_state = NL80211_PS_DISABLED;
10515
9360ffd1
DM
10516 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
10517 goto nla_put_failure;
ffb9eb3d
KV
10518
10519 genlmsg_end(msg, hdr);
4c476991 10520 return genlmsg_reply(msg, info);
ffb9eb3d 10521
4c476991 10522 nla_put_failure:
ffb9eb3d 10523 err = -ENOBUFS;
4c476991 10524 free_msg:
ffb9eb3d 10525 nlmsg_free(msg);
ffb9eb3d
KV
10526 return err;
10527}
10528
94e860f1
JB
10529static const struct nla_policy
10530nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
4a4b8169 10531 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
d6dc1a38
JO
10532 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
10533 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
84f10708
TP
10534 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
10535 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
10536 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
bee427b8 10537 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
d6dc1a38
JO
10538};
10539
84f10708 10540static int nl80211_set_cqm_txe(struct genl_info *info,
d9d8b019 10541 u32 rate, u32 pkts, u32 intvl)
84f10708
TP
10542{
10543 struct cfg80211_registered_device *rdev = info->user_ptr[0];
84f10708 10544 struct net_device *dev = info->user_ptr[1];
1da5fcc8 10545 struct wireless_dev *wdev = dev->ieee80211_ptr;
84f10708 10546
d9d8b019 10547 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
84f10708
TP
10548 return -EINVAL;
10549
84f10708
TP
10550 if (!rdev->ops->set_cqm_txe_config)
10551 return -EOPNOTSUPP;
10552
10553 if (wdev->iftype != NL80211_IFTYPE_STATION &&
10554 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
10555 return -EOPNOTSUPP;
10556
e35e4d28 10557 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
84f10708
TP
10558}
10559
4a4b8169
AZ
10560static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
10561 struct net_device *dev)
10562{
10563 struct wireless_dev *wdev = dev->ieee80211_ptr;
10564 s32 last, low, high;
10565 u32 hyst;
1222a160 10566 int i, n, low_index;
4a4b8169
AZ
10567 int err;
10568
10569 /* RSSI reporting disabled? */
10570 if (!wdev->cqm_config)
10571 return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
10572
10573 /*
10574 * Obtain current RSSI value if possible, if not and no RSSI threshold
10575 * event has been received yet, we should receive an event after a
10576 * connection is established and enough beacons received to calculate
10577 * the average.
10578 */
10579 if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss &&
10580 rdev->ops->get_station) {
73887fd9 10581 struct station_info sinfo = {};
4a4b8169
AZ
10582 u8 *mac_addr;
10583
10584 mac_addr = wdev->current_bss->pub.bssid;
10585
73887fd9
JB
10586 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
10587 if (err)
4a4b8169
AZ
10588 return err;
10589
397c657a 10590 if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
4a4b8169 10591 wdev->cqm_config->last_rssi_event_value =
73887fd9 10592 (s8) sinfo.rx_beacon_signal_avg;
4a4b8169
AZ
10593 }
10594
10595 last = wdev->cqm_config->last_rssi_event_value;
10596 hyst = wdev->cqm_config->rssi_hyst;
10597 n = wdev->cqm_config->n_rssi_thresholds;
10598
10599 for (i = 0; i < n; i++)
10600 if (last < wdev->cqm_config->rssi_thresholds[i])
10601 break;
10602
1222a160
MH
10603 low_index = i - 1;
10604 if (low_index >= 0) {
10605 low_index = array_index_nospec(low_index, n);
10606 low = wdev->cqm_config->rssi_thresholds[low_index] - hyst;
10607 } else {
10608 low = S32_MIN;
10609 }
10610 if (i < n) {
10611 i = array_index_nospec(i, n);
10612 high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1;
10613 } else {
10614 high = S32_MAX;
10615 }
4a4b8169
AZ
10616
10617 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
10618}
10619
d6dc1a38 10620static int nl80211_set_cqm_rssi(struct genl_info *info,
4a4b8169
AZ
10621 const s32 *thresholds, int n_thresholds,
10622 u32 hysteresis)
d6dc1a38 10623{
4c476991 10624 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4c476991 10625 struct net_device *dev = info->user_ptr[1];
1da5fcc8 10626 struct wireless_dev *wdev = dev->ieee80211_ptr;
4a4b8169
AZ
10627 int i, err;
10628 s32 prev = S32_MIN;
d6dc1a38 10629
4a4b8169
AZ
10630 /* Check all values negative and sorted */
10631 for (i = 0; i < n_thresholds; i++) {
10632 if (thresholds[i] > 0 || thresholds[i] <= prev)
10633 return -EINVAL;
d6dc1a38 10634
4a4b8169
AZ
10635 prev = thresholds[i];
10636 }
d6dc1a38 10637
074ac8df 10638 if (wdev->iftype != NL80211_IFTYPE_STATION &&
4c476991
JB
10639 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
10640 return -EOPNOTSUPP;
d6dc1a38 10641
4a4b8169
AZ
10642 wdev_lock(wdev);
10643 cfg80211_cqm_config_free(wdev);
10644 wdev_unlock(wdev);
10645
10646 if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) {
10647 if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */
10648 return rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
10649
10650 return rdev_set_cqm_rssi_config(rdev, dev,
10651 thresholds[0], hysteresis);
10652 }
10653
10654 if (!wiphy_ext_feature_isset(&rdev->wiphy,
10655 NL80211_EXT_FEATURE_CQM_RSSI_LIST))
10656 return -EOPNOTSUPP;
10657
10658 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
10659 n_thresholds = 0;
10660
10661 wdev_lock(wdev);
10662 if (n_thresholds) {
10663 struct cfg80211_cqm_config *cqm_config;
10664
10665 cqm_config = kzalloc(sizeof(struct cfg80211_cqm_config) +
10666 n_thresholds * sizeof(s32), GFP_KERNEL);
10667 if (!cqm_config) {
10668 err = -ENOMEM;
10669 goto unlock;
10670 }
10671
10672 cqm_config->rssi_hyst = hysteresis;
10673 cqm_config->n_rssi_thresholds = n_thresholds;
10674 memcpy(cqm_config->rssi_thresholds, thresholds,
10675 n_thresholds * sizeof(s32));
10676
10677 wdev->cqm_config = cqm_config;
10678 }
10679
10680 err = cfg80211_cqm_rssi_update(rdev, dev);
10681
10682unlock:
10683 wdev_unlock(wdev);
10684
10685 return err;
d6dc1a38
JO
10686}
10687
10688static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
10689{
10690 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
10691 struct nlattr *cqm;
10692 int err;
10693
10694 cqm = info->attrs[NL80211_ATTR_CQM];
1da5fcc8
JB
10695 if (!cqm)
10696 return -EINVAL;
d6dc1a38 10697
8cb08174
JB
10698 err = nla_parse_nested_deprecated(attrs, NL80211_ATTR_CQM_MAX, cqm,
10699 nl80211_attr_cqm_policy,
10700 info->extack);
d6dc1a38 10701 if (err)
1da5fcc8 10702 return err;
d6dc1a38
JO
10703
10704 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
10705 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
4a4b8169
AZ
10706 const s32 *thresholds =
10707 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
10708 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
1da5fcc8 10709 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
d6dc1a38 10710
4a4b8169
AZ
10711 if (len % 4)
10712 return -EINVAL;
10713
10714 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
10715 hysteresis);
1da5fcc8
JB
10716 }
10717
10718 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
10719 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
10720 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
10721 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
10722 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
10723 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
10724
10725 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
10726 }
10727
10728 return -EINVAL;
d6dc1a38
JO
10729}
10730
6e0bd6c3
RL
10731static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
10732{
10733 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10734 struct net_device *dev = info->user_ptr[1];
10735 struct ocb_setup setup = {};
10736 int err;
10737
10738 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
10739 if (err)
10740 return err;
10741
10742 return cfg80211_join_ocb(rdev, dev, &setup);
10743}
10744
10745static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
10746{
10747 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10748 struct net_device *dev = info->user_ptr[1];
10749
10750 return cfg80211_leave_ocb(rdev, dev);
10751}
10752
29cbe68c
JB
10753static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
10754{
10755 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10756 struct net_device *dev = info->user_ptr[1];
10757 struct mesh_config cfg;
c80d545d 10758 struct mesh_setup setup;
29cbe68c
JB
10759 int err;
10760
10761 /* start with default */
10762 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
c80d545d 10763 memcpy(&setup, &default_mesh_setup, sizeof(setup));
29cbe68c 10764
24bdd9f4 10765 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
29cbe68c 10766 /* and parse parameters if given */
24bdd9f4 10767 err = nl80211_parse_mesh_config(info, &cfg, NULL);
29cbe68c
JB
10768 if (err)
10769 return err;
10770 }
10771
10772 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
10773 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
10774 return -EINVAL;
10775
c80d545d
JC
10776 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
10777 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
10778
4bb62344
CYY
10779 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
10780 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
10781 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
10782 return -EINVAL;
10783
9bdbf04d
MP
10784 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
10785 setup.beacon_interval =
10786 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
12d20fc9 10787
0c317a02
PK
10788 err = cfg80211_validate_beacon_int(rdev,
10789 NL80211_IFTYPE_MESH_POINT,
10790 setup.beacon_interval);
12d20fc9
PK
10791 if (err)
10792 return err;
9bdbf04d
MP
10793 }
10794
10795 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
10796 setup.dtim_period =
10797 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
10798 if (setup.dtim_period < 1 || setup.dtim_period > 100)
10799 return -EINVAL;
10800 }
10801
c80d545d
JC
10802 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
10803 /* parse additional setup parameters if given */
10804 err = nl80211_parse_mesh_setup(info, &setup);
10805 if (err)
10806 return err;
10807 }
10808
d37bb18a
TP
10809 if (setup.user_mpm)
10810 cfg.auto_open_plinks = false;
10811
cc1d2806 10812 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
683b6d3b
JB
10813 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
10814 if (err)
10815 return err;
cc1d2806 10816 } else {
188c1b3c 10817 /* __cfg80211_join_mesh() will sort it out */
683b6d3b 10818 setup.chandef.chan = NULL;
cc1d2806
JB
10819 }
10820
ffb3cf30
AN
10821 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
10822 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10823 int n_rates =
10824 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
10825 struct ieee80211_supported_band *sband;
10826
10827 if (!setup.chandef.chan)
10828 return -EINVAL;
10829
10830 sband = rdev->wiphy.bands[setup.chandef.chan->band];
10831
10832 err = ieee80211_get_ratemask(sband, rates, n_rates,
10833 &setup.basic_rates);
10834 if (err)
10835 return err;
10836 }
10837
8564e382
JB
10838 if (info->attrs[NL80211_ATTR_TX_RATES]) {
10839 err = nl80211_parse_tx_bitrate_mask(info, &setup.beacon_rate);
10840 if (err)
10841 return err;
10842
265698d7
JB
10843 if (!setup.chandef.chan)
10844 return -EINVAL;
10845
8564e382
JB
10846 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
10847 &setup.beacon_rate);
10848 if (err)
10849 return err;
10850 }
10851
d37d49c2
BB
10852 setup.userspace_handles_dfs =
10853 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
10854
1224f583
DK
10855 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
10856 int r = validate_pae_over_nl80211(rdev, info);
10857
10858 if (r < 0)
10859 return r;
10860
10861 setup.control_port_over_nl80211 = true;
10862 }
10863
188c1b3c
DK
10864 wdev_lock(dev->ieee80211_ptr);
10865 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
10866 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
10867 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
10868 wdev_unlock(dev->ieee80211_ptr);
10869
10870 return err;
29cbe68c
JB
10871}
10872
10873static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
10874{
10875 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10876 struct net_device *dev = info->user_ptr[1];
10877
10878 return cfg80211_leave_mesh(rdev, dev);
10879}
10880
dfb89c56 10881#ifdef CONFIG_PM
bb92d199
AK
10882static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
10883 struct cfg80211_registered_device *rdev)
10884{
6abb9cb9 10885 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
bb92d199
AK
10886 struct nlattr *nl_pats, *nl_pat;
10887 int i, pat_len;
10888
6abb9cb9 10889 if (!wowlan->n_patterns)
bb92d199
AK
10890 return 0;
10891
ae0be8de 10892 nl_pats = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
bb92d199
AK
10893 if (!nl_pats)
10894 return -ENOBUFS;
10895
6abb9cb9 10896 for (i = 0; i < wowlan->n_patterns; i++) {
ae0be8de 10897 nl_pat = nla_nest_start_noflag(msg, i + 1);
bb92d199
AK
10898 if (!nl_pat)
10899 return -ENOBUFS;
6abb9cb9 10900 pat_len = wowlan->patterns[i].pattern_len;
50ac6607 10901 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
6abb9cb9 10902 wowlan->patterns[i].mask) ||
50ac6607
AK
10903 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
10904 wowlan->patterns[i].pattern) ||
10905 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
6abb9cb9 10906 wowlan->patterns[i].pkt_offset))
bb92d199
AK
10907 return -ENOBUFS;
10908 nla_nest_end(msg, nl_pat);
10909 }
10910 nla_nest_end(msg, nl_pats);
10911
10912 return 0;
10913}
10914
2a0e047e
JB
10915static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
10916 struct cfg80211_wowlan_tcp *tcp)
10917{
10918 struct nlattr *nl_tcp;
10919
10920 if (!tcp)
10921 return 0;
10922
ae0be8de
MK
10923 nl_tcp = nla_nest_start_noflag(msg,
10924 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
2a0e047e
JB
10925 if (!nl_tcp)
10926 return -ENOBUFS;
10927
930345ea
JB
10928 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
10929 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
2a0e047e
JB
10930 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
10931 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
10932 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
10933 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
10934 tcp->payload_len, tcp->payload) ||
10935 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
10936 tcp->data_interval) ||
10937 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
10938 tcp->wake_len, tcp->wake_data) ||
10939 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
10940 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
10941 return -ENOBUFS;
10942
10943 if (tcp->payload_seq.len &&
10944 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
10945 sizeof(tcp->payload_seq), &tcp->payload_seq))
10946 return -ENOBUFS;
10947
10948 if (tcp->payload_tok.len &&
10949 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
10950 sizeof(tcp->payload_tok) + tcp->tokens_size,
10951 &tcp->payload_tok))
10952 return -ENOBUFS;
10953
e248ad30
JB
10954 nla_nest_end(msg, nl_tcp);
10955
2a0e047e
JB
10956 return 0;
10957}
10958
75453ccb
LC
10959static int nl80211_send_wowlan_nd(struct sk_buff *msg,
10960 struct cfg80211_sched_scan_request *req)
10961{
3b06d277 10962 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
75453ccb
LC
10963 int i;
10964
10965 if (!req)
10966 return 0;
10967
ae0be8de 10968 nd = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
75453ccb
LC
10969 if (!nd)
10970 return -ENOBUFS;
10971
3b06d277
AS
10972 if (req->n_scan_plans == 1 &&
10973 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
10974 req->scan_plans[0].interval * 1000))
75453ccb
LC
10975 return -ENOBUFS;
10976
21fea567
LC
10977 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
10978 return -ENOBUFS;
10979
bf95ecdb 10980 if (req->relative_rssi_set) {
10981 struct nl80211_bss_select_rssi_adjust rssi_adjust;
10982
10983 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
10984 req->relative_rssi))
10985 return -ENOBUFS;
10986
10987 rssi_adjust.band = req->rssi_adjust.band;
10988 rssi_adjust.delta = req->rssi_adjust.delta;
10989 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
10990 sizeof(rssi_adjust), &rssi_adjust))
10991 return -ENOBUFS;
10992 }
10993
ae0be8de 10994 freqs = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
75453ccb
LC
10995 if (!freqs)
10996 return -ENOBUFS;
10997
53b18980
JB
10998 for (i = 0; i < req->n_channels; i++) {
10999 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
11000 return -ENOBUFS;
11001 }
75453ccb
LC
11002
11003 nla_nest_end(msg, freqs);
11004
11005 if (req->n_match_sets) {
ae0be8de
MK
11006 matches = nla_nest_start_noflag(msg,
11007 NL80211_ATTR_SCHED_SCAN_MATCH);
76e1fb4b
JB
11008 if (!matches)
11009 return -ENOBUFS;
11010
75453ccb 11011 for (i = 0; i < req->n_match_sets; i++) {
ae0be8de 11012 match = nla_nest_start_noflag(msg, i);
76e1fb4b
JB
11013 if (!match)
11014 return -ENOBUFS;
11015
53b18980
JB
11016 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
11017 req->match_sets[i].ssid.ssid_len,
11018 req->match_sets[i].ssid.ssid))
11019 return -ENOBUFS;
75453ccb
LC
11020 nla_nest_end(msg, match);
11021 }
11022 nla_nest_end(msg, matches);
11023 }
11024
ae0be8de 11025 scan_plans = nla_nest_start_noflag(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
3b06d277
AS
11026 if (!scan_plans)
11027 return -ENOBUFS;
11028
11029 for (i = 0; i < req->n_scan_plans; i++) {
ae0be8de 11030 scan_plan = nla_nest_start_noflag(msg, i + 1);
76e1fb4b
JB
11031 if (!scan_plan)
11032 return -ENOBUFS;
11033
67626964 11034 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
3b06d277
AS
11035 req->scan_plans[i].interval) ||
11036 (req->scan_plans[i].iterations &&
11037 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
11038 req->scan_plans[i].iterations)))
11039 return -ENOBUFS;
11040 nla_nest_end(msg, scan_plan);
11041 }
11042 nla_nest_end(msg, scan_plans);
11043
75453ccb
LC
11044 nla_nest_end(msg, nd);
11045
11046 return 0;
11047}
11048
ff1b6e69
JB
11049static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
11050{
11051 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11052 struct sk_buff *msg;
11053 void *hdr;
2a0e047e 11054 u32 size = NLMSG_DEFAULT_SIZE;
ff1b6e69 11055
964dc9e2 11056 if (!rdev->wiphy.wowlan)
ff1b6e69
JB
11057 return -EOPNOTSUPP;
11058
6abb9cb9 11059 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
2a0e047e 11060 /* adjust size to have room for all the data */
6abb9cb9
JB
11061 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
11062 rdev->wiphy.wowlan_config->tcp->payload_len +
11063 rdev->wiphy.wowlan_config->tcp->wake_len +
11064 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
2a0e047e
JB
11065 }
11066
11067 msg = nlmsg_new(size, GFP_KERNEL);
ff1b6e69
JB
11068 if (!msg)
11069 return -ENOMEM;
11070
15e47304 11071 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
ff1b6e69
JB
11072 NL80211_CMD_GET_WOWLAN);
11073 if (!hdr)
11074 goto nla_put_failure;
11075
6abb9cb9 11076 if (rdev->wiphy.wowlan_config) {
ff1b6e69
JB
11077 struct nlattr *nl_wowlan;
11078
ae0be8de
MK
11079 nl_wowlan = nla_nest_start_noflag(msg,
11080 NL80211_ATTR_WOWLAN_TRIGGERS);
ff1b6e69
JB
11081 if (!nl_wowlan)
11082 goto nla_put_failure;
11083
6abb9cb9 11084 if ((rdev->wiphy.wowlan_config->any &&
9360ffd1 11085 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
6abb9cb9 11086 (rdev->wiphy.wowlan_config->disconnect &&
9360ffd1 11087 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
6abb9cb9 11088 (rdev->wiphy.wowlan_config->magic_pkt &&
9360ffd1 11089 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
6abb9cb9 11090 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
9360ffd1 11091 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
6abb9cb9 11092 (rdev->wiphy.wowlan_config->eap_identity_req &&
9360ffd1 11093 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
6abb9cb9 11094 (rdev->wiphy.wowlan_config->four_way_handshake &&
9360ffd1 11095 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
6abb9cb9 11096 (rdev->wiphy.wowlan_config->rfkill_release &&
9360ffd1
DM
11097 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
11098 goto nla_put_failure;
2a0e047e 11099
bb92d199
AK
11100 if (nl80211_send_wowlan_patterns(msg, rdev))
11101 goto nla_put_failure;
2a0e047e 11102
6abb9cb9
JB
11103 if (nl80211_send_wowlan_tcp(msg,
11104 rdev->wiphy.wowlan_config->tcp))
2a0e047e 11105 goto nla_put_failure;
75453ccb
LC
11106
11107 if (nl80211_send_wowlan_nd(
11108 msg,
11109 rdev->wiphy.wowlan_config->nd_config))
11110 goto nla_put_failure;
2a0e047e 11111
ff1b6e69
JB
11112 nla_nest_end(msg, nl_wowlan);
11113 }
11114
11115 genlmsg_end(msg, hdr);
11116 return genlmsg_reply(msg, info);
11117
11118nla_put_failure:
11119 nlmsg_free(msg);
11120 return -ENOBUFS;
11121}
11122
2a0e047e
JB
11123static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
11124 struct nlattr *attr,
11125 struct cfg80211_wowlan *trig)
11126{
11127 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
11128 struct cfg80211_wowlan_tcp *cfg;
11129 struct nl80211_wowlan_tcp_data_token *tok = NULL;
11130 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
11131 u32 size;
11132 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
11133 int err, port;
11134
964dc9e2 11135 if (!rdev->wiphy.wowlan->tcp)
2a0e047e
JB
11136 return -EINVAL;
11137
8cb08174
JB
11138 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TCP, attr,
11139 nl80211_wowlan_tcp_policy, NULL);
2a0e047e
JB
11140 if (err)
11141 return err;
11142
11143 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
11144 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
11145 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
11146 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
11147 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
11148 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
11149 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
11150 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
11151 return -EINVAL;
11152
11153 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
964dc9e2 11154 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
2a0e047e
JB
11155 return -EINVAL;
11156
11157 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
964dc9e2 11158 rdev->wiphy.wowlan->tcp->data_interval_max ||
723d568a 11159 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
2a0e047e
JB
11160 return -EINVAL;
11161
11162 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
964dc9e2 11163 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
2a0e047e
JB
11164 return -EINVAL;
11165
11166 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
11167 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
11168 return -EINVAL;
11169
11170 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
11171 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
11172
11173 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
11174 tokens_size = tokln - sizeof(*tok);
11175
11176 if (!tok->len || tokens_size % tok->len)
11177 return -EINVAL;
964dc9e2 11178 if (!rdev->wiphy.wowlan->tcp->tok)
2a0e047e 11179 return -EINVAL;
964dc9e2 11180 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
2a0e047e 11181 return -EINVAL;
964dc9e2 11182 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
2a0e047e 11183 return -EINVAL;
964dc9e2 11184 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
2a0e047e
JB
11185 return -EINVAL;
11186 if (tok->offset + tok->len > data_size)
11187 return -EINVAL;
11188 }
11189
11190 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
11191 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
964dc9e2 11192 if (!rdev->wiphy.wowlan->tcp->seq)
2a0e047e
JB
11193 return -EINVAL;
11194 if (seq->len == 0 || seq->len > 4)
11195 return -EINVAL;
11196 if (seq->len + seq->offset > data_size)
11197 return -EINVAL;
11198 }
11199
11200 size = sizeof(*cfg);
11201 size += data_size;
11202 size += wake_size + wake_mask_size;
11203 size += tokens_size;
11204
11205 cfg = kzalloc(size, GFP_KERNEL);
11206 if (!cfg)
11207 return -ENOMEM;
67b61f6c
JB
11208 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
11209 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
2a0e047e
JB
11210 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
11211 ETH_ALEN);
11212 if (tb[NL80211_WOWLAN_TCP_SRC_PORT])
11213 port = nla_get_u16(tb[NL80211_WOWLAN_TCP_SRC_PORT]);
11214 else
11215 port = 0;
11216#ifdef CONFIG_INET
11217 /* allocate a socket and port for it and use it */
11218 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
11219 IPPROTO_TCP, &cfg->sock, 1);
11220 if (err) {
11221 kfree(cfg);
11222 return err;
11223 }
11224 if (inet_csk_get_port(cfg->sock->sk, port)) {
11225 sock_release(cfg->sock);
11226 kfree(cfg);
11227 return -EADDRINUSE;
11228 }
11229 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
11230#else
11231 if (!port) {
11232 kfree(cfg);
11233 return -EINVAL;
11234 }
11235 cfg->src_port = port;
11236#endif
11237
11238 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
11239 cfg->payload_len = data_size;
11240 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
11241 memcpy((void *)cfg->payload,
11242 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
11243 data_size);
11244 if (seq)
11245 cfg->payload_seq = *seq;
11246 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
11247 cfg->wake_len = wake_size;
11248 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
11249 memcpy((void *)cfg->wake_data,
11250 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
11251 wake_size);
11252 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
11253 data_size + wake_size;
11254 memcpy((void *)cfg->wake_mask,
11255 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
11256 wake_mask_size);
11257 if (tok) {
11258 cfg->tokens_size = tokens_size;
11259 memcpy(&cfg->payload_tok, tok, sizeof(*tok) + tokens_size);
11260 }
11261
11262 trig->tcp = cfg;
11263
11264 return 0;
11265}
11266
8cd4d456
LC
11267static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
11268 const struct wiphy_wowlan_support *wowlan,
11269 struct nlattr *attr,
11270 struct cfg80211_wowlan *trig)
11271{
11272 struct nlattr **tb;
11273 int err;
11274
6396bb22 11275 tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
8cd4d456
LC
11276 if (!tb)
11277 return -ENOMEM;
11278
11279 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
11280 err = -EOPNOTSUPP;
11281 goto out;
11282 }
11283
8cb08174
JB
11284 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_MAX, attr,
11285 nl80211_policy, NULL);
8cd4d456
LC
11286 if (err)
11287 goto out;
11288
aad1e812
AVS
11289 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
11290 wowlan->max_nd_match_sets);
8cd4d456
LC
11291 err = PTR_ERR_OR_ZERO(trig->nd_config);
11292 if (err)
11293 trig->nd_config = NULL;
11294
11295out:
11296 kfree(tb);
11297 return err;
11298}
11299
ff1b6e69
JB
11300static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
11301{
11302 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11303 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
ff1b6e69 11304 struct cfg80211_wowlan new_triggers = {};
ae33bd81 11305 struct cfg80211_wowlan *ntrig;
964dc9e2 11306 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
ff1b6e69 11307 int err, i;
6abb9cb9 11308 bool prev_enabled = rdev->wiphy.wowlan_config;
98fc4386 11309 bool regular = false;
ff1b6e69 11310
964dc9e2 11311 if (!wowlan)
ff1b6e69
JB
11312 return -EOPNOTSUPP;
11313
ae33bd81
JB
11314 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
11315 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 11316 rdev->wiphy.wowlan_config = NULL;
ae33bd81
JB
11317 goto set_wakeup;
11318 }
ff1b6e69 11319
8cb08174
JB
11320 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TRIG,
11321 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
11322 nl80211_wowlan_policy, info->extack);
ff1b6e69
JB
11323 if (err)
11324 return err;
11325
11326 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
11327 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
11328 return -EINVAL;
11329 new_triggers.any = true;
11330 }
11331
11332 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
11333 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
11334 return -EINVAL;
11335 new_triggers.disconnect = true;
98fc4386 11336 regular = true;
ff1b6e69
JB
11337 }
11338
11339 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
11340 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
11341 return -EINVAL;
11342 new_triggers.magic_pkt = true;
98fc4386 11343 regular = true;
ff1b6e69
JB
11344 }
11345
77dbbb13
JB
11346 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
11347 return -EINVAL;
11348
11349 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
11350 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
11351 return -EINVAL;
11352 new_triggers.gtk_rekey_failure = true;
98fc4386 11353 regular = true;
77dbbb13
JB
11354 }
11355
11356 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
11357 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
11358 return -EINVAL;
11359 new_triggers.eap_identity_req = true;
98fc4386 11360 regular = true;
77dbbb13
JB
11361 }
11362
11363 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
11364 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
11365 return -EINVAL;
11366 new_triggers.four_way_handshake = true;
98fc4386 11367 regular = true;
77dbbb13
JB
11368 }
11369
11370 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
11371 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
11372 return -EINVAL;
11373 new_triggers.rfkill_release = true;
98fc4386 11374 regular = true;
77dbbb13
JB
11375 }
11376
ff1b6e69
JB
11377 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
11378 struct nlattr *pat;
11379 int n_patterns = 0;
bb92d199 11380 int rem, pat_len, mask_len, pkt_offset;
50ac6607 11381 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
ff1b6e69 11382
98fc4386
JB
11383 regular = true;
11384
ff1b6e69
JB
11385 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
11386 rem)
11387 n_patterns++;
11388 if (n_patterns > wowlan->n_patterns)
11389 return -EINVAL;
11390
11391 new_triggers.patterns = kcalloc(n_patterns,
11392 sizeof(new_triggers.patterns[0]),
11393 GFP_KERNEL);
11394 if (!new_triggers.patterns)
11395 return -ENOMEM;
11396
11397 new_triggers.n_patterns = n_patterns;
11398 i = 0;
11399
11400 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
11401 rem) {
922bd80f
JB
11402 u8 *mask_pat;
11403
8cb08174
JB
11404 err = nla_parse_nested_deprecated(pat_tb,
11405 MAX_NL80211_PKTPAT,
11406 pat,
11407 nl80211_packet_pattern_policy,
11408 info->extack);
95bca62f
JB
11409 if (err)
11410 goto error;
11411
ff1b6e69 11412 err = -EINVAL;
50ac6607
AK
11413 if (!pat_tb[NL80211_PKTPAT_MASK] ||
11414 !pat_tb[NL80211_PKTPAT_PATTERN])
ff1b6e69 11415 goto error;
50ac6607 11416 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
ff1b6e69 11417 mask_len = DIV_ROUND_UP(pat_len, 8);
50ac6607 11418 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
ff1b6e69
JB
11419 goto error;
11420 if (pat_len > wowlan->pattern_max_len ||
11421 pat_len < wowlan->pattern_min_len)
11422 goto error;
11423
50ac6607 11424 if (!pat_tb[NL80211_PKTPAT_OFFSET])
bb92d199
AK
11425 pkt_offset = 0;
11426 else
11427 pkt_offset = nla_get_u32(
50ac6607 11428 pat_tb[NL80211_PKTPAT_OFFSET]);
bb92d199
AK
11429 if (pkt_offset > wowlan->max_pkt_offset)
11430 goto error;
11431 new_triggers.patterns[i].pkt_offset = pkt_offset;
11432
922bd80f
JB
11433 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
11434 if (!mask_pat) {
ff1b6e69
JB
11435 err = -ENOMEM;
11436 goto error;
11437 }
922bd80f
JB
11438 new_triggers.patterns[i].mask = mask_pat;
11439 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
ff1b6e69 11440 mask_len);
922bd80f
JB
11441 mask_pat += mask_len;
11442 new_triggers.patterns[i].pattern = mask_pat;
ff1b6e69 11443 new_triggers.patterns[i].pattern_len = pat_len;
922bd80f 11444 memcpy(mask_pat,
50ac6607 11445 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
ff1b6e69
JB
11446 pat_len);
11447 i++;
11448 }
11449 }
11450
2a0e047e 11451 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
98fc4386 11452 regular = true;
2a0e047e
JB
11453 err = nl80211_parse_wowlan_tcp(
11454 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
11455 &new_triggers);
11456 if (err)
11457 goto error;
11458 }
11459
8cd4d456 11460 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
98fc4386 11461 regular = true;
8cd4d456
LC
11462 err = nl80211_parse_wowlan_nd(
11463 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
11464 &new_triggers);
11465 if (err)
11466 goto error;
11467 }
11468
98fc4386
JB
11469 /* The 'any' trigger means the device continues operating more or less
11470 * as in its normal operation mode and wakes up the host on most of the
11471 * normal interrupts (like packet RX, ...)
11472 * It therefore makes little sense to combine with the more constrained
11473 * wakeup trigger modes.
11474 */
11475 if (new_triggers.any && regular) {
11476 err = -EINVAL;
11477 goto error;
11478 }
11479
ae33bd81
JB
11480 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
11481 if (!ntrig) {
11482 err = -ENOMEM;
11483 goto error;
ff1b6e69 11484 }
ae33bd81 11485 cfg80211_rdev_free_wowlan(rdev);
6abb9cb9 11486 rdev->wiphy.wowlan_config = ntrig;
ff1b6e69 11487
ae33bd81 11488 set_wakeup:
6abb9cb9
JB
11489 if (rdev->ops->set_wakeup &&
11490 prev_enabled != !!rdev->wiphy.wowlan_config)
11491 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
6d52563f 11492
ff1b6e69
JB
11493 return 0;
11494 error:
11495 for (i = 0; i < new_triggers.n_patterns; i++)
11496 kfree(new_triggers.patterns[i].mask);
11497 kfree(new_triggers.patterns);
2a0e047e
JB
11498 if (new_triggers.tcp && new_triggers.tcp->sock)
11499 sock_release(new_triggers.tcp->sock);
11500 kfree(new_triggers.tcp);
e5dbe070 11501 kfree(new_triggers.nd_config);
ff1b6e69
JB
11502 return err;
11503}
dfb89c56 11504#endif
ff1b6e69 11505
be29b99a
AK
11506static int nl80211_send_coalesce_rules(struct sk_buff *msg,
11507 struct cfg80211_registered_device *rdev)
11508{
11509 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
11510 int i, j, pat_len;
11511 struct cfg80211_coalesce_rules *rule;
11512
11513 if (!rdev->coalesce->n_rules)
11514 return 0;
11515
ae0be8de 11516 nl_rules = nla_nest_start_noflag(msg, NL80211_ATTR_COALESCE_RULE);
be29b99a
AK
11517 if (!nl_rules)
11518 return -ENOBUFS;
11519
11520 for (i = 0; i < rdev->coalesce->n_rules; i++) {
ae0be8de 11521 nl_rule = nla_nest_start_noflag(msg, i + 1);
be29b99a
AK
11522 if (!nl_rule)
11523 return -ENOBUFS;
11524
11525 rule = &rdev->coalesce->rules[i];
11526 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
11527 rule->delay))
11528 return -ENOBUFS;
11529
11530 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
11531 rule->condition))
11532 return -ENOBUFS;
11533
ae0be8de
MK
11534 nl_pats = nla_nest_start_noflag(msg,
11535 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
be29b99a
AK
11536 if (!nl_pats)
11537 return -ENOBUFS;
11538
11539 for (j = 0; j < rule->n_patterns; j++) {
ae0be8de 11540 nl_pat = nla_nest_start_noflag(msg, j + 1);
be29b99a
AK
11541 if (!nl_pat)
11542 return -ENOBUFS;
11543 pat_len = rule->patterns[j].pattern_len;
11544 if (nla_put(msg, NL80211_PKTPAT_MASK,
11545 DIV_ROUND_UP(pat_len, 8),
11546 rule->patterns[j].mask) ||
11547 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
11548 rule->patterns[j].pattern) ||
11549 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
11550 rule->patterns[j].pkt_offset))
11551 return -ENOBUFS;
11552 nla_nest_end(msg, nl_pat);
11553 }
11554 nla_nest_end(msg, nl_pats);
11555 nla_nest_end(msg, nl_rule);
11556 }
11557 nla_nest_end(msg, nl_rules);
11558
11559 return 0;
11560}
11561
11562static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
11563{
11564 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11565 struct sk_buff *msg;
11566 void *hdr;
11567
11568 if (!rdev->wiphy.coalesce)
11569 return -EOPNOTSUPP;
11570
11571 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11572 if (!msg)
11573 return -ENOMEM;
11574
11575 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
11576 NL80211_CMD_GET_COALESCE);
11577 if (!hdr)
11578 goto nla_put_failure;
11579
11580 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
11581 goto nla_put_failure;
11582
11583 genlmsg_end(msg, hdr);
11584 return genlmsg_reply(msg, info);
11585
11586nla_put_failure:
11587 nlmsg_free(msg);
11588 return -ENOBUFS;
11589}
11590
11591void cfg80211_rdev_free_coalesce(struct cfg80211_registered_device *rdev)
11592{
11593 struct cfg80211_coalesce *coalesce = rdev->coalesce;
11594 int i, j;
11595 struct cfg80211_coalesce_rules *rule;
11596
11597 if (!coalesce)
11598 return;
11599
11600 for (i = 0; i < coalesce->n_rules; i++) {
11601 rule = &coalesce->rules[i];
11602 for (j = 0; j < rule->n_patterns; j++)
11603 kfree(rule->patterns[j].mask);
11604 kfree(rule->patterns);
11605 }
11606 kfree(coalesce->rules);
11607 kfree(coalesce);
11608 rdev->coalesce = NULL;
11609}
11610
11611static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
11612 struct nlattr *rule,
11613 struct cfg80211_coalesce_rules *new_rule)
11614{
11615 int err, i;
11616 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
11617 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
11618 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
11619 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
11620
8cb08174
JB
11621 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_COALESCE_RULE_MAX,
11622 rule, nl80211_coalesce_policy, NULL);
be29b99a
AK
11623 if (err)
11624 return err;
11625
11626 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
11627 new_rule->delay =
11628 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
11629 if (new_rule->delay > coalesce->max_delay)
11630 return -EINVAL;
11631
11632 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
11633 new_rule->condition =
11634 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
be29b99a
AK
11635
11636 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
11637 return -EINVAL;
11638
11639 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
11640 rem)
11641 n_patterns++;
11642 if (n_patterns > coalesce->n_patterns)
11643 return -EINVAL;
11644
11645 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
11646 GFP_KERNEL);
11647 if (!new_rule->patterns)
11648 return -ENOMEM;
11649
11650 new_rule->n_patterns = n_patterns;
11651 i = 0;
11652
11653 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
11654 rem) {
922bd80f
JB
11655 u8 *mask_pat;
11656
8cb08174
JB
11657 err = nla_parse_nested_deprecated(pat_tb, MAX_NL80211_PKTPAT,
11658 pat,
11659 nl80211_packet_pattern_policy,
11660 NULL);
95bca62f
JB
11661 if (err)
11662 return err;
11663
be29b99a
AK
11664 if (!pat_tb[NL80211_PKTPAT_MASK] ||
11665 !pat_tb[NL80211_PKTPAT_PATTERN])
11666 return -EINVAL;
11667 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
11668 mask_len = DIV_ROUND_UP(pat_len, 8);
11669 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
11670 return -EINVAL;
11671 if (pat_len > coalesce->pattern_max_len ||
11672 pat_len < coalesce->pattern_min_len)
11673 return -EINVAL;
11674
11675 if (!pat_tb[NL80211_PKTPAT_OFFSET])
11676 pkt_offset = 0;
11677 else
11678 pkt_offset = nla_get_u32(pat_tb[NL80211_PKTPAT_OFFSET]);
11679 if (pkt_offset > coalesce->max_pkt_offset)
11680 return -EINVAL;
11681 new_rule->patterns[i].pkt_offset = pkt_offset;
11682
922bd80f
JB
11683 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
11684 if (!mask_pat)
be29b99a 11685 return -ENOMEM;
922bd80f
JB
11686
11687 new_rule->patterns[i].mask = mask_pat;
11688 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
11689 mask_len);
11690
11691 mask_pat += mask_len;
11692 new_rule->patterns[i].pattern = mask_pat;
be29b99a 11693 new_rule->patterns[i].pattern_len = pat_len;
922bd80f
JB
11694 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
11695 pat_len);
be29b99a
AK
11696 i++;
11697 }
11698
11699 return 0;
11700}
11701
11702static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
11703{
11704 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11705 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
11706 struct cfg80211_coalesce new_coalesce = {};
11707 struct cfg80211_coalesce *n_coalesce;
11708 int err, rem_rule, n_rules = 0, i, j;
11709 struct nlattr *rule;
11710 struct cfg80211_coalesce_rules *tmp_rule;
11711
11712 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
11713 return -EOPNOTSUPP;
11714
11715 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
11716 cfg80211_rdev_free_coalesce(rdev);
a1056b1b 11717 rdev_set_coalesce(rdev, NULL);
be29b99a
AK
11718 return 0;
11719 }
11720
11721 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
11722 rem_rule)
11723 n_rules++;
11724 if (n_rules > coalesce->n_rules)
11725 return -EINVAL;
11726
11727 new_coalesce.rules = kcalloc(n_rules, sizeof(new_coalesce.rules[0]),
11728 GFP_KERNEL);
11729 if (!new_coalesce.rules)
11730 return -ENOMEM;
11731
11732 new_coalesce.n_rules = n_rules;
11733 i = 0;
11734
11735 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
11736 rem_rule) {
11737 err = nl80211_parse_coalesce_rule(rdev, rule,
11738 &new_coalesce.rules[i]);
11739 if (err)
11740 goto error;
11741
11742 i++;
11743 }
11744
a1056b1b 11745 err = rdev_set_coalesce(rdev, &new_coalesce);
be29b99a
AK
11746 if (err)
11747 goto error;
11748
11749 n_coalesce = kmemdup(&new_coalesce, sizeof(new_coalesce), GFP_KERNEL);
11750 if (!n_coalesce) {
11751 err = -ENOMEM;
11752 goto error;
11753 }
11754 cfg80211_rdev_free_coalesce(rdev);
11755 rdev->coalesce = n_coalesce;
11756
11757 return 0;
11758error:
11759 for (i = 0; i < new_coalesce.n_rules; i++) {
11760 tmp_rule = &new_coalesce.rules[i];
11761 for (j = 0; j < tmp_rule->n_patterns; j++)
11762 kfree(tmp_rule->patterns[j].mask);
11763 kfree(tmp_rule->patterns);
11764 }
11765 kfree(new_coalesce.rules);
11766
11767 return err;
11768}
11769
e5497d76
JB
11770static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
11771{
11772 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11773 struct net_device *dev = info->user_ptr[1];
11774 struct wireless_dev *wdev = dev->ieee80211_ptr;
11775 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
11776 struct cfg80211_gtk_rekey_data rekey_data;
11777 int err;
11778
11779 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
11780 return -EINVAL;
11781
8cb08174
JB
11782 err = nla_parse_nested_deprecated(tb, MAX_NL80211_REKEY_DATA,
11783 info->attrs[NL80211_ATTR_REKEY_DATA],
11784 nl80211_rekey_policy, info->extack);
e5497d76
JB
11785 if (err)
11786 return err;
11787
e785fa0a
VD
11788 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
11789 !tb[NL80211_REKEY_DATA_KCK])
11790 return -EINVAL;
e5497d76
JB
11791 if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
11792 return -ERANGE;
11793 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
11794 return -ERANGE;
11795 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
11796 return -ERANGE;
11797
78f686ca
JB
11798 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
11799 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
11800 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
e5497d76
JB
11801
11802 wdev_lock(wdev);
11803 if (!wdev->current_bss) {
11804 err = -ENOTCONN;
11805 goto out;
11806 }
11807
11808 if (!rdev->ops->set_rekey_data) {
11809 err = -EOPNOTSUPP;
11810 goto out;
11811 }
11812
e35e4d28 11813 err = rdev_set_rekey_data(rdev, dev, &rekey_data);
e5497d76
JB
11814 out:
11815 wdev_unlock(wdev);
11816 return err;
11817}
11818
28946da7
JB
11819static int nl80211_register_unexpected_frame(struct sk_buff *skb,
11820 struct genl_info *info)
11821{
11822 struct net_device *dev = info->user_ptr[1];
11823 struct wireless_dev *wdev = dev->ieee80211_ptr;
11824
11825 if (wdev->iftype != NL80211_IFTYPE_AP &&
11826 wdev->iftype != NL80211_IFTYPE_P2P_GO)
11827 return -EINVAL;
11828
15e47304 11829 if (wdev->ap_unexpected_nlportid)
28946da7
JB
11830 return -EBUSY;
11831
15e47304 11832 wdev->ap_unexpected_nlportid = info->snd_portid;
28946da7
JB
11833 return 0;
11834}
11835
7f6cf311
JB
11836static int nl80211_probe_client(struct sk_buff *skb,
11837 struct genl_info *info)
11838{
11839 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11840 struct net_device *dev = info->user_ptr[1];
11841 struct wireless_dev *wdev = dev->ieee80211_ptr;
11842 struct sk_buff *msg;
11843 void *hdr;
11844 const u8 *addr;
11845 u64 cookie;
11846 int err;
11847
11848 if (wdev->iftype != NL80211_IFTYPE_AP &&
11849 wdev->iftype != NL80211_IFTYPE_P2P_GO)
11850 return -EOPNOTSUPP;
11851
11852 if (!info->attrs[NL80211_ATTR_MAC])
11853 return -EINVAL;
11854
11855 if (!rdev->ops->probe_client)
11856 return -EOPNOTSUPP;
11857
11858 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11859 if (!msg)
11860 return -ENOMEM;
11861
15e47304 11862 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
7f6cf311 11863 NL80211_CMD_PROBE_CLIENT);
cb35fba3
DC
11864 if (!hdr) {
11865 err = -ENOBUFS;
7f6cf311
JB
11866 goto free_msg;
11867 }
11868
11869 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
11870
e35e4d28 11871 err = rdev_probe_client(rdev, dev, addr, &cookie);
7f6cf311
JB
11872 if (err)
11873 goto free_msg;
11874
2dad624e
ND
11875 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
11876 NL80211_ATTR_PAD))
9360ffd1 11877 goto nla_put_failure;
7f6cf311
JB
11878
11879 genlmsg_end(msg, hdr);
11880
11881 return genlmsg_reply(msg, info);
11882
11883 nla_put_failure:
11884 err = -ENOBUFS;
11885 free_msg:
11886 nlmsg_free(msg);
11887 return err;
11888}
11889
5e760230
JB
11890static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
11891{
11892 struct cfg80211_registered_device *rdev = info->user_ptr[0];
37c73b5f
BG
11893 struct cfg80211_beacon_registration *reg, *nreg;
11894 int rv;
5e760230
JB
11895
11896 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
11897 return -EOPNOTSUPP;
11898
37c73b5f
BG
11899 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
11900 if (!nreg)
11901 return -ENOMEM;
11902
11903 /* First, check if already registered. */
11904 spin_lock_bh(&rdev->beacon_registrations_lock);
11905 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
11906 if (reg->nlportid == info->snd_portid) {
11907 rv = -EALREADY;
11908 goto out_err;
11909 }
11910 }
11911 /* Add it to the list */
11912 nreg->nlportid = info->snd_portid;
11913 list_add(&nreg->list, &rdev->beacon_registrations);
5e760230 11914
37c73b5f 11915 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
11916
11917 return 0;
37c73b5f
BG
11918out_err:
11919 spin_unlock_bh(&rdev->beacon_registrations_lock);
11920 kfree(nreg);
11921 return rv;
5e760230
JB
11922}
11923
98104fde
JB
11924static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
11925{
11926 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11927 struct wireless_dev *wdev = info->user_ptr[1];
11928 int err;
11929
11930 if (!rdev->ops->start_p2p_device)
11931 return -EOPNOTSUPP;
11932
11933 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
11934 return -EOPNOTSUPP;
11935
73c7da3d 11936 if (wdev_running(wdev))
98104fde
JB
11937 return 0;
11938
b6a55015
LC
11939 if (rfkill_blocked(rdev->rfkill))
11940 return -ERFKILL;
98104fde 11941
eeb126e9 11942 err = rdev_start_p2p_device(rdev, wdev);
98104fde
JB
11943 if (err)
11944 return err;
11945
73c7da3d 11946 wdev->is_running = true;
98104fde 11947 rdev->opencount++;
98104fde
JB
11948
11949 return 0;
11950}
11951
11952static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
11953{
11954 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11955 struct wireless_dev *wdev = info->user_ptr[1];
11956
11957 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
11958 return -EOPNOTSUPP;
11959
11960 if (!rdev->ops->stop_p2p_device)
11961 return -EOPNOTSUPP;
11962
f9f47529 11963 cfg80211_stop_p2p_device(rdev, wdev);
98104fde
JB
11964
11965 return 0;
11966}
11967
cb3b7d87
AB
11968static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
11969{
11970 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11971 struct wireless_dev *wdev = info->user_ptr[1];
11972 struct cfg80211_nan_conf conf = {};
11973 int err;
11974
11975 if (wdev->iftype != NL80211_IFTYPE_NAN)
11976 return -EOPNOTSUPP;
11977
eeb04a96 11978 if (wdev_running(wdev))
cb3b7d87
AB
11979 return -EEXIST;
11980
11981 if (rfkill_blocked(rdev->rfkill))
11982 return -ERFKILL;
11983
11984 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
11985 return -EINVAL;
11986
cb3b7d87
AB
11987 conf.master_pref =
11988 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
cb3b7d87 11989
8585989d
LC
11990 if (info->attrs[NL80211_ATTR_BANDS]) {
11991 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
11992
11993 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
11994 return -EOPNOTSUPP;
11995
11996 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
11997 return -EINVAL;
11998
11999 conf.bands = bands;
12000 }
cb3b7d87
AB
12001
12002 err = rdev_start_nan(rdev, wdev, &conf);
12003 if (err)
12004 return err;
12005
73c7da3d 12006 wdev->is_running = true;
cb3b7d87
AB
12007 rdev->opencount++;
12008
12009 return 0;
12010}
12011
12012static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
12013{
12014 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12015 struct wireless_dev *wdev = info->user_ptr[1];
12016
12017 if (wdev->iftype != NL80211_IFTYPE_NAN)
12018 return -EOPNOTSUPP;
12019
12020 cfg80211_stop_nan(rdev, wdev);
12021
12022 return 0;
12023}
12024
a442b761
AB
12025static int validate_nan_filter(struct nlattr *filter_attr)
12026{
12027 struct nlattr *attr;
12028 int len = 0, n_entries = 0, rem;
12029
12030 nla_for_each_nested(attr, filter_attr, rem) {
12031 len += nla_len(attr);
12032 n_entries++;
12033 }
12034
12035 if (len >= U8_MAX)
12036 return -EINVAL;
12037
12038 return n_entries;
12039}
12040
12041static int handle_nan_filter(struct nlattr *attr_filter,
12042 struct cfg80211_nan_func *func,
12043 bool tx)
12044{
12045 struct nlattr *attr;
12046 int n_entries, rem, i;
12047 struct cfg80211_nan_func_filter *filter;
12048
12049 n_entries = validate_nan_filter(attr_filter);
12050 if (n_entries < 0)
12051 return n_entries;
12052
12053 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
12054
12055 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
12056 if (!filter)
12057 return -ENOMEM;
12058
12059 i = 0;
12060 nla_for_each_nested(attr, attr_filter, rem) {
b15ca182 12061 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
a442b761
AB
12062 filter[i].len = nla_len(attr);
12063 i++;
12064 }
12065 if (tx) {
12066 func->num_tx_filters = n_entries;
12067 func->tx_filters = filter;
12068 } else {
12069 func->num_rx_filters = n_entries;
12070 func->rx_filters = filter;
12071 }
12072
12073 return 0;
12074}
12075
12076static int nl80211_nan_add_func(struct sk_buff *skb,
12077 struct genl_info *info)
12078{
12079 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12080 struct wireless_dev *wdev = info->user_ptr[1];
12081 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
12082 struct cfg80211_nan_func *func;
12083 struct sk_buff *msg = NULL;
12084 void *hdr = NULL;
12085 int err = 0;
12086
12087 if (wdev->iftype != NL80211_IFTYPE_NAN)
12088 return -EOPNOTSUPP;
12089
73c7da3d 12090 if (!wdev_running(wdev))
a442b761
AB
12091 return -ENOTCONN;
12092
12093 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
12094 return -EINVAL;
12095
8cb08174
JB
12096 err = nla_parse_nested_deprecated(tb, NL80211_NAN_FUNC_ATTR_MAX,
12097 info->attrs[NL80211_ATTR_NAN_FUNC],
12098 nl80211_nan_func_policy,
12099 info->extack);
a442b761
AB
12100 if (err)
12101 return err;
12102
12103 func = kzalloc(sizeof(*func), GFP_KERNEL);
12104 if (!func)
12105 return -ENOMEM;
12106
b60ad348 12107 func->cookie = cfg80211_assign_cookie(rdev);
a442b761
AB
12108
12109 if (!tb[NL80211_NAN_FUNC_TYPE] ||
12110 nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]) > NL80211_NAN_FUNC_MAX_TYPE) {
12111 err = -EINVAL;
12112 goto out;
12113 }
12114
12115
12116 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
12117
12118 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
12119 err = -EINVAL;
12120 goto out;
12121 }
12122
12123 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
12124 sizeof(func->service_id));
12125
12126 func->close_range =
12127 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
12128
12129 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
12130 func->serv_spec_info_len =
12131 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
12132 func->serv_spec_info =
12133 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
12134 func->serv_spec_info_len,
12135 GFP_KERNEL);
12136 if (!func->serv_spec_info) {
12137 err = -ENOMEM;
12138 goto out;
12139 }
12140 }
12141
12142 if (tb[NL80211_NAN_FUNC_TTL])
12143 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
12144
12145 switch (func->type) {
12146 case NL80211_NAN_FUNC_PUBLISH:
12147 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
12148 err = -EINVAL;
12149 goto out;
12150 }
12151
12152 func->publish_type =
12153 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
12154 func->publish_bcast =
12155 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
12156
12157 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
12158 func->publish_bcast) {
12159 err = -EINVAL;
12160 goto out;
12161 }
12162 break;
12163 case NL80211_NAN_FUNC_SUBSCRIBE:
12164 func->subscribe_active =
12165 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
12166 break;
12167 case NL80211_NAN_FUNC_FOLLOW_UP:
12168 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
3ea15452
HC
12169 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
12170 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
a442b761
AB
12171 err = -EINVAL;
12172 goto out;
12173 }
12174
12175 func->followup_id =
12176 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
12177 func->followup_reqid =
12178 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
12179 memcpy(func->followup_dest.addr,
12180 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
12181 sizeof(func->followup_dest.addr));
12182 if (func->ttl) {
12183 err = -EINVAL;
12184 goto out;
12185 }
12186 break;
12187 default:
12188 err = -EINVAL;
12189 goto out;
12190 }
12191
12192 if (tb[NL80211_NAN_FUNC_SRF]) {
12193 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
12194
8cb08174
JB
12195 err = nla_parse_nested_deprecated(srf_tb,
12196 NL80211_NAN_SRF_ATTR_MAX,
12197 tb[NL80211_NAN_FUNC_SRF],
12198 nl80211_nan_srf_policy,
12199 info->extack);
a442b761
AB
12200 if (err)
12201 goto out;
12202
12203 func->srf_include =
12204 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
12205
12206 if (srf_tb[NL80211_NAN_SRF_BF]) {
12207 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
12208 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
12209 err = -EINVAL;
12210 goto out;
12211 }
12212
12213 func->srf_bf_len =
12214 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
12215 func->srf_bf =
12216 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
12217 func->srf_bf_len, GFP_KERNEL);
12218 if (!func->srf_bf) {
12219 err = -ENOMEM;
12220 goto out;
12221 }
12222
12223 func->srf_bf_idx =
12224 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
12225 } else {
12226 struct nlattr *attr, *mac_attr =
12227 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
12228 int n_entries, rem, i = 0;
12229
12230 if (!mac_attr) {
12231 err = -EINVAL;
12232 goto out;
12233 }
12234
12235 n_entries = validate_acl_mac_addrs(mac_attr);
12236 if (n_entries <= 0) {
12237 err = -EINVAL;
12238 goto out;
12239 }
12240
12241 func->srf_num_macs = n_entries;
12242 func->srf_macs =
6396bb22 12243 kcalloc(n_entries, sizeof(*func->srf_macs),
a442b761
AB
12244 GFP_KERNEL);
12245 if (!func->srf_macs) {
12246 err = -ENOMEM;
12247 goto out;
12248 }
12249
12250 nla_for_each_nested(attr, mac_attr, rem)
12251 memcpy(func->srf_macs[i++].addr, nla_data(attr),
12252 sizeof(*func->srf_macs));
12253 }
12254 }
12255
12256 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
12257 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
12258 func, true);
12259 if (err)
12260 goto out;
12261 }
12262
12263 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
12264 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
12265 func, false);
12266 if (err)
12267 goto out;
12268 }
12269
12270 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12271 if (!msg) {
12272 err = -ENOMEM;
12273 goto out;
12274 }
12275
12276 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12277 NL80211_CMD_ADD_NAN_FUNCTION);
12278 /* This can't really happen - we just allocated 4KB */
12279 if (WARN_ON(!hdr)) {
12280 err = -ENOMEM;
12281 goto out;
12282 }
12283
12284 err = rdev_add_nan_func(rdev, wdev, func);
12285out:
12286 if (err < 0) {
12287 cfg80211_free_nan_func(func);
12288 nlmsg_free(msg);
12289 return err;
12290 }
12291
12292 /* propagate the instance id and cookie to userspace */
12293 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
12294 NL80211_ATTR_PAD))
12295 goto nla_put_failure;
12296
ae0be8de 12297 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
a442b761
AB
12298 if (!func_attr)
12299 goto nla_put_failure;
12300
12301 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
12302 func->instance_id))
12303 goto nla_put_failure;
12304
12305 nla_nest_end(msg, func_attr);
12306
12307 genlmsg_end(msg, hdr);
12308 return genlmsg_reply(msg, info);
12309
12310nla_put_failure:
12311 nlmsg_free(msg);
12312 return -ENOBUFS;
12313}
12314
12315static int nl80211_nan_del_func(struct sk_buff *skb,
12316 struct genl_info *info)
12317{
12318 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12319 struct wireless_dev *wdev = info->user_ptr[1];
12320 u64 cookie;
12321
12322 if (wdev->iftype != NL80211_IFTYPE_NAN)
12323 return -EOPNOTSUPP;
12324
73c7da3d 12325 if (!wdev_running(wdev))
a442b761
AB
12326 return -ENOTCONN;
12327
12328 if (!info->attrs[NL80211_ATTR_COOKIE])
12329 return -EINVAL;
12330
a442b761
AB
12331 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
12332
12333 rdev_del_nan_func(rdev, wdev, cookie);
12334
12335 return 0;
12336}
12337
a5a9dcf2
AB
12338static int nl80211_nan_change_config(struct sk_buff *skb,
12339 struct genl_info *info)
12340{
12341 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12342 struct wireless_dev *wdev = info->user_ptr[1];
12343 struct cfg80211_nan_conf conf = {};
12344 u32 changed = 0;
12345
12346 if (wdev->iftype != NL80211_IFTYPE_NAN)
12347 return -EOPNOTSUPP;
12348
73c7da3d 12349 if (!wdev_running(wdev))
a5a9dcf2
AB
12350 return -ENOTCONN;
12351
12352 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
12353 conf.master_pref =
12354 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
12355 if (conf.master_pref <= 1 || conf.master_pref == 255)
12356 return -EINVAL;
12357
12358 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
12359 }
12360
8585989d
LC
12361 if (info->attrs[NL80211_ATTR_BANDS]) {
12362 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
12363
12364 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
12365 return -EOPNOTSUPP;
12366
12367 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
12368 return -EINVAL;
12369
12370 conf.bands = bands;
12371 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
a5a9dcf2
AB
12372 }
12373
12374 if (!changed)
12375 return -EINVAL;
12376
12377 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
12378}
12379
50bcd31d
AB
12380void cfg80211_nan_match(struct wireless_dev *wdev,
12381 struct cfg80211_nan_match_params *match, gfp_t gfp)
12382{
12383 struct wiphy *wiphy = wdev->wiphy;
12384 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
12385 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
12386 struct sk_buff *msg;
12387 void *hdr;
12388
12389 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
12390 return;
12391
12392 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
12393 if (!msg)
12394 return;
12395
12396 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
12397 if (!hdr) {
12398 nlmsg_free(msg);
12399 return;
12400 }
12401
12402 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12403 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12404 wdev->netdev->ifindex)) ||
12405 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12406 NL80211_ATTR_PAD))
12407 goto nla_put_failure;
12408
12409 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
12410 NL80211_ATTR_PAD) ||
12411 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
12412 goto nla_put_failure;
12413
ae0be8de 12414 match_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_MATCH);
50bcd31d
AB
12415 if (!match_attr)
12416 goto nla_put_failure;
12417
ae0be8de
MK
12418 local_func_attr = nla_nest_start_noflag(msg,
12419 NL80211_NAN_MATCH_FUNC_LOCAL);
50bcd31d
AB
12420 if (!local_func_attr)
12421 goto nla_put_failure;
12422
12423 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
12424 goto nla_put_failure;
12425
12426 nla_nest_end(msg, local_func_attr);
12427
ae0be8de
MK
12428 peer_func_attr = nla_nest_start_noflag(msg,
12429 NL80211_NAN_MATCH_FUNC_PEER);
50bcd31d
AB
12430 if (!peer_func_attr)
12431 goto nla_put_failure;
12432
12433 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
12434 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
12435 goto nla_put_failure;
12436
12437 if (match->info && match->info_len &&
12438 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
12439 match->info))
12440 goto nla_put_failure;
12441
12442 nla_nest_end(msg, peer_func_attr);
12443 nla_nest_end(msg, match_attr);
12444 genlmsg_end(msg, hdr);
12445
12446 if (!wdev->owner_nlportid)
12447 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
12448 msg, 0, NL80211_MCGRP_NAN, gfp);
12449 else
12450 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
12451 wdev->owner_nlportid);
12452
12453 return;
12454
12455nla_put_failure:
12456 nlmsg_free(msg);
12457}
12458EXPORT_SYMBOL(cfg80211_nan_match);
12459
368e5a7b
AB
12460void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
12461 u8 inst_id,
12462 enum nl80211_nan_func_term_reason reason,
12463 u64 cookie, gfp_t gfp)
12464{
12465 struct wiphy *wiphy = wdev->wiphy;
12466 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
12467 struct sk_buff *msg;
12468 struct nlattr *func_attr;
12469 void *hdr;
12470
12471 if (WARN_ON(!inst_id))
12472 return;
12473
12474 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
12475 if (!msg)
12476 return;
12477
12478 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
12479 if (!hdr) {
12480 nlmsg_free(msg);
12481 return;
12482 }
12483
12484 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
12485 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
12486 wdev->netdev->ifindex)) ||
12487 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
12488 NL80211_ATTR_PAD))
12489 goto nla_put_failure;
12490
12491 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12492 NL80211_ATTR_PAD))
12493 goto nla_put_failure;
12494
ae0be8de 12495 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
368e5a7b
AB
12496 if (!func_attr)
12497 goto nla_put_failure;
12498
12499 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
12500 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
12501 goto nla_put_failure;
12502
12503 nla_nest_end(msg, func_attr);
12504 genlmsg_end(msg, hdr);
12505
12506 if (!wdev->owner_nlportid)
12507 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
12508 msg, 0, NL80211_MCGRP_NAN, gfp);
12509 else
12510 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
12511 wdev->owner_nlportid);
12512
12513 return;
12514
12515nla_put_failure:
12516 nlmsg_free(msg);
12517}
12518EXPORT_SYMBOL(cfg80211_nan_func_terminated);
12519
3713b4e3
JB
12520static int nl80211_get_protocol_features(struct sk_buff *skb,
12521 struct genl_info *info)
12522{
12523 void *hdr;
12524 struct sk_buff *msg;
12525
12526 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12527 if (!msg)
12528 return -ENOMEM;
12529
12530 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12531 NL80211_CMD_GET_PROTOCOL_FEATURES);
12532 if (!hdr)
12533 goto nla_put_failure;
12534
12535 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
12536 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
12537 goto nla_put_failure;
12538
12539 genlmsg_end(msg, hdr);
12540 return genlmsg_reply(msg, info);
12541
12542 nla_put_failure:
12543 kfree_skb(msg);
12544 return -ENOBUFS;
12545}
12546
355199e0
JM
12547static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
12548{
12549 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12550 struct cfg80211_update_ft_ies_params ft_params;
12551 struct net_device *dev = info->user_ptr[1];
12552
12553 if (!rdev->ops->update_ft_ies)
12554 return -EOPNOTSUPP;
12555
12556 if (!info->attrs[NL80211_ATTR_MDID] ||
3d7af878 12557 !info->attrs[NL80211_ATTR_IE])
355199e0
JM
12558 return -EINVAL;
12559
12560 memset(&ft_params, 0, sizeof(ft_params));
12561 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
12562 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
12563 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
12564
12565 return rdev_update_ft_ies(rdev, dev, &ft_params);
12566}
12567
5de17984
AS
12568static int nl80211_crit_protocol_start(struct sk_buff *skb,
12569 struct genl_info *info)
12570{
12571 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12572 struct wireless_dev *wdev = info->user_ptr[1];
12573 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
12574 u16 duration;
12575 int ret;
12576
12577 if (!rdev->ops->crit_proto_start)
12578 return -EOPNOTSUPP;
12579
12580 if (WARN_ON(!rdev->ops->crit_proto_stop))
12581 return -EINVAL;
12582
12583 if (rdev->crit_proto_nlportid)
12584 return -EBUSY;
12585
12586 /* determine protocol if provided */
12587 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
12588 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
12589
12590 if (proto >= NUM_NL80211_CRIT_PROTO)
12591 return -EINVAL;
12592
12593 /* timeout must be provided */
12594 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
12595 return -EINVAL;
12596
12597 duration =
12598 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
12599
12600 if (duration > NL80211_CRIT_PROTO_MAX_DURATION)
12601 return -ERANGE;
12602
12603 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
12604 if (!ret)
12605 rdev->crit_proto_nlportid = info->snd_portid;
12606
12607 return ret;
12608}
12609
12610static int nl80211_crit_protocol_stop(struct sk_buff *skb,
12611 struct genl_info *info)
12612{
12613 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12614 struct wireless_dev *wdev = info->user_ptr[1];
12615
12616 if (!rdev->ops->crit_proto_stop)
12617 return -EOPNOTSUPP;
12618
12619 if (rdev->crit_proto_nlportid) {
12620 rdev->crit_proto_nlportid = 0;
12621 rdev_crit_proto_stop(rdev, wdev);
12622 }
12623 return 0;
12624}
12625
ad7e718c
JB
12626static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
12627{
12628 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12629 struct wireless_dev *wdev =
12630 __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
12631 int i, err;
12632 u32 vid, subcmd;
12633
12634 if (!rdev->wiphy.vendor_commands)
12635 return -EOPNOTSUPP;
12636
12637 if (IS_ERR(wdev)) {
12638 err = PTR_ERR(wdev);
12639 if (err != -EINVAL)
12640 return err;
12641 wdev = NULL;
12642 } else if (wdev->wiphy != &rdev->wiphy) {
12643 return -EINVAL;
12644 }
12645
12646 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
12647 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
12648 return -EINVAL;
12649
12650 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
12651 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
12652 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
12653 const struct wiphy_vendor_command *vcmd;
12654 void *data = NULL;
12655 int len = 0;
12656
12657 vcmd = &rdev->wiphy.vendor_commands[i];
12658
12659 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
12660 continue;
12661
12662 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
12663 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
12664 if (!wdev)
12665 return -EINVAL;
12666 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
12667 !wdev->netdev)
12668 return -EINVAL;
12669
12670 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
73c7da3d 12671 if (!wdev_running(wdev))
ad7e718c
JB
12672 return -ENETDOWN;
12673 }
7bdbe400
JB
12674
12675 if (!vcmd->doit)
12676 return -EOPNOTSUPP;
ad7e718c
JB
12677 } else {
12678 wdev = NULL;
12679 }
12680
12681 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
12682 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
12683 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
12684 }
12685
12686 rdev->cur_cmd_info = info;
12687 err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
12688 data, len);
12689 rdev->cur_cmd_info = NULL;
12690 return err;
12691 }
12692
12693 return -EOPNOTSUPP;
12694}
12695
7bdbe400
JB
12696static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
12697 struct netlink_callback *cb,
12698 struct cfg80211_registered_device **rdev,
12699 struct wireless_dev **wdev)
12700{
c90c39da 12701 struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
7bdbe400
JB
12702 u32 vid, subcmd;
12703 unsigned int i;
12704 int vcmd_idx = -1;
12705 int err;
12706 void *data = NULL;
12707 unsigned int data_len = 0;
12708
7bdbe400
JB
12709 if (cb->args[0]) {
12710 /* subtract the 1 again here */
12711 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
12712 struct wireless_dev *tmp;
12713
ea90e0dc
JB
12714 if (!wiphy)
12715 return -ENODEV;
7bdbe400
JB
12716 *rdev = wiphy_to_rdev(wiphy);
12717 *wdev = NULL;
12718
12719 if (cb->args[1]) {
53873f13 12720 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
7bdbe400
JB
12721 if (tmp->identifier == cb->args[1] - 1) {
12722 *wdev = tmp;
12723 break;
12724 }
12725 }
12726 }
12727
12728 /* keep rtnl locked in successful case */
12729 return 0;
12730 }
12731
8cb08174
JB
12732 err = nlmsg_parse_deprecated(cb->nlh,
12733 GENL_HDRLEN + nl80211_fam.hdrsize,
12734 attrbuf, nl80211_fam.maxattr,
12735 nl80211_policy, NULL);
7bdbe400 12736 if (err)
ea90e0dc 12737 return err;
7bdbe400 12738
c90c39da 12739 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
ea90e0dc
JB
12740 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD])
12741 return -EINVAL;
7bdbe400 12742
c90c39da 12743 *wdev = __cfg80211_wdev_from_attrs(sock_net(skb->sk), attrbuf);
7bdbe400
JB
12744 if (IS_ERR(*wdev))
12745 *wdev = NULL;
12746
c90c39da 12747 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
ea90e0dc
JB
12748 if (IS_ERR(*rdev))
12749 return PTR_ERR(*rdev);
7bdbe400 12750
c90c39da
JB
12751 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
12752 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
7bdbe400
JB
12753
12754 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
12755 const struct wiphy_vendor_command *vcmd;
12756
12757 vcmd = &(*rdev)->wiphy.vendor_commands[i];
12758
12759 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
12760 continue;
12761
ea90e0dc
JB
12762 if (!vcmd->dumpit)
12763 return -EOPNOTSUPP;
7bdbe400
JB
12764
12765 vcmd_idx = i;
12766 break;
12767 }
12768
ea90e0dc
JB
12769 if (vcmd_idx < 0)
12770 return -EOPNOTSUPP;
7bdbe400 12771
c90c39da
JB
12772 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
12773 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
12774 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
7bdbe400
JB
12775 }
12776
12777 /* 0 is the first index - add 1 to parse only once */
12778 cb->args[0] = (*rdev)->wiphy_idx + 1;
12779 /* add 1 to know if it was NULL */
12780 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
12781 cb->args[2] = vcmd_idx;
12782 cb->args[3] = (unsigned long)data;
12783 cb->args[4] = data_len;
12784
12785 /* keep rtnl locked in successful case */
12786 return 0;
7bdbe400
JB
12787}
12788
12789static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
12790 struct netlink_callback *cb)
12791{
12792 struct cfg80211_registered_device *rdev;
12793 struct wireless_dev *wdev;
12794 unsigned int vcmd_idx;
12795 const struct wiphy_vendor_command *vcmd;
12796 void *data;
12797 int data_len;
12798 int err;
12799 struct nlattr *vendor_data;
12800
ea90e0dc 12801 rtnl_lock();
7bdbe400
JB
12802 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
12803 if (err)
ea90e0dc 12804 goto out;
7bdbe400
JB
12805
12806 vcmd_idx = cb->args[2];
12807 data = (void *)cb->args[3];
12808 data_len = cb->args[4];
12809 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
12810
12811 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
12812 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
ea90e0dc
JB
12813 if (!wdev) {
12814 err = -EINVAL;
12815 goto out;
12816 }
7bdbe400 12817 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
ea90e0dc
JB
12818 !wdev->netdev) {
12819 err = -EINVAL;
12820 goto out;
12821 }
7bdbe400
JB
12822
12823 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
ea90e0dc
JB
12824 if (!wdev_running(wdev)) {
12825 err = -ENETDOWN;
12826 goto out;
12827 }
7bdbe400
JB
12828 }
12829 }
12830
12831 while (1) {
12832 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
12833 cb->nlh->nlmsg_seq, NLM_F_MULTI,
12834 NL80211_CMD_VENDOR);
12835 if (!hdr)
12836 break;
12837
12838 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
12839 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
12840 wdev_id(wdev),
12841 NL80211_ATTR_PAD))) {
7bdbe400
JB
12842 genlmsg_cancel(skb, hdr);
12843 break;
12844 }
12845
ae0be8de
MK
12846 vendor_data = nla_nest_start_noflag(skb,
12847 NL80211_ATTR_VENDOR_DATA);
7bdbe400
JB
12848 if (!vendor_data) {
12849 genlmsg_cancel(skb, hdr);
12850 break;
12851 }
12852
12853 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
12854 (unsigned long *)&cb->args[5]);
12855 nla_nest_end(skb, vendor_data);
12856
12857 if (err == -ENOBUFS || err == -ENOENT) {
12858 genlmsg_cancel(skb, hdr);
12859 break;
12860 } else if (err) {
12861 genlmsg_cancel(skb, hdr);
12862 goto out;
12863 }
12864
12865 genlmsg_end(skb, hdr);
12866 }
12867
12868 err = skb->len;
12869 out:
12870 rtnl_unlock();
12871 return err;
12872}
12873
ad7e718c
JB
12874struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
12875 enum nl80211_commands cmd,
12876 enum nl80211_attrs attr,
12877 int approxlen)
12878{
f26cbf40 12879 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ad7e718c
JB
12880
12881 if (WARN_ON(!rdev->cur_cmd_info))
12882 return NULL;
12883
6c09e791 12884 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
ad7e718c
JB
12885 rdev->cur_cmd_info->snd_portid,
12886 rdev->cur_cmd_info->snd_seq,
567ffc35 12887 cmd, attr, NULL, GFP_KERNEL);
ad7e718c
JB
12888}
12889EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
12890
12891int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
12892{
12893 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
12894 void *hdr = ((void **)skb->cb)[1];
12895 struct nlattr *data = ((void **)skb->cb)[2];
12896
bd8c78e7
JB
12897 /* clear CB data for netlink core to own from now on */
12898 memset(skb->cb, 0, sizeof(skb->cb));
12899
ad7e718c
JB
12900 if (WARN_ON(!rdev->cur_cmd_info)) {
12901 kfree_skb(skb);
12902 return -EINVAL;
12903 }
12904
12905 nla_nest_end(skb, data);
12906 genlmsg_end(skb, hdr);
12907 return genlmsg_reply(skb, rdev->cur_cmd_info);
12908}
12909EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
12910
55c1fdf0
JB
12911unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy)
12912{
12913 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
12914
12915 if (WARN_ON(!rdev->cur_cmd_info))
12916 return 0;
12917
12918 return rdev->cur_cmd_info->snd_portid;
12919}
12920EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender);
12921
fa9ffc74
KP
12922static int nl80211_set_qos_map(struct sk_buff *skb,
12923 struct genl_info *info)
12924{
12925 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12926 struct cfg80211_qos_map *qos_map = NULL;
12927 struct net_device *dev = info->user_ptr[1];
12928 u8 *pos, len, num_des, des_len, des;
12929 int ret;
12930
12931 if (!rdev->ops->set_qos_map)
12932 return -EOPNOTSUPP;
12933
12934 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
12935 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
12936 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
12937
12938 if (len % 2 || len < IEEE80211_QOS_MAP_LEN_MIN ||
12939 len > IEEE80211_QOS_MAP_LEN_MAX)
12940 return -EINVAL;
12941
12942 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
12943 if (!qos_map)
12944 return -ENOMEM;
12945
12946 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
12947 if (num_des) {
12948 des_len = num_des *
12949 sizeof(struct cfg80211_dscp_exception);
12950 memcpy(qos_map->dscp_exception, pos, des_len);
12951 qos_map->num_des = num_des;
12952 for (des = 0; des < num_des; des++) {
12953 if (qos_map->dscp_exception[des].up > 7) {
12954 kfree(qos_map);
12955 return -EINVAL;
12956 }
12957 }
12958 pos += des_len;
12959 }
12960 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
12961 }
12962
12963 wdev_lock(dev->ieee80211_ptr);
12964 ret = nl80211_key_allowed(dev->ieee80211_ptr);
12965 if (!ret)
12966 ret = rdev_set_qos_map(rdev, dev, qos_map);
12967 wdev_unlock(dev->ieee80211_ptr);
12968
12969 kfree(qos_map);
12970 return ret;
12971}
12972
960d01ac
JB
12973static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
12974{
12975 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12976 struct net_device *dev = info->user_ptr[1];
12977 struct wireless_dev *wdev = dev->ieee80211_ptr;
12978 const u8 *peer;
12979 u8 tsid, up;
12980 u16 admitted_time = 0;
12981 int err;
12982
723e73ac 12983 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
960d01ac
JB
12984 return -EOPNOTSUPP;
12985
12986 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
12987 !info->attrs[NL80211_ATTR_USER_PRIO])
12988 return -EINVAL;
12989
12990 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
960d01ac 12991 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
960d01ac
JB
12992
12993 /* WMM uses TIDs 0-7 even for TSPEC */
723e73ac 12994 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
960d01ac 12995 /* TODO: handle 802.11 TSPEC/admission control
723e73ac
JB
12996 * need more attributes for that (e.g. BA session requirement);
12997 * change the WMM adminssion test above to allow both then
960d01ac
JB
12998 */
12999 return -EINVAL;
13000 }
13001
13002 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
13003
13004 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
13005 admitted_time =
13006 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
13007 if (!admitted_time)
13008 return -EINVAL;
13009 }
13010
13011 wdev_lock(wdev);
13012 switch (wdev->iftype) {
13013 case NL80211_IFTYPE_STATION:
13014 case NL80211_IFTYPE_P2P_CLIENT:
13015 if (wdev->current_bss)
13016 break;
13017 err = -ENOTCONN;
13018 goto out;
13019 default:
13020 err = -EOPNOTSUPP;
13021 goto out;
13022 }
13023
13024 err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
13025
13026 out:
13027 wdev_unlock(wdev);
13028 return err;
13029}
13030
13031static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
13032{
13033 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13034 struct net_device *dev = info->user_ptr[1];
13035 struct wireless_dev *wdev = dev->ieee80211_ptr;
13036 const u8 *peer;
13037 u8 tsid;
13038 int err;
13039
13040 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
13041 return -EINVAL;
13042
13043 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
13044 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
13045
13046 wdev_lock(wdev);
13047 err = rdev_del_tx_ts(rdev, dev, tsid, peer);
13048 wdev_unlock(wdev);
13049
13050 return err;
13051}
13052
1057d35e
AN
13053static int nl80211_tdls_channel_switch(struct sk_buff *skb,
13054 struct genl_info *info)
13055{
13056 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13057 struct net_device *dev = info->user_ptr[1];
13058 struct wireless_dev *wdev = dev->ieee80211_ptr;
13059 struct cfg80211_chan_def chandef = {};
13060 const u8 *addr;
13061 u8 oper_class;
13062 int err;
13063
13064 if (!rdev->ops->tdls_channel_switch ||
13065 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
13066 return -EOPNOTSUPP;
13067
13068 switch (dev->ieee80211_ptr->iftype) {
13069 case NL80211_IFTYPE_STATION:
13070 case NL80211_IFTYPE_P2P_CLIENT:
13071 break;
13072 default:
13073 return -EOPNOTSUPP;
13074 }
13075
13076 if (!info->attrs[NL80211_ATTR_MAC] ||
13077 !info->attrs[NL80211_ATTR_OPER_CLASS])
13078 return -EINVAL;
13079
13080 err = nl80211_parse_chandef(rdev, info, &chandef);
13081 if (err)
13082 return err;
13083
13084 /*
13085 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
13086 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
13087 * specification is not defined for them.
13088 */
57fbcce3 13089 if (chandef.chan->band == NL80211_BAND_2GHZ &&
1057d35e
AN
13090 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
13091 chandef.width != NL80211_CHAN_WIDTH_20)
13092 return -EINVAL;
13093
13094 /* we will be active on the TDLS link */
923b352f
AN
13095 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
13096 wdev->iftype))
1057d35e
AN
13097 return -EINVAL;
13098
13099 /* don't allow switching to DFS channels */
13100 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
13101 return -EINVAL;
13102
13103 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
13104 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
13105
13106 wdev_lock(wdev);
13107 err = rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
13108 wdev_unlock(wdev);
13109
13110 return err;
13111}
13112
13113static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
13114 struct genl_info *info)
13115{
13116 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13117 struct net_device *dev = info->user_ptr[1];
13118 struct wireless_dev *wdev = dev->ieee80211_ptr;
13119 const u8 *addr;
13120
13121 if (!rdev->ops->tdls_channel_switch ||
13122 !rdev->ops->tdls_cancel_channel_switch ||
13123 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
13124 return -EOPNOTSUPP;
13125
13126 switch (dev->ieee80211_ptr->iftype) {
13127 case NL80211_IFTYPE_STATION:
13128 case NL80211_IFTYPE_P2P_CLIENT:
13129 break;
13130 default:
13131 return -EOPNOTSUPP;
13132 }
13133
13134 if (!info->attrs[NL80211_ATTR_MAC])
13135 return -EINVAL;
13136
13137 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
13138
13139 wdev_lock(wdev);
13140 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
13141 wdev_unlock(wdev);
13142
13143 return 0;
13144}
13145
ce0ce13a
MB
13146static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
13147 struct genl_info *info)
13148{
13149 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13150 struct net_device *dev = info->user_ptr[1];
13151 struct wireless_dev *wdev = dev->ieee80211_ptr;
13152 const struct nlattr *nla;
13153 bool enabled;
13154
ce0ce13a
MB
13155 if (!rdev->ops->set_multicast_to_unicast)
13156 return -EOPNOTSUPP;
13157
13158 if (wdev->iftype != NL80211_IFTYPE_AP &&
13159 wdev->iftype != NL80211_IFTYPE_P2P_GO)
13160 return -EOPNOTSUPP;
13161
13162 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
13163 enabled = nla_get_flag(nla);
13164
13165 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
13166}
13167
3a00df57
AS
13168static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
13169{
13170 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13171 struct net_device *dev = info->user_ptr[1];
13172 struct wireless_dev *wdev = dev->ieee80211_ptr;
13173 struct cfg80211_pmk_conf pmk_conf = {};
13174 int ret;
13175
13176 if (wdev->iftype != NL80211_IFTYPE_STATION &&
13177 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
13178 return -EOPNOTSUPP;
13179
13180 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13181 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
13182 return -EOPNOTSUPP;
13183
13184 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
13185 return -EINVAL;
13186
13187 wdev_lock(wdev);
13188 if (!wdev->current_bss) {
13189 ret = -ENOTCONN;
13190 goto out;
13191 }
13192
13193 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
13194 if (memcmp(pmk_conf.aa, wdev->current_bss->pub.bssid, ETH_ALEN)) {
13195 ret = -EINVAL;
13196 goto out;
13197 }
13198
13199 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
13200 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
13201 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
13202 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192) {
13203 ret = -EINVAL;
13204 goto out;
13205 }
13206
13207 if (info->attrs[NL80211_ATTR_PMKR0_NAME]) {
13208 int r0_name_len = nla_len(info->attrs[NL80211_ATTR_PMKR0_NAME]);
13209
13210 if (r0_name_len != WLAN_PMK_NAME_LEN) {
13211 ret = -EINVAL;
13212 goto out;
13213 }
13214
13215 pmk_conf.pmk_r0_name =
13216 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
13217 }
13218
13219 ret = rdev_set_pmk(rdev, dev, &pmk_conf);
13220out:
13221 wdev_unlock(wdev);
13222 return ret;
13223}
13224
13225static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
13226{
13227 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13228 struct net_device *dev = info->user_ptr[1];
13229 struct wireless_dev *wdev = dev->ieee80211_ptr;
13230 const u8 *aa;
13231 int ret;
13232
13233 if (wdev->iftype != NL80211_IFTYPE_STATION &&
13234 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
13235 return -EOPNOTSUPP;
13236
13237 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13238 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
13239 return -EOPNOTSUPP;
13240
13241 if (!info->attrs[NL80211_ATTR_MAC])
13242 return -EINVAL;
13243
13244 wdev_lock(wdev);
13245 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
13246 ret = rdev_del_pmk(rdev, dev, aa);
13247 wdev_unlock(wdev);
13248
13249 return ret;
13250}
13251
40cbfa90
SD
13252static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
13253{
13254 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13255 struct net_device *dev = info->user_ptr[1];
13256 struct cfg80211_external_auth_params params;
13257
db8d93a7 13258 if (!rdev->ops->external_auth)
40cbfa90
SD
13259 return -EOPNOTSUPP;
13260
fe494370
SD
13261 if (!info->attrs[NL80211_ATTR_SSID] &&
13262 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
13263 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
40cbfa90
SD
13264 return -EINVAL;
13265
13266 if (!info->attrs[NL80211_ATTR_BSSID])
13267 return -EINVAL;
13268
13269 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
13270 return -EINVAL;
13271
13272 memset(&params, 0, sizeof(params));
13273
fe494370
SD
13274 if (info->attrs[NL80211_ATTR_SSID]) {
13275 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
13276 if (params.ssid.ssid_len == 0 ||
13277 params.ssid.ssid_len > IEEE80211_MAX_SSID_LEN)
13278 return -EINVAL;
13279 memcpy(params.ssid.ssid,
13280 nla_data(info->attrs[NL80211_ATTR_SSID]),
13281 params.ssid.ssid_len);
13282 }
40cbfa90
SD
13283
13284 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
13285 ETH_ALEN);
13286
13287 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
13288
fe494370
SD
13289 if (info->attrs[NL80211_ATTR_PMKID])
13290 params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
13291
40cbfa90
SD
13292 return rdev_external_auth(rdev, dev, &params);
13293}
13294
2576a9ac
DK
13295static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
13296{
13297 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13298 struct net_device *dev = info->user_ptr[1];
13299 struct wireless_dev *wdev = dev->ieee80211_ptr;
13300 const u8 *buf;
13301 size_t len;
13302 u8 *dest;
13303 u16 proto;
13304 bool noencrypt;
13305 int err;
13306
13307 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13308 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
13309 return -EOPNOTSUPP;
13310
13311 if (!rdev->ops->tx_control_port)
13312 return -EOPNOTSUPP;
13313
13314 if (!info->attrs[NL80211_ATTR_FRAME] ||
13315 !info->attrs[NL80211_ATTR_MAC] ||
13316 !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
13317 GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
13318 return -EINVAL;
13319 }
13320
13321 wdev_lock(wdev);
13322
13323 switch (wdev->iftype) {
13324 case NL80211_IFTYPE_AP:
13325 case NL80211_IFTYPE_P2P_GO:
13326 case NL80211_IFTYPE_MESH_POINT:
13327 break;
13328 case NL80211_IFTYPE_ADHOC:
13329 case NL80211_IFTYPE_STATION:
13330 case NL80211_IFTYPE_P2P_CLIENT:
13331 if (wdev->current_bss)
13332 break;
13333 err = -ENOTCONN;
13334 goto out;
13335 default:
13336 err = -EOPNOTSUPP;
13337 goto out;
13338 }
13339
13340 wdev_unlock(wdev);
13341
13342 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
13343 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
13344 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
13345 proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
13346 noencrypt =
13347 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
13348
13349 return rdev_tx_control_port(rdev, dev, buf, len,
13350 dest, cpu_to_be16(proto), noencrypt);
13351
13352 out:
13353 wdev_unlock(wdev);
13354 return err;
13355}
13356
81e54d08
PKC
13357static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
13358 struct genl_info *info)
13359{
13360 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13361 struct net_device *dev = info->user_ptr[1];
13362 struct wireless_dev *wdev = dev->ieee80211_ptr;
13363 struct cfg80211_ftm_responder_stats ftm_stats = {};
13364 struct sk_buff *msg;
13365 void *hdr;
13366 struct nlattr *ftm_stats_attr;
13367 int err;
13368
13369 if (wdev->iftype != NL80211_IFTYPE_AP || !wdev->beacon_interval)
13370 return -EOPNOTSUPP;
13371
13372 err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
13373 if (err)
13374 return err;
13375
13376 if (!ftm_stats.filled)
13377 return -ENODATA;
13378
13379 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13380 if (!msg)
13381 return -ENOMEM;
13382
13383 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13384 NL80211_CMD_GET_FTM_RESPONDER_STATS);
13385 if (!hdr)
13386 return -ENOBUFS;
13387
13388 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
13389 goto nla_put_failure;
13390
ae0be8de
MK
13391 ftm_stats_attr = nla_nest_start_noflag(msg,
13392 NL80211_ATTR_FTM_RESPONDER_STATS);
81e54d08
PKC
13393 if (!ftm_stats_attr)
13394 goto nla_put_failure;
13395
13396#define SET_FTM(field, name, type) \
13397 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
13398 nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name, \
13399 ftm_stats.field)) \
13400 goto nla_put_failure; } while (0)
13401#define SET_FTM_U64(field, name) \
13402 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
13403 nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name, \
13404 ftm_stats.field, NL80211_FTM_STATS_PAD)) \
13405 goto nla_put_failure; } while (0)
13406
13407 SET_FTM(success_num, SUCCESS_NUM, u32);
13408 SET_FTM(partial_num, PARTIAL_NUM, u32);
13409 SET_FTM(failed_num, FAILED_NUM, u32);
13410 SET_FTM(asap_num, ASAP_NUM, u32);
13411 SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
13412 SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
13413 SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
13414 SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
13415 SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
13416#undef SET_FTM
13417
13418 nla_nest_end(msg, ftm_stats_attr);
13419
13420 genlmsg_end(msg, hdr);
13421 return genlmsg_reply(msg, info);
13422
13423nla_put_failure:
13424 nlmsg_free(msg);
13425 return -ENOBUFS;
13426}
13427
cb74e977
SD
13428static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
13429{
13430 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13431 struct cfg80211_update_owe_info owe_info;
13432 struct net_device *dev = info->user_ptr[1];
13433
13434 if (!rdev->ops->update_owe_info)
13435 return -EOPNOTSUPP;
13436
13437 if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
13438 !info->attrs[NL80211_ATTR_MAC])
13439 return -EINVAL;
13440
13441 memset(&owe_info, 0, sizeof(owe_info));
13442 owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
13443 nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
13444
13445 if (info->attrs[NL80211_ATTR_IE]) {
13446 owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
13447 owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
13448 }
13449
13450 return rdev_update_owe_info(rdev, dev, &owe_info);
13451}
13452
5ab92e7f
RM
13453static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
13454{
13455 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13456 struct net_device *dev = info->user_ptr[1];
13457 struct wireless_dev *wdev = dev->ieee80211_ptr;
13458 struct station_info sinfo = {};
13459 const u8 *buf;
13460 size_t len;
13461 u8 *dest;
13462 int err;
13463
13464 if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
13465 return -EOPNOTSUPP;
13466
13467 if (!info->attrs[NL80211_ATTR_MAC] ||
13468 !info->attrs[NL80211_ATTR_FRAME]) {
13469 GENL_SET_ERR_MSG(info, "Frame or MAC missing");
13470 return -EINVAL;
13471 }
13472
13473 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
13474 return -EOPNOTSUPP;
13475
13476 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
13477 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
13478 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
13479
13480 if (len < sizeof(struct ethhdr))
13481 return -EINVAL;
13482
13483 if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
13484 !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
13485 return -EINVAL;
13486
13487 err = rdev_get_station(rdev, dev, dest, &sinfo);
13488 if (err)
13489 return err;
13490
13491 return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
13492}
13493
4c476991
JB
13494#define NL80211_FLAG_NEED_WIPHY 0x01
13495#define NL80211_FLAG_NEED_NETDEV 0x02
13496#define NL80211_FLAG_NEED_RTNL 0x04
41265714
JB
13497#define NL80211_FLAG_CHECK_NETDEV_UP 0x08
13498#define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
13499 NL80211_FLAG_CHECK_NETDEV_UP)
1bf614ef 13500#define NL80211_FLAG_NEED_WDEV 0x10
98104fde 13501/* If a netdev is associated, it must be UP, P2P must be started */
1bf614ef
JB
13502#define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
13503 NL80211_FLAG_CHECK_NETDEV_UP)
5393b917 13504#define NL80211_FLAG_CLEAR_SKB 0x20
4c476991 13505
f84f771d 13506static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
13507 struct genl_info *info)
13508{
13509 struct cfg80211_registered_device *rdev;
89a54e48 13510 struct wireless_dev *wdev;
4c476991 13511 struct net_device *dev;
4c476991
JB
13512 bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL;
13513
13514 if (rtnl)
13515 rtnl_lock();
13516
13517 if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) {
4f7eff10 13518 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
4c476991
JB
13519 if (IS_ERR(rdev)) {
13520 if (rtnl)
13521 rtnl_unlock();
13522 return PTR_ERR(rdev);
13523 }
13524 info->user_ptr[0] = rdev;
1bf614ef
JB
13525 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
13526 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
5fe231e8
JB
13527 ASSERT_RTNL();
13528
89a54e48
JB
13529 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
13530 info->attrs);
13531 if (IS_ERR(wdev)) {
4c476991
JB
13532 if (rtnl)
13533 rtnl_unlock();
89a54e48 13534 return PTR_ERR(wdev);
4c476991 13535 }
89a54e48 13536
89a54e48 13537 dev = wdev->netdev;
f26cbf40 13538 rdev = wiphy_to_rdev(wdev->wiphy);
89a54e48 13539
1bf614ef
JB
13540 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
13541 if (!dev) {
1bf614ef
JB
13542 if (rtnl)
13543 rtnl_unlock();
13544 return -EINVAL;
13545 }
13546
13547 info->user_ptr[1] = dev;
13548 } else {
13549 info->user_ptr[1] = wdev;
41265714 13550 }
1bf614ef 13551
73c7da3d
AVS
13552 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
13553 !wdev_running(wdev)) {
13554 if (rtnl)
13555 rtnl_unlock();
13556 return -ENETDOWN;
13557 }
1bf614ef 13558
73c7da3d 13559 if (dev)
1bf614ef 13560 dev_hold(dev);
89a54e48 13561
4c476991 13562 info->user_ptr[0] = rdev;
4c476991
JB
13563 }
13564
13565 return 0;
13566}
13567
f84f771d 13568static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
4c476991
JB
13569 struct genl_info *info)
13570{
1bf614ef
JB
13571 if (info->user_ptr[1]) {
13572 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
13573 struct wireless_dev *wdev = info->user_ptr[1];
13574
13575 if (wdev->netdev)
13576 dev_put(wdev->netdev);
13577 } else {
13578 dev_put(info->user_ptr[1]);
13579 }
13580 }
5393b917 13581
4c476991
JB
13582 if (ops->internal_flags & NL80211_FLAG_NEED_RTNL)
13583 rtnl_unlock();
5393b917
JB
13584
13585 /* If needed, clear the netlink message payload from the SKB
13586 * as it might contain key data that shouldn't stick around on
13587 * the heap after the SKB is freed. The netlink message header
13588 * is still needed for further processing, so leave it intact.
13589 */
13590 if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) {
13591 struct nlmsghdr *nlh = nlmsg_hdr(skb);
13592
13593 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
13594 }
4c476991
JB
13595}
13596
4534de83 13597static const struct genl_ops nl80211_ops[] = {
55682965
JB
13598 {
13599 .cmd = NL80211_CMD_GET_WIPHY,
ef6243ac 13600 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
13601 .doit = nl80211_get_wiphy,
13602 .dumpit = nl80211_dump_wiphy,
86e8cf98 13603 .done = nl80211_dump_wiphy_done,
55682965 13604 /* can be retrieved by unprivileged users */
5fe231e8
JB
13605 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13606 NL80211_FLAG_NEED_RTNL,
55682965
JB
13607 },
13608 {
13609 .cmd = NL80211_CMD_SET_WIPHY,
ef6243ac 13610 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 13611 .doit = nl80211_set_wiphy,
5617c6cd 13612 .flags = GENL_UNS_ADMIN_PERM,
4c476991 13613 .internal_flags = NL80211_FLAG_NEED_RTNL,
55682965
JB
13614 },
13615 {
13616 .cmd = NL80211_CMD_GET_INTERFACE,
ef6243ac 13617 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965
JB
13618 .doit = nl80211_get_interface,
13619 .dumpit = nl80211_dump_interface,
55682965 13620 /* can be retrieved by unprivileged users */
5fe231e8
JB
13621 .internal_flags = NL80211_FLAG_NEED_WDEV |
13622 NL80211_FLAG_NEED_RTNL,
55682965
JB
13623 },
13624 {
13625 .cmd = NL80211_CMD_SET_INTERFACE,
ef6243ac 13626 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 13627 .doit = nl80211_set_interface,
5617c6cd 13628 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13629 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13630 NL80211_FLAG_NEED_RTNL,
55682965
JB
13631 },
13632 {
13633 .cmd = NL80211_CMD_NEW_INTERFACE,
ef6243ac 13634 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 13635 .doit = nl80211_new_interface,
5617c6cd 13636 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13637 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13638 NL80211_FLAG_NEED_RTNL,
55682965
JB
13639 },
13640 {
13641 .cmd = NL80211_CMD_DEL_INTERFACE,
ef6243ac 13642 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
55682965 13643 .doit = nl80211_del_interface,
5617c6cd 13644 .flags = GENL_UNS_ADMIN_PERM,
84efbb84 13645 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 13646 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
13647 },
13648 {
13649 .cmd = NL80211_CMD_GET_KEY,
ef6243ac 13650 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 13651 .doit = nl80211_get_key,
5617c6cd 13652 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13653 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13654 NL80211_FLAG_NEED_RTNL,
41ade00f
JB
13655 },
13656 {
13657 .cmd = NL80211_CMD_SET_KEY,
ef6243ac 13658 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 13659 .doit = nl80211_set_key,
5617c6cd 13660 .flags = GENL_UNS_ADMIN_PERM,
41265714 13661 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13662 NL80211_FLAG_NEED_RTNL |
13663 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
13664 },
13665 {
13666 .cmd = NL80211_CMD_NEW_KEY,
ef6243ac 13667 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 13668 .doit = nl80211_new_key,
5617c6cd 13669 .flags = GENL_UNS_ADMIN_PERM,
41265714 13670 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13671 NL80211_FLAG_NEED_RTNL |
13672 NL80211_FLAG_CLEAR_SKB,
41ade00f
JB
13673 },
13674 {
13675 .cmd = NL80211_CMD_DEL_KEY,
ef6243ac 13676 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
41ade00f 13677 .doit = nl80211_del_key,
5617c6cd 13678 .flags = GENL_UNS_ADMIN_PERM,
41265714 13679 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13680 NL80211_FLAG_NEED_RTNL,
55682965 13681 },
ed1b6cc7
JB
13682 {
13683 .cmd = NL80211_CMD_SET_BEACON,
ef6243ac 13684 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 13685 .flags = GENL_UNS_ADMIN_PERM,
8860020e 13686 .doit = nl80211_set_beacon,
2b5f8b0b 13687 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13688 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
13689 },
13690 {
8860020e 13691 .cmd = NL80211_CMD_START_AP,
ef6243ac 13692 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 13693 .flags = GENL_UNS_ADMIN_PERM,
8860020e 13694 .doit = nl80211_start_ap,
2b5f8b0b 13695 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13696 NL80211_FLAG_NEED_RTNL,
ed1b6cc7
JB
13697 },
13698 {
8860020e 13699 .cmd = NL80211_CMD_STOP_AP,
ef6243ac 13700 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5617c6cd 13701 .flags = GENL_UNS_ADMIN_PERM,
8860020e 13702 .doit = nl80211_stop_ap,
2b5f8b0b 13703 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13704 NL80211_FLAG_NEED_RTNL,
ed1b6cc7 13705 },
5727ef1b
JB
13706 {
13707 .cmd = NL80211_CMD_GET_STATION,
ef6243ac 13708 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 13709 .doit = nl80211_get_station,
2ec600d6 13710 .dumpit = nl80211_dump_station,
4c476991
JB
13711 .internal_flags = NL80211_FLAG_NEED_NETDEV |
13712 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
13713 },
13714 {
13715 .cmd = NL80211_CMD_SET_STATION,
ef6243ac 13716 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 13717 .doit = nl80211_set_station,
5617c6cd 13718 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13719 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13720 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
13721 },
13722 {
13723 .cmd = NL80211_CMD_NEW_STATION,
ef6243ac 13724 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 13725 .doit = nl80211_new_station,
5617c6cd 13726 .flags = GENL_UNS_ADMIN_PERM,
41265714 13727 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13728 NL80211_FLAG_NEED_RTNL,
5727ef1b
JB
13729 },
13730 {
13731 .cmd = NL80211_CMD_DEL_STATION,
ef6243ac 13732 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5727ef1b 13733 .doit = nl80211_del_station,
5617c6cd 13734 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13735 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13736 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
13737 },
13738 {
13739 .cmd = NL80211_CMD_GET_MPATH,
ef6243ac 13740 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6
LCC
13741 .doit = nl80211_get_mpath,
13742 .dumpit = nl80211_dump_mpath,
5617c6cd 13743 .flags = GENL_UNS_ADMIN_PERM,
41265714 13744 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13745 NL80211_FLAG_NEED_RTNL,
2ec600d6 13746 },
66be7d2b
HR
13747 {
13748 .cmd = NL80211_CMD_GET_MPP,
ef6243ac 13749 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
66be7d2b
HR
13750 .doit = nl80211_get_mpp,
13751 .dumpit = nl80211_dump_mpp,
5617c6cd 13752 .flags = GENL_UNS_ADMIN_PERM,
66be7d2b
HR
13753 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13754 NL80211_FLAG_NEED_RTNL,
13755 },
2ec600d6
LCC
13756 {
13757 .cmd = NL80211_CMD_SET_MPATH,
ef6243ac 13758 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 13759 .doit = nl80211_set_mpath,
5617c6cd 13760 .flags = GENL_UNS_ADMIN_PERM,
41265714 13761 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13762 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
13763 },
13764 {
13765 .cmd = NL80211_CMD_NEW_MPATH,
ef6243ac 13766 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 13767 .doit = nl80211_new_mpath,
5617c6cd 13768 .flags = GENL_UNS_ADMIN_PERM,
41265714 13769 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13770 NL80211_FLAG_NEED_RTNL,
2ec600d6
LCC
13771 },
13772 {
13773 .cmd = NL80211_CMD_DEL_MPATH,
ef6243ac 13774 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2ec600d6 13775 .doit = nl80211_del_mpath,
5617c6cd 13776 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13777 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13778 NL80211_FLAG_NEED_RTNL,
9f1ba906
JM
13779 },
13780 {
13781 .cmd = NL80211_CMD_SET_BSS,
ef6243ac 13782 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9f1ba906 13783 .doit = nl80211_set_bss,
5617c6cd 13784 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13785 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13786 NL80211_FLAG_NEED_RTNL,
b2e1b302 13787 },
f130347c
LR
13788 {
13789 .cmd = NL80211_CMD_GET_REG,
ef6243ac 13790 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad30ca2c
AN
13791 .doit = nl80211_get_reg_do,
13792 .dumpit = nl80211_get_reg_dump,
5fe231e8 13793 .internal_flags = NL80211_FLAG_NEED_RTNL,
f130347c
LR
13794 /* can be retrieved by unprivileged users */
13795 },
b6863036 13796#ifdef CONFIG_CFG80211_CRDA_SUPPORT
b2e1b302
LR
13797 {
13798 .cmd = NL80211_CMD_SET_REG,
ef6243ac 13799 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 13800 .doit = nl80211_set_reg,
b2e1b302 13801 .flags = GENL_ADMIN_PERM,
5fe231e8 13802 .internal_flags = NL80211_FLAG_NEED_RTNL,
b2e1b302 13803 },
b6863036 13804#endif
b2e1b302
LR
13805 {
13806 .cmd = NL80211_CMD_REQ_SET_REG,
ef6243ac 13807 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b2e1b302 13808 .doit = nl80211_req_set_reg,
93da9cc1 13809 .flags = GENL_ADMIN_PERM,
13810 },
1ea4ff3e
JB
13811 {
13812 .cmd = NL80211_CMD_RELOAD_REGDB,
ef6243ac 13813 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1ea4ff3e 13814 .doit = nl80211_reload_regdb,
1ea4ff3e
JB
13815 .flags = GENL_ADMIN_PERM,
13816 },
93da9cc1 13817 {
24bdd9f4 13818 .cmd = NL80211_CMD_GET_MESH_CONFIG,
ef6243ac 13819 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 13820 .doit = nl80211_get_mesh_config,
93da9cc1 13821 /* can be retrieved by unprivileged users */
2b5f8b0b 13822 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13823 NL80211_FLAG_NEED_RTNL,
93da9cc1 13824 },
13825 {
24bdd9f4 13826 .cmd = NL80211_CMD_SET_MESH_CONFIG,
ef6243ac 13827 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
24bdd9f4 13828 .doit = nl80211_update_mesh_config,
5617c6cd 13829 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c 13830 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13831 NL80211_FLAG_NEED_RTNL,
9aed3cc1 13832 },
2a519311
JB
13833 {
13834 .cmd = NL80211_CMD_TRIGGER_SCAN,
ef6243ac 13835 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311 13836 .doit = nl80211_trigger_scan,
5617c6cd 13837 .flags = GENL_UNS_ADMIN_PERM,
fd014284 13838 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 13839 NL80211_FLAG_NEED_RTNL,
2a519311 13840 },
91d3ab46
VK
13841 {
13842 .cmd = NL80211_CMD_ABORT_SCAN,
ef6243ac 13843 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
91d3ab46 13844 .doit = nl80211_abort_scan,
5617c6cd 13845 .flags = GENL_UNS_ADMIN_PERM,
91d3ab46
VK
13846 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
13847 NL80211_FLAG_NEED_RTNL,
13848 },
2a519311
JB
13849 {
13850 .cmd = NL80211_CMD_GET_SCAN,
ef6243ac 13851 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2a519311
JB
13852 .dumpit = nl80211_dump_scan,
13853 },
807f8a8c
LC
13854 {
13855 .cmd = NL80211_CMD_START_SCHED_SCAN,
ef6243ac 13856 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 13857 .doit = nl80211_start_sched_scan,
5617c6cd 13858 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
13859 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13860 NL80211_FLAG_NEED_RTNL,
13861 },
13862 {
13863 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
ef6243ac 13864 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
807f8a8c 13865 .doit = nl80211_stop_sched_scan,
5617c6cd 13866 .flags = GENL_UNS_ADMIN_PERM,
807f8a8c
LC
13867 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
13868 NL80211_FLAG_NEED_RTNL,
13869 },
636a5d36
JM
13870 {
13871 .cmd = NL80211_CMD_AUTHENTICATE,
ef6243ac 13872 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 13873 .doit = nl80211_authenticate,
5617c6cd 13874 .flags = GENL_UNS_ADMIN_PERM,
41265714 13875 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
13876 NL80211_FLAG_NEED_RTNL |
13877 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
13878 },
13879 {
13880 .cmd = NL80211_CMD_ASSOCIATE,
ef6243ac 13881 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 13882 .doit = nl80211_associate,
5617c6cd 13883 .flags = GENL_UNS_ADMIN_PERM,
41265714 13884 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
13885 NL80211_FLAG_NEED_RTNL |
13886 NL80211_FLAG_CLEAR_SKB,
636a5d36
JM
13887 },
13888 {
13889 .cmd = NL80211_CMD_DEAUTHENTICATE,
ef6243ac 13890 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 13891 .doit = nl80211_deauthenticate,
5617c6cd 13892 .flags = GENL_UNS_ADMIN_PERM,
41265714 13893 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13894 NL80211_FLAG_NEED_RTNL,
636a5d36
JM
13895 },
13896 {
13897 .cmd = NL80211_CMD_DISASSOCIATE,
ef6243ac 13898 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
636a5d36 13899 .doit = nl80211_disassociate,
5617c6cd 13900 .flags = GENL_UNS_ADMIN_PERM,
41265714 13901 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13902 NL80211_FLAG_NEED_RTNL,
636a5d36 13903 },
04a773ad
JB
13904 {
13905 .cmd = NL80211_CMD_JOIN_IBSS,
ef6243ac 13906 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 13907 .doit = nl80211_join_ibss,
5617c6cd 13908 .flags = GENL_UNS_ADMIN_PERM,
41265714 13909 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13910 NL80211_FLAG_NEED_RTNL,
04a773ad
JB
13911 },
13912 {
13913 .cmd = NL80211_CMD_LEAVE_IBSS,
ef6243ac 13914 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04a773ad 13915 .doit = nl80211_leave_ibss,
5617c6cd 13916 .flags = GENL_UNS_ADMIN_PERM,
41265714 13917 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13918 NL80211_FLAG_NEED_RTNL,
04a773ad 13919 },
aff89a9b
JB
13920#ifdef CONFIG_NL80211_TESTMODE
13921 {
13922 .cmd = NL80211_CMD_TESTMODE,
ef6243ac 13923 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
aff89a9b 13924 .doit = nl80211_testmode_do,
71063f0e 13925 .dumpit = nl80211_testmode_dump,
5617c6cd 13926 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13927 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13928 NL80211_FLAG_NEED_RTNL,
aff89a9b
JB
13929 },
13930#endif
b23aa676
SO
13931 {
13932 .cmd = NL80211_CMD_CONNECT,
ef6243ac 13933 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 13934 .doit = nl80211_connect,
5617c6cd 13935 .flags = GENL_UNS_ADMIN_PERM,
41265714 13936 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
13937 NL80211_FLAG_NEED_RTNL |
13938 NL80211_FLAG_CLEAR_SKB,
b23aa676 13939 },
088e8df8 13940 {
13941 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
ef6243ac 13942 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
088e8df8 13943 .doit = nl80211_update_connect_params,
088e8df8 13944 .flags = GENL_ADMIN_PERM,
13945 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
13946 NL80211_FLAG_NEED_RTNL |
13947 NL80211_FLAG_CLEAR_SKB,
088e8df8 13948 },
b23aa676
SO
13949 {
13950 .cmd = NL80211_CMD_DISCONNECT,
ef6243ac 13951 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
b23aa676 13952 .doit = nl80211_disconnect,
5617c6cd 13953 .flags = GENL_UNS_ADMIN_PERM,
41265714 13954 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13955 NL80211_FLAG_NEED_RTNL,
b23aa676 13956 },
463d0183
JB
13957 {
13958 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
ef6243ac 13959 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
463d0183 13960 .doit = nl80211_wiphy_netns,
5617c6cd 13961 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
13962 .internal_flags = NL80211_FLAG_NEED_WIPHY |
13963 NL80211_FLAG_NEED_RTNL,
463d0183 13964 },
61fa713c
HS
13965 {
13966 .cmd = NL80211_CMD_GET_SURVEY,
ef6243ac 13967 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
61fa713c
HS
13968 .dumpit = nl80211_dump_survey,
13969 },
67fbb16b
SO
13970 {
13971 .cmd = NL80211_CMD_SET_PMKSA,
ef6243ac 13972 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 13973 .doit = nl80211_setdel_pmksa,
5617c6cd 13974 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13975 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
13976 NL80211_FLAG_NEED_RTNL |
13977 NL80211_FLAG_CLEAR_SKB,
67fbb16b
SO
13978 },
13979 {
13980 .cmd = NL80211_CMD_DEL_PMKSA,
ef6243ac 13981 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 13982 .doit = nl80211_setdel_pmksa,
5617c6cd 13983 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13984 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13985 NL80211_FLAG_NEED_RTNL,
67fbb16b
SO
13986 },
13987 {
13988 .cmd = NL80211_CMD_FLUSH_PMKSA,
ef6243ac 13989 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
67fbb16b 13990 .doit = nl80211_flush_pmksa,
5617c6cd 13991 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 13992 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
4c476991 13993 NL80211_FLAG_NEED_RTNL,
67fbb16b 13994 },
9588bbd5
JM
13995 {
13996 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
ef6243ac 13997 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 13998 .doit = nl80211_remain_on_channel,
5617c6cd 13999 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14000 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 14001 NL80211_FLAG_NEED_RTNL,
9588bbd5
JM
14002 },
14003 {
14004 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
ef6243ac 14005 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9588bbd5 14006 .doit = nl80211_cancel_remain_on_channel,
5617c6cd 14007 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14008 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 14009 NL80211_FLAG_NEED_RTNL,
9588bbd5 14010 },
13ae75b1
JM
14011 {
14012 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
ef6243ac 14013 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
13ae75b1 14014 .doit = nl80211_set_tx_bitrate_mask,
5617c6cd 14015 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14016 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14017 NL80211_FLAG_NEED_RTNL,
13ae75b1 14018 },
026331c4 14019 {
2e161f78 14020 .cmd = NL80211_CMD_REGISTER_FRAME,
ef6243ac 14021 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 14022 .doit = nl80211_register_mgmt,
5617c6cd 14023 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14024 .internal_flags = NL80211_FLAG_NEED_WDEV |
4c476991 14025 NL80211_FLAG_NEED_RTNL,
026331c4
JM
14026 },
14027 {
2e161f78 14028 .cmd = NL80211_CMD_FRAME,
ef6243ac 14029 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2e161f78 14030 .doit = nl80211_tx_mgmt,
5617c6cd 14031 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14032 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
f7ca38df
JB
14033 NL80211_FLAG_NEED_RTNL,
14034 },
14035 {
14036 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
ef6243ac 14037 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f7ca38df 14038 .doit = nl80211_tx_mgmt_cancel_wait,
5617c6cd 14039 .flags = GENL_UNS_ADMIN_PERM,
71bbc994 14040 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
4c476991 14041 NL80211_FLAG_NEED_RTNL,
026331c4 14042 },
ffb9eb3d
KV
14043 {
14044 .cmd = NL80211_CMD_SET_POWER_SAVE,
ef6243ac 14045 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 14046 .doit = nl80211_set_power_save,
5617c6cd 14047 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14048 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14049 NL80211_FLAG_NEED_RTNL,
ffb9eb3d
KV
14050 },
14051 {
14052 .cmd = NL80211_CMD_GET_POWER_SAVE,
ef6243ac 14053 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ffb9eb3d 14054 .doit = nl80211_get_power_save,
ffb9eb3d 14055 /* can be retrieved by unprivileged users */
4c476991
JB
14056 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14057 NL80211_FLAG_NEED_RTNL,
ffb9eb3d 14058 },
d6dc1a38
JO
14059 {
14060 .cmd = NL80211_CMD_SET_CQM,
ef6243ac 14061 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
d6dc1a38 14062 .doit = nl80211_set_cqm,
5617c6cd 14063 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14064 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14065 NL80211_FLAG_NEED_RTNL,
d6dc1a38 14066 },
f444de05
JB
14067 {
14068 .cmd = NL80211_CMD_SET_CHANNEL,
ef6243ac 14069 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f444de05 14070 .doit = nl80211_set_channel,
5617c6cd 14071 .flags = GENL_UNS_ADMIN_PERM,
4c476991
JB
14072 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14073 NL80211_FLAG_NEED_RTNL,
f444de05 14074 },
e8347eba
BJ
14075 {
14076 .cmd = NL80211_CMD_SET_WDS_PEER,
ef6243ac 14077 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
e8347eba 14078 .doit = nl80211_set_wds_peer,
5617c6cd 14079 .flags = GENL_UNS_ADMIN_PERM,
43b19952
JB
14080 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14081 NL80211_FLAG_NEED_RTNL,
e8347eba 14082 },
29cbe68c
JB
14083 {
14084 .cmd = NL80211_CMD_JOIN_MESH,
ef6243ac 14085 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 14086 .doit = nl80211_join_mesh,
5617c6cd 14087 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
14088 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14089 NL80211_FLAG_NEED_RTNL,
14090 },
14091 {
14092 .cmd = NL80211_CMD_LEAVE_MESH,
ef6243ac 14093 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
29cbe68c 14094 .doit = nl80211_leave_mesh,
5617c6cd 14095 .flags = GENL_UNS_ADMIN_PERM,
29cbe68c
JB
14096 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14097 NL80211_FLAG_NEED_RTNL,
14098 },
6e0bd6c3
RL
14099 {
14100 .cmd = NL80211_CMD_JOIN_OCB,
ef6243ac 14101 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 14102 .doit = nl80211_join_ocb,
5617c6cd 14103 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
14104 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14105 NL80211_FLAG_NEED_RTNL,
14106 },
14107 {
14108 .cmd = NL80211_CMD_LEAVE_OCB,
ef6243ac 14109 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
6e0bd6c3 14110 .doit = nl80211_leave_ocb,
5617c6cd 14111 .flags = GENL_UNS_ADMIN_PERM,
6e0bd6c3
RL
14112 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14113 NL80211_FLAG_NEED_RTNL,
14114 },
dfb89c56 14115#ifdef CONFIG_PM
ff1b6e69
JB
14116 {
14117 .cmd = NL80211_CMD_GET_WOWLAN,
ef6243ac 14118 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 14119 .doit = nl80211_get_wowlan,
ff1b6e69
JB
14120 /* can be retrieved by unprivileged users */
14121 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14122 NL80211_FLAG_NEED_RTNL,
14123 },
14124 {
14125 .cmd = NL80211_CMD_SET_WOWLAN,
ef6243ac 14126 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ff1b6e69 14127 .doit = nl80211_set_wowlan,
5617c6cd 14128 .flags = GENL_UNS_ADMIN_PERM,
ff1b6e69
JB
14129 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14130 NL80211_FLAG_NEED_RTNL,
14131 },
dfb89c56 14132#endif
e5497d76
JB
14133 {
14134 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
ef6243ac 14135 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
e5497d76 14136 .doit = nl80211_set_rekey_data,
5617c6cd 14137 .flags = GENL_UNS_ADMIN_PERM,
e5497d76 14138 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
5393b917
JB
14139 NL80211_FLAG_NEED_RTNL |
14140 NL80211_FLAG_CLEAR_SKB,
e5497d76 14141 },
109086ce
AN
14142 {
14143 .cmd = NL80211_CMD_TDLS_MGMT,
ef6243ac 14144 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 14145 .doit = nl80211_tdls_mgmt,
5617c6cd 14146 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
14147 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14148 NL80211_FLAG_NEED_RTNL,
14149 },
14150 {
14151 .cmd = NL80211_CMD_TDLS_OPER,
ef6243ac 14152 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
109086ce 14153 .doit = nl80211_tdls_oper,
5617c6cd 14154 .flags = GENL_UNS_ADMIN_PERM,
109086ce
AN
14155 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14156 NL80211_FLAG_NEED_RTNL,
14157 },
28946da7
JB
14158 {
14159 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
ef6243ac 14160 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
28946da7 14161 .doit = nl80211_register_unexpected_frame,
5617c6cd 14162 .flags = GENL_UNS_ADMIN_PERM,
28946da7
JB
14163 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14164 NL80211_FLAG_NEED_RTNL,
14165 },
7f6cf311
JB
14166 {
14167 .cmd = NL80211_CMD_PROBE_CLIENT,
ef6243ac 14168 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
7f6cf311 14169 .doit = nl80211_probe_client,
5617c6cd 14170 .flags = GENL_UNS_ADMIN_PERM,
2b5f8b0b 14171 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
7f6cf311
JB
14172 NL80211_FLAG_NEED_RTNL,
14173 },
5e760230
JB
14174 {
14175 .cmd = NL80211_CMD_REGISTER_BEACONS,
ef6243ac 14176 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5e760230 14177 .doit = nl80211_register_beacons,
5617c6cd 14178 .flags = GENL_UNS_ADMIN_PERM,
5e760230
JB
14179 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14180 NL80211_FLAG_NEED_RTNL,
14181 },
1d9d9213
SW
14182 {
14183 .cmd = NL80211_CMD_SET_NOACK_MAP,
ef6243ac 14184 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1d9d9213 14185 .doit = nl80211_set_noack_map,
5617c6cd 14186 .flags = GENL_UNS_ADMIN_PERM,
1d9d9213
SW
14187 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14188 NL80211_FLAG_NEED_RTNL,
14189 },
98104fde
JB
14190 {
14191 .cmd = NL80211_CMD_START_P2P_DEVICE,
ef6243ac 14192 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 14193 .doit = nl80211_start_p2p_device,
5617c6cd 14194 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
14195 .internal_flags = NL80211_FLAG_NEED_WDEV |
14196 NL80211_FLAG_NEED_RTNL,
14197 },
14198 {
14199 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
ef6243ac 14200 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
98104fde 14201 .doit = nl80211_stop_p2p_device,
5617c6cd 14202 .flags = GENL_UNS_ADMIN_PERM,
98104fde
JB
14203 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14204 NL80211_FLAG_NEED_RTNL,
cb3b7d87
AB
14205 },
14206 {
14207 .cmd = NL80211_CMD_START_NAN,
ef6243ac 14208 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 14209 .doit = nl80211_start_nan,
cb3b7d87
AB
14210 .flags = GENL_ADMIN_PERM,
14211 .internal_flags = NL80211_FLAG_NEED_WDEV |
14212 NL80211_FLAG_NEED_RTNL,
14213 },
14214 {
14215 .cmd = NL80211_CMD_STOP_NAN,
ef6243ac 14216 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
cb3b7d87 14217 .doit = nl80211_stop_nan,
cb3b7d87
AB
14218 .flags = GENL_ADMIN_PERM,
14219 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14220 NL80211_FLAG_NEED_RTNL,
a442b761
AB
14221 },
14222 {
14223 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
ef6243ac 14224 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 14225 .doit = nl80211_nan_add_func,
a442b761
AB
14226 .flags = GENL_ADMIN_PERM,
14227 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14228 NL80211_FLAG_NEED_RTNL,
14229 },
14230 {
14231 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
ef6243ac 14232 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a442b761 14233 .doit = nl80211_nan_del_func,
a442b761
AB
14234 .flags = GENL_ADMIN_PERM,
14235 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14236 NL80211_FLAG_NEED_RTNL,
a5a9dcf2
AB
14237 },
14238 {
14239 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
ef6243ac 14240 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
a5a9dcf2 14241 .doit = nl80211_nan_change_config,
a5a9dcf2
AB
14242 .flags = GENL_ADMIN_PERM,
14243 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14244 NL80211_FLAG_NEED_RTNL,
98104fde 14245 },
f4e583c8
AQ
14246 {
14247 .cmd = NL80211_CMD_SET_MCAST_RATE,
ef6243ac 14248 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
f4e583c8 14249 .doit = nl80211_set_mcast_rate,
5617c6cd 14250 .flags = GENL_UNS_ADMIN_PERM,
77765eaf
VT
14251 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14252 NL80211_FLAG_NEED_RTNL,
14253 },
14254 {
14255 .cmd = NL80211_CMD_SET_MAC_ACL,
ef6243ac 14256 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
77765eaf 14257 .doit = nl80211_set_mac_acl,
5617c6cd 14258 .flags = GENL_UNS_ADMIN_PERM,
f4e583c8
AQ
14259 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14260 NL80211_FLAG_NEED_RTNL,
14261 },
04f39047
SW
14262 {
14263 .cmd = NL80211_CMD_RADAR_DETECT,
ef6243ac 14264 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
04f39047 14265 .doit = nl80211_start_radar_detection,
5617c6cd 14266 .flags = GENL_UNS_ADMIN_PERM,
04f39047
SW
14267 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14268 NL80211_FLAG_NEED_RTNL,
14269 },
3713b4e3
JB
14270 {
14271 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
ef6243ac 14272 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3713b4e3 14273 .doit = nl80211_get_protocol_features,
3713b4e3 14274 },
355199e0
JM
14275 {
14276 .cmd = NL80211_CMD_UPDATE_FT_IES,
ef6243ac 14277 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
355199e0 14278 .doit = nl80211_update_ft_ies,
5617c6cd 14279 .flags = GENL_UNS_ADMIN_PERM,
355199e0
JM
14280 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14281 NL80211_FLAG_NEED_RTNL,
14282 },
5de17984
AS
14283 {
14284 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
ef6243ac 14285 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 14286 .doit = nl80211_crit_protocol_start,
5617c6cd 14287 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
14288 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14289 NL80211_FLAG_NEED_RTNL,
14290 },
14291 {
14292 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
ef6243ac 14293 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
5de17984 14294 .doit = nl80211_crit_protocol_stop,
5617c6cd 14295 .flags = GENL_UNS_ADMIN_PERM,
5de17984
AS
14296 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14297 NL80211_FLAG_NEED_RTNL,
be29b99a
AK
14298 },
14299 {
14300 .cmd = NL80211_CMD_GET_COALESCE,
ef6243ac 14301 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 14302 .doit = nl80211_get_coalesce,
be29b99a
AK
14303 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14304 NL80211_FLAG_NEED_RTNL,
14305 },
14306 {
14307 .cmd = NL80211_CMD_SET_COALESCE,
ef6243ac 14308 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
be29b99a 14309 .doit = nl80211_set_coalesce,
5617c6cd 14310 .flags = GENL_UNS_ADMIN_PERM,
be29b99a
AK
14311 .internal_flags = NL80211_FLAG_NEED_WIPHY |
14312 NL80211_FLAG_NEED_RTNL,
16ef1fe2
SW
14313 },
14314 {
14315 .cmd = NL80211_CMD_CHANNEL_SWITCH,
ef6243ac 14316 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16ef1fe2 14317 .doit = nl80211_channel_switch,
5617c6cd 14318 .flags = GENL_UNS_ADMIN_PERM,
16ef1fe2
SW
14319 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14320 NL80211_FLAG_NEED_RTNL,
14321 },
ad7e718c
JB
14322 {
14323 .cmd = NL80211_CMD_VENDOR,
ef6243ac 14324 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ad7e718c 14325 .doit = nl80211_vendor_cmd,
7bdbe400 14326 .dumpit = nl80211_vendor_cmd_dump,
5617c6cd 14327 .flags = GENL_UNS_ADMIN_PERM,
ad7e718c 14328 .internal_flags = NL80211_FLAG_NEED_WIPHY |
d6db02a8
SD
14329 NL80211_FLAG_NEED_RTNL |
14330 NL80211_FLAG_CLEAR_SKB,
ad7e718c 14331 },
fa9ffc74
KP
14332 {
14333 .cmd = NL80211_CMD_SET_QOS_MAP,
ef6243ac 14334 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
fa9ffc74 14335 .doit = nl80211_set_qos_map,
5617c6cd 14336 .flags = GENL_UNS_ADMIN_PERM,
fa9ffc74
KP
14337 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14338 NL80211_FLAG_NEED_RTNL,
14339 },
960d01ac
JB
14340 {
14341 .cmd = NL80211_CMD_ADD_TX_TS,
ef6243ac 14342 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 14343 .doit = nl80211_add_tx_ts,
5617c6cd 14344 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
14345 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14346 NL80211_FLAG_NEED_RTNL,
14347 },
14348 {
14349 .cmd = NL80211_CMD_DEL_TX_TS,
ef6243ac 14350 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
960d01ac 14351 .doit = nl80211_del_tx_ts,
5617c6cd 14352 .flags = GENL_UNS_ADMIN_PERM,
960d01ac
JB
14353 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14354 NL80211_FLAG_NEED_RTNL,
14355 },
1057d35e
AN
14356 {
14357 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
ef6243ac 14358 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 14359 .doit = nl80211_tdls_channel_switch,
5617c6cd 14360 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
14361 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14362 NL80211_FLAG_NEED_RTNL,
14363 },
14364 {
14365 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
ef6243ac 14366 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
1057d35e 14367 .doit = nl80211_tdls_cancel_channel_switch,
5617c6cd 14368 .flags = GENL_UNS_ADMIN_PERM,
1057d35e
AN
14369 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14370 NL80211_FLAG_NEED_RTNL,
14371 },
ce0ce13a
MB
14372 {
14373 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
ef6243ac 14374 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
ce0ce13a 14375 .doit = nl80211_set_multicast_to_unicast,
ce0ce13a
MB
14376 .flags = GENL_UNS_ADMIN_PERM,
14377 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14378 NL80211_FLAG_NEED_RTNL,
14379 },
3a00df57
AS
14380 {
14381 .cmd = NL80211_CMD_SET_PMK,
ef6243ac 14382 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 14383 .doit = nl80211_set_pmk,
3a00df57 14384 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
d6db02a8
SD
14385 NL80211_FLAG_NEED_RTNL |
14386 NL80211_FLAG_CLEAR_SKB,
3a00df57
AS
14387 },
14388 {
14389 .cmd = NL80211_CMD_DEL_PMK,
ef6243ac 14390 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
3a00df57 14391 .doit = nl80211_del_pmk,
3a00df57
AS
14392 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14393 NL80211_FLAG_NEED_RTNL,
14394 },
40cbfa90
SD
14395 {
14396 .cmd = NL80211_CMD_EXTERNAL_AUTH,
ef6243ac 14397 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
40cbfa90 14398 .doit = nl80211_external_auth,
40cbfa90
SD
14399 .flags = GENL_ADMIN_PERM,
14400 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14401 NL80211_FLAG_NEED_RTNL,
14402 },
2576a9ac
DK
14403 {
14404 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
ef6243ac 14405 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
2576a9ac 14406 .doit = nl80211_tx_control_port,
2576a9ac
DK
14407 .flags = GENL_UNS_ADMIN_PERM,
14408 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14409 NL80211_FLAG_NEED_RTNL,
14410 },
81e54d08
PKC
14411 {
14412 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
ef6243ac 14413 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
81e54d08 14414 .doit = nl80211_get_ftm_responder_stats,
81e54d08
PKC
14415 .internal_flags = NL80211_FLAG_NEED_NETDEV |
14416 NL80211_FLAG_NEED_RTNL,
14417 },
9bb7e0f2
JB
14418 {
14419 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
ef6243ac 14420 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9bb7e0f2 14421 .doit = nl80211_pmsr_start,
9bb7e0f2
JB
14422 .flags = GENL_UNS_ADMIN_PERM,
14423 .internal_flags = NL80211_FLAG_NEED_WDEV_UP |
14424 NL80211_FLAG_NEED_RTNL,
14425 },
30c63115
S
14426 {
14427 .cmd = NL80211_CMD_NOTIFY_RADAR,
ef6243ac 14428 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
30c63115 14429 .doit = nl80211_notify_radar_detection,
30c63115
S
14430 .flags = GENL_UNS_ADMIN_PERM,
14431 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14432 NL80211_FLAG_NEED_RTNL,
14433 },
cb74e977
SD
14434 {
14435 .cmd = NL80211_CMD_UPDATE_OWE_INFO,
14436 .doit = nl80211_update_owe_info,
14437 .flags = GENL_ADMIN_PERM,
5ab92e7f
RM
14438 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14439 NL80211_FLAG_NEED_RTNL,
14440 },
14441 {
14442 .cmd = NL80211_CMD_PROBE_MESH_LINK,
14443 .doit = nl80211_probe_mesh_link,
14444 .flags = GENL_UNS_ADMIN_PERM,
cb74e977
SD
14445 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
14446 NL80211_FLAG_NEED_RTNL,
14447 },
55682965 14448};
9588bbd5 14449
56989f6d 14450static struct genl_family nl80211_fam __ro_after_init = {
489111e5
JB
14451 .name = NL80211_GENL_NAME, /* have users key off the name instead */
14452 .hdrsize = 0, /* no private header */
14453 .version = 1, /* no particular meaning now */
14454 .maxattr = NL80211_ATTR_MAX,
3b0f31f2 14455 .policy = nl80211_policy,
489111e5
JB
14456 .netnsok = true,
14457 .pre_doit = nl80211_pre_doit,
14458 .post_doit = nl80211_post_doit,
14459 .module = THIS_MODULE,
14460 .ops = nl80211_ops,
14461 .n_ops = ARRAY_SIZE(nl80211_ops),
14462 .mcgrps = nl80211_mcgrps,
14463 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
14464};
14465
55682965
JB
14466/* notification functions */
14467
3bb20556
JB
14468void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
14469 enum nl80211_commands cmd)
55682965
JB
14470{
14471 struct sk_buff *msg;
86e8cf98 14472 struct nl80211_dump_wiphy_state state = {};
55682965 14473
3bb20556
JB
14474 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
14475 cmd != NL80211_CMD_DEL_WIPHY);
14476
fd2120ca 14477 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
55682965
JB
14478 if (!msg)
14479 return;
14480
3bb20556 14481 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
55682965
JB
14482 nlmsg_free(msg);
14483 return;
14484 }
14485
68eb5503 14486 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14487 NL80211_MCGRP_CONFIG, GFP_KERNEL);
55682965
JB
14488}
14489
896ff063
DK
14490void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
14491 struct wireless_dev *wdev,
14492 enum nl80211_commands cmd)
14493{
14494 struct sk_buff *msg;
14495
896ff063
DK
14496 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14497 if (!msg)
14498 return;
14499
3d1a5bbf 14500 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
896ff063
DK
14501 nlmsg_free(msg);
14502 return;
14503 }
14504
14505 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
14506 NL80211_MCGRP_CONFIG, GFP_KERNEL);
14507}
14508
362a415d
JB
14509static int nl80211_add_scan_req(struct sk_buff *msg,
14510 struct cfg80211_registered_device *rdev)
14511{
14512 struct cfg80211_scan_request *req = rdev->scan_req;
14513 struct nlattr *nest;
14514 int i;
14515
14516 if (WARN_ON(!req))
14517 return 0;
14518
ae0be8de 14519 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_SSIDS);
362a415d
JB
14520 if (!nest)
14521 goto nla_put_failure;
9360ffd1
DM
14522 for (i = 0; i < req->n_ssids; i++) {
14523 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
14524 goto nla_put_failure;
14525 }
362a415d
JB
14526 nla_nest_end(msg, nest);
14527
ae0be8de 14528 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
362a415d
JB
14529 if (!nest)
14530 goto nla_put_failure;
9360ffd1
DM
14531 for (i = 0; i < req->n_channels; i++) {
14532 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
14533 goto nla_put_failure;
14534 }
362a415d
JB
14535 nla_nest_end(msg, nest);
14536
9360ffd1
DM
14537 if (req->ie &&
14538 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
14539 goto nla_put_failure;
362a415d 14540
ae917c9f
JB
14541 if (req->flags &&
14542 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
14543 goto nla_put_failure;
ed473771 14544
1d76250b
AS
14545 if (req->info.scan_start_tsf &&
14546 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
14547 req->info.scan_start_tsf, NL80211_BSS_PAD) ||
14548 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
14549 req->info.tsf_bssid)))
14550 goto nla_put_failure;
14551
362a415d
JB
14552 return 0;
14553 nla_put_failure:
14554 return -ENOBUFS;
14555}
14556
505a2e88 14557static int nl80211_prep_scan_msg(struct sk_buff *msg,
a538e2d5 14558 struct cfg80211_registered_device *rdev,
fd014284 14559 struct wireless_dev *wdev,
15e47304 14560 u32 portid, u32 seq, int flags,
a538e2d5 14561 u32 cmd)
2a519311
JB
14562{
14563 void *hdr;
14564
15e47304 14565 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2a519311
JB
14566 if (!hdr)
14567 return -1;
14568
9360ffd1 14569 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
fd014284
JB
14570 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14571 wdev->netdev->ifindex)) ||
2dad624e
ND
14572 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14573 NL80211_ATTR_PAD))
9360ffd1 14574 goto nla_put_failure;
2a519311 14575
362a415d
JB
14576 /* ignore errors and send incomplete event anyway */
14577 nl80211_add_scan_req(msg, rdev);
2a519311 14578
053c095a
JB
14579 genlmsg_end(msg, hdr);
14580 return 0;
2a519311
JB
14581
14582 nla_put_failure:
14583 genlmsg_cancel(msg, hdr);
14584 return -EMSGSIZE;
14585}
14586
807f8a8c 14587static int
505a2e88 14588nl80211_prep_sched_scan_msg(struct sk_buff *msg,
96b08fd6 14589 struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
14590{
14591 void *hdr;
14592
96b08fd6 14593 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
807f8a8c
LC
14594 if (!hdr)
14595 return -1;
14596
96b08fd6
AVS
14597 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
14598 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
14599 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
14600 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
14601 NL80211_ATTR_PAD))
9360ffd1 14602 goto nla_put_failure;
807f8a8c 14603
053c095a
JB
14604 genlmsg_end(msg, hdr);
14605 return 0;
807f8a8c
LC
14606
14607 nla_put_failure:
14608 genlmsg_cancel(msg, hdr);
14609 return -EMSGSIZE;
14610}
14611
a538e2d5 14612void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
fd014284 14613 struct wireless_dev *wdev)
a538e2d5
JB
14614{
14615 struct sk_buff *msg;
14616
58050fce 14617 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
a538e2d5
JB
14618 if (!msg)
14619 return;
14620
505a2e88 14621 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
a538e2d5
JB
14622 NL80211_CMD_TRIGGER_SCAN) < 0) {
14623 nlmsg_free(msg);
14624 return;
14625 }
14626
68eb5503 14627 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14628 NL80211_MCGRP_SCAN, GFP_KERNEL);
a538e2d5
JB
14629}
14630
f9d15d16
JB
14631struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
14632 struct wireless_dev *wdev, bool aborted)
2a519311
JB
14633{
14634 struct sk_buff *msg;
14635
fd2120ca 14636 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2a519311 14637 if (!msg)
f9d15d16 14638 return NULL;
2a519311 14639
505a2e88 14640 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
f9d15d16
JB
14641 aborted ? NL80211_CMD_SCAN_ABORTED :
14642 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
2a519311 14643 nlmsg_free(msg);
f9d15d16 14644 return NULL;
2a519311
JB
14645 }
14646
f9d15d16 14647 return msg;
2a519311
JB
14648}
14649
505a2e88
AVS
14650/* send message created by nl80211_build_scan_msg() */
14651void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
14652 struct sk_buff *msg)
807f8a8c 14653{
807f8a8c
LC
14654 if (!msg)
14655 return;
14656
68eb5503 14657 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14658 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
14659}
14660
96b08fd6 14661void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
807f8a8c
LC
14662{
14663 struct sk_buff *msg;
14664
58050fce 14665 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
807f8a8c
LC
14666 if (!msg)
14667 return;
14668
96b08fd6 14669 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
807f8a8c
LC
14670 nlmsg_free(msg);
14671 return;
14672 }
14673
96b08fd6 14674 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
2a94fe48 14675 NL80211_MCGRP_SCAN, GFP_KERNEL);
807f8a8c
LC
14676}
14677
b0d7aa59
JD
14678static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
14679 struct regulatory_request *request)
73d54c9e 14680{
73d54c9e 14681 /* Userspace can always count this one always being set */
9360ffd1
DM
14682 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
14683 goto nla_put_failure;
14684
14685 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
14686 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14687 NL80211_REGDOM_TYPE_WORLD))
14688 goto nla_put_failure;
14689 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
14690 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14691 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
14692 goto nla_put_failure;
14693 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
14694 request->intersect) {
14695 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14696 NL80211_REGDOM_TYPE_INTERSECTION))
14697 goto nla_put_failure;
14698 } else {
14699 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
14700 NL80211_REGDOM_TYPE_COUNTRY) ||
14701 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
14702 request->alpha2))
14703 goto nla_put_failure;
14704 }
14705
ad30ca2c
AN
14706 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
14707 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
14708
14709 if (wiphy &&
14710 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
14711 goto nla_put_failure;
1bdd716c
AN
14712
14713 if (wiphy &&
14714 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
14715 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
14716 goto nla_put_failure;
ad30ca2c 14717 }
73d54c9e 14718
b0d7aa59
JD
14719 return true;
14720
14721nla_put_failure:
14722 return false;
14723}
14724
14725/*
14726 * This can happen on global regulatory changes or device specific settings
14727 * based on custom regulatory domains.
14728 */
14729void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
14730 struct regulatory_request *request)
14731{
14732 struct sk_buff *msg;
14733 void *hdr;
14734
14735 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14736 if (!msg)
14737 return;
14738
14739 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
14740 if (!hdr) {
14741 nlmsg_free(msg);
14742 return;
14743 }
14744
14745 if (nl80211_reg_change_event_fill(msg, request) == false)
14746 goto nla_put_failure;
14747
3b7b72ee 14748 genlmsg_end(msg, hdr);
73d54c9e 14749
bc43b28c 14750 rcu_read_lock();
68eb5503 14751 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 14752 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
bc43b28c 14753 rcu_read_unlock();
73d54c9e
LR
14754
14755 return;
14756
14757nla_put_failure:
73d54c9e
LR
14758 nlmsg_free(msg);
14759}
14760
6039f6d2
JM
14761static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
14762 struct net_device *netdev,
14763 const u8 *buf, size_t len,
b0b6aa2c 14764 enum nl80211_commands cmd, gfp_t gfp,
4d9ec73d
JM
14765 int uapsd_queues, const u8 *req_ies,
14766 size_t req_ies_len)
6039f6d2
JM
14767{
14768 struct sk_buff *msg;
14769 void *hdr;
14770
4d9ec73d 14771 msg = nlmsg_new(100 + len + req_ies_len, gfp);
6039f6d2
JM
14772 if (!msg)
14773 return;
14774
14775 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
14776 if (!hdr) {
14777 nlmsg_free(msg);
14778 return;
14779 }
14780
9360ffd1
DM
14781 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14782 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
4d9ec73d
JM
14783 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
14784 (req_ies &&
14785 nla_put(msg, NL80211_ATTR_REQ_IE, req_ies_len, req_ies)))
9360ffd1 14786 goto nla_put_failure;
6039f6d2 14787
b0b6aa2c
EP
14788 if (uapsd_queues >= 0) {
14789 struct nlattr *nla_wmm =
ae0be8de 14790 nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
b0b6aa2c
EP
14791 if (!nla_wmm)
14792 goto nla_put_failure;
14793
14794 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
14795 uapsd_queues))
14796 goto nla_put_failure;
14797
14798 nla_nest_end(msg, nla_wmm);
14799 }
14800
3b7b72ee 14801 genlmsg_end(msg, hdr);
6039f6d2 14802
68eb5503 14803 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14804 NL80211_MCGRP_MLME, gfp);
6039f6d2
JM
14805 return;
14806
14807 nla_put_failure:
6039f6d2
JM
14808 nlmsg_free(msg);
14809}
14810
14811void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14812 struct net_device *netdev, const u8 *buf,
14813 size_t len, gfp_t gfp)
6039f6d2
JM
14814{
14815 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 14816 NL80211_CMD_AUTHENTICATE, gfp, -1, NULL, 0);
6039f6d2
JM
14817}
14818
14819void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
14820 struct net_device *netdev, const u8 *buf,
4d9ec73d
JM
14821 size_t len, gfp_t gfp, int uapsd_queues,
14822 const u8 *req_ies, size_t req_ies_len)
6039f6d2 14823{
e6d6e342 14824 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d
JM
14825 NL80211_CMD_ASSOCIATE, gfp, uapsd_queues,
14826 req_ies, req_ies_len);
6039f6d2
JM
14827}
14828
53b46b84 14829void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14830 struct net_device *netdev, const u8 *buf,
14831 size_t len, gfp_t gfp)
6039f6d2
JM
14832{
14833 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 14834 NL80211_CMD_DEAUTHENTICATE, gfp, -1, NULL, 0);
6039f6d2
JM
14835}
14836
53b46b84
JM
14837void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
14838 struct net_device *netdev, const u8 *buf,
e6d6e342 14839 size_t len, gfp_t gfp)
6039f6d2
JM
14840{
14841 nl80211_send_mlme_event(rdev, netdev, buf, len,
4d9ec73d 14842 NL80211_CMD_DISASSOCIATE, gfp, -1, NULL, 0);
6039f6d2
JM
14843}
14844
6ff57cf8
JB
14845void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
14846 size_t len)
cf4e594e 14847{
947add36
JB
14848 struct wireless_dev *wdev = dev->ieee80211_ptr;
14849 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 14850 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6ff57cf8
JB
14851 const struct ieee80211_mgmt *mgmt = (void *)buf;
14852 u32 cmd;
947add36 14853
6ff57cf8
JB
14854 if (WARN_ON(len < 2))
14855 return;
cf4e594e 14856
6ff57cf8
JB
14857 if (ieee80211_is_deauth(mgmt->frame_control))
14858 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
14859 else
14860 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
947add36 14861
6ff57cf8 14862 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
4d9ec73d
JM
14863 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1,
14864 NULL, 0);
cf4e594e 14865}
6ff57cf8 14866EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
cf4e594e 14867
1b06bb40
LR
14868static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
14869 struct net_device *netdev, int cmd,
e6d6e342 14870 const u8 *addr, gfp_t gfp)
1965c853
JM
14871{
14872 struct sk_buff *msg;
14873 void *hdr;
14874
e6d6e342 14875 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
1965c853
JM
14876 if (!msg)
14877 return;
14878
14879 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
14880 if (!hdr) {
14881 nlmsg_free(msg);
14882 return;
14883 }
14884
9360ffd1
DM
14885 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14886 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14887 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
14888 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
14889 goto nla_put_failure;
1965c853 14890
3b7b72ee 14891 genlmsg_end(msg, hdr);
1965c853 14892
68eb5503 14893 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14894 NL80211_MCGRP_MLME, gfp);
1965c853
JM
14895 return;
14896
14897 nla_put_failure:
1965c853
JM
14898 nlmsg_free(msg);
14899}
14900
14901void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14902 struct net_device *netdev, const u8 *addr,
14903 gfp_t gfp)
1965c853
JM
14904{
14905 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
e6d6e342 14906 addr, gfp);
1965c853
JM
14907}
14908
14909void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
e6d6e342
JB
14910 struct net_device *netdev, const u8 *addr,
14911 gfp_t gfp)
1965c853 14912{
e6d6e342
JB
14913 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
14914 addr, gfp);
1965c853
JM
14915}
14916
b23aa676 14917void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
5349a0f7
VK
14918 struct net_device *netdev,
14919 struct cfg80211_connect_resp_params *cr,
3093ebbe 14920 gfp_t gfp)
b23aa676
SO
14921{
14922 struct sk_buff *msg;
14923 void *hdr;
14924
a3caf744 14925 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
76804d28
AVS
14926 cr->fils.kek_len + cr->fils.pmk_len +
14927 (cr->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
14928 if (!msg)
14929 return;
14930
14931 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
14932 if (!hdr) {
14933 nlmsg_free(msg);
14934 return;
14935 }
14936
9360ffd1
DM
14937 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14938 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
5349a0f7
VK
14939 (cr->bssid &&
14940 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, cr->bssid)) ||
bf1ecd21 14941 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
5349a0f7
VK
14942 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
14943 cr->status) ||
14944 (cr->status < 0 &&
3093ebbe 14945 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
5349a0f7
VK
14946 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
14947 cr->timeout_reason))) ||
14948 (cr->req_ie &&
14949 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
14950 (cr->resp_ie &&
14951 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
a3caf744 14952 cr->resp_ie)) ||
76804d28 14953 (cr->fils.update_erp_next_seq_num &&
a3caf744 14954 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
76804d28 14955 cr->fils.erp_next_seq_num)) ||
a3caf744 14956 (cr->status == WLAN_STATUS_SUCCESS &&
76804d28
AVS
14957 ((cr->fils.kek &&
14958 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
14959 cr->fils.kek)) ||
14960 (cr->fils.pmk &&
14961 nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
14962 (cr->fils.pmkid &&
14963 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
9360ffd1 14964 goto nla_put_failure;
b23aa676 14965
3b7b72ee 14966 genlmsg_end(msg, hdr);
b23aa676 14967
68eb5503 14968 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 14969 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
14970 return;
14971
14972 nla_put_failure:
b23aa676 14973 nlmsg_free(msg);
b23aa676
SO
14974}
14975
14976void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
29ce6ecb
AS
14977 struct net_device *netdev,
14978 struct cfg80211_roam_info *info, gfp_t gfp)
b23aa676
SO
14979{
14980 struct sk_buff *msg;
14981 void *hdr;
29ce6ecb 14982 const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
b23aa676 14983
e841b7b1
AVS
14984 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
14985 info->fils.kek_len + info->fils.pmk_len +
14986 (info->fils.pmkid ? WLAN_PMKID_LEN : 0), gfp);
b23aa676
SO
14987 if (!msg)
14988 return;
14989
14990 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
14991 if (!hdr) {
14992 nlmsg_free(msg);
14993 return;
14994 }
14995
9360ffd1
DM
14996 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14997 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
14998 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
29ce6ecb
AS
14999 (info->req_ie &&
15000 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
15001 info->req_ie)) ||
15002 (info->resp_ie &&
15003 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
e841b7b1
AVS
15004 info->resp_ie)) ||
15005 (info->fils.update_erp_next_seq_num &&
15006 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
15007 info->fils.erp_next_seq_num)) ||
15008 (info->fils.kek &&
15009 nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
15010 info->fils.kek)) ||
15011 (info->fils.pmk &&
15012 nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
15013 (info->fils.pmkid &&
15014 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
9360ffd1 15015 goto nla_put_failure;
b23aa676 15016
3b7b72ee 15017 genlmsg_end(msg, hdr);
b23aa676 15018
68eb5503 15019 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15020 NL80211_MCGRP_MLME, gfp);
b23aa676
SO
15021 return;
15022
503c1fb9 15023 nla_put_failure:
503c1fb9
AS
15024 nlmsg_free(msg);
15025}
15026
15027void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
15028 struct net_device *netdev, const u8 *bssid)
15029{
15030 struct sk_buff *msg;
15031 void *hdr;
15032
15033 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15034 if (!msg)
15035 return;
15036
15037 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
15038 if (!hdr) {
15039 nlmsg_free(msg);
15040 return;
15041 }
15042
15043 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
15044 goto nla_put_failure;
15045
15046 genlmsg_end(msg, hdr);
15047
15048 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
15049 NL80211_MCGRP_MLME, GFP_KERNEL);
15050 return;
15051
b23aa676 15052 nla_put_failure:
b23aa676 15053 nlmsg_free(msg);
b23aa676
SO
15054}
15055
15056void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
15057 struct net_device *netdev, u16 reason,
667503dd 15058 const u8 *ie, size_t ie_len, bool from_ap)
b23aa676
SO
15059{
15060 struct sk_buff *msg;
15061 void *hdr;
15062
4ef8c1c9 15063 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
b23aa676
SO
15064 if (!msg)
15065 return;
15066
15067 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
15068 if (!hdr) {
15069 nlmsg_free(msg);
15070 return;
15071 }
15072
9360ffd1
DM
15073 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15074 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
86b6c465 15075 (reason &&
9360ffd1
DM
15076 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
15077 (from_ap &&
15078 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
15079 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
15080 goto nla_put_failure;
b23aa676 15081
3b7b72ee 15082 genlmsg_end(msg, hdr);
b23aa676 15083
68eb5503 15084 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15085 NL80211_MCGRP_MLME, GFP_KERNEL);
b23aa676
SO
15086 return;
15087
15088 nla_put_failure:
b23aa676 15089 nlmsg_free(msg);
b23aa676
SO
15090}
15091
04a773ad
JB
15092void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
15093 struct net_device *netdev, const u8 *bssid,
15094 gfp_t gfp)
15095{
15096 struct sk_buff *msg;
15097 void *hdr;
15098
fd2120ca 15099 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
04a773ad
JB
15100 if (!msg)
15101 return;
15102
15103 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
15104 if (!hdr) {
15105 nlmsg_free(msg);
15106 return;
15107 }
15108
9360ffd1
DM
15109 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15110 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15111 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
15112 goto nla_put_failure;
04a773ad 15113
3b7b72ee 15114 genlmsg_end(msg, hdr);
04a773ad 15115
68eb5503 15116 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15117 NL80211_MCGRP_MLME, gfp);
04a773ad
JB
15118 return;
15119
15120 nla_put_failure:
04a773ad
JB
15121 nlmsg_free(msg);
15122}
15123
947add36 15124void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
ecbc12ad
BC
15125 const u8 *ie, u8 ie_len,
15126 int sig_dbm, gfp_t gfp)
c93b5e71 15127{
947add36 15128 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15129 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
c93b5e71
JC
15130 struct sk_buff *msg;
15131 void *hdr;
15132
947add36
JB
15133 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
15134 return;
15135
15136 trace_cfg80211_notify_new_peer_candidate(dev, addr);
15137
4ef8c1c9 15138 msg = nlmsg_new(100 + ie_len, gfp);
c93b5e71
JC
15139 if (!msg)
15140 return;
15141
15142 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
15143 if (!hdr) {
15144 nlmsg_free(msg);
15145 return;
15146 }
15147
9360ffd1 15148 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36
JB
15149 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15150 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
9360ffd1 15151 (ie_len && ie &&
ecbc12ad
BC
15152 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
15153 (sig_dbm &&
15154 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
9360ffd1 15155 goto nla_put_failure;
c93b5e71 15156
3b7b72ee 15157 genlmsg_end(msg, hdr);
c93b5e71 15158
68eb5503 15159 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15160 NL80211_MCGRP_MLME, gfp);
c93b5e71
JC
15161 return;
15162
15163 nla_put_failure:
c93b5e71
JC
15164 nlmsg_free(msg);
15165}
947add36 15166EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
c93b5e71 15167
a3b8b056
JM
15168void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
15169 struct net_device *netdev, const u8 *addr,
15170 enum nl80211_key_type key_type, int key_id,
e6d6e342 15171 const u8 *tsc, gfp_t gfp)
a3b8b056
JM
15172{
15173 struct sk_buff *msg;
15174 void *hdr;
15175
e6d6e342 15176 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
a3b8b056
JM
15177 if (!msg)
15178 return;
15179
15180 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
15181 if (!hdr) {
15182 nlmsg_free(msg);
15183 return;
15184 }
15185
9360ffd1
DM
15186 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15187 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15188 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
15189 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
15190 (key_id != -1 &&
15191 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
15192 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
15193 goto nla_put_failure;
a3b8b056 15194
3b7b72ee 15195 genlmsg_end(msg, hdr);
a3b8b056 15196
68eb5503 15197 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15198 NL80211_MCGRP_MLME, gfp);
a3b8b056
JM
15199 return;
15200
15201 nla_put_failure:
a3b8b056
JM
15202 nlmsg_free(msg);
15203}
15204
6bad8766
LR
15205void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
15206 struct ieee80211_channel *channel_before,
15207 struct ieee80211_channel *channel_after)
15208{
15209 struct sk_buff *msg;
15210 void *hdr;
15211 struct nlattr *nl_freq;
15212
fd2120ca 15213 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
6bad8766
LR
15214 if (!msg)
15215 return;
15216
15217 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
15218 if (!hdr) {
15219 nlmsg_free(msg);
15220 return;
15221 }
15222
15223 /*
15224 * Since we are applying the beacon hint to a wiphy we know its
15225 * wiphy_idx is valid
15226 */
9360ffd1
DM
15227 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
15228 goto nla_put_failure;
6bad8766
LR
15229
15230 /* Before */
ae0be8de 15231 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_BEFORE);
6bad8766
LR
15232 if (!nl_freq)
15233 goto nla_put_failure;
50f32718
HD
15234
15235 if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
6bad8766
LR
15236 goto nla_put_failure;
15237 nla_nest_end(msg, nl_freq);
15238
15239 /* After */
ae0be8de 15240 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_AFTER);
6bad8766
LR
15241 if (!nl_freq)
15242 goto nla_put_failure;
50f32718
HD
15243
15244 if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
6bad8766
LR
15245 goto nla_put_failure;
15246 nla_nest_end(msg, nl_freq);
15247
3b7b72ee 15248 genlmsg_end(msg, hdr);
6bad8766 15249
463d0183 15250 rcu_read_lock();
68eb5503 15251 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
2a94fe48 15252 NL80211_MCGRP_REGULATORY, GFP_ATOMIC);
463d0183 15253 rcu_read_unlock();
6bad8766
LR
15254
15255 return;
15256
15257nla_put_failure:
6bad8766
LR
15258 nlmsg_free(msg);
15259}
15260
9588bbd5
JM
15261static void nl80211_send_remain_on_chan_event(
15262 int cmd, struct cfg80211_registered_device *rdev,
71bbc994 15263 struct wireless_dev *wdev, u64 cookie,
9588bbd5 15264 struct ieee80211_channel *chan,
9588bbd5
JM
15265 unsigned int duration, gfp_t gfp)
15266{
15267 struct sk_buff *msg;
15268 void *hdr;
15269
15270 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15271 if (!msg)
15272 return;
15273
15274 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
15275 if (!hdr) {
15276 nlmsg_free(msg);
15277 return;
15278 }
15279
9360ffd1 15280 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
15281 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15282 wdev->netdev->ifindex)) ||
2dad624e
ND
15283 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15284 NL80211_ATTR_PAD) ||
9360ffd1 15285 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
42d97a59
JB
15286 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
15287 NL80211_CHAN_NO_HT) ||
2dad624e
ND
15288 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
15289 NL80211_ATTR_PAD))
9360ffd1 15290 goto nla_put_failure;
9588bbd5 15291
9360ffd1
DM
15292 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
15293 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
15294 goto nla_put_failure;
9588bbd5 15295
3b7b72ee 15296 genlmsg_end(msg, hdr);
9588bbd5 15297
68eb5503 15298 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15299 NL80211_MCGRP_MLME, gfp);
9588bbd5
JM
15300 return;
15301
15302 nla_put_failure:
9588bbd5
JM
15303 nlmsg_free(msg);
15304}
15305
947add36
JB
15306void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
15307 struct ieee80211_channel *chan,
15308 unsigned int duration, gfp_t gfp)
9588bbd5 15309{
947add36 15310 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15311 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15312
15313 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
9588bbd5 15314 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
71bbc994 15315 rdev, wdev, cookie, chan,
42d97a59 15316 duration, gfp);
9588bbd5 15317}
947add36 15318EXPORT_SYMBOL(cfg80211_ready_on_channel);
9588bbd5 15319
947add36
JB
15320void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
15321 struct ieee80211_channel *chan,
15322 gfp_t gfp)
9588bbd5 15323{
947add36 15324 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15325 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15326
15327 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
9588bbd5 15328 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
42d97a59 15329 rdev, wdev, cookie, chan, 0, gfp);
9588bbd5 15330}
947add36 15331EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
9588bbd5 15332
947add36
JB
15333void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
15334 struct station_info *sinfo, gfp_t gfp)
98b62183 15335{
947add36 15336 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 15337 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
98b62183
JB
15338 struct sk_buff *msg;
15339
947add36
JB
15340 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
15341
58050fce 15342 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
98b62183
JB
15343 if (!msg)
15344 return;
15345
cf5ead82 15346 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
66266b3a 15347 rdev, dev, mac_addr, sinfo) < 0) {
98b62183
JB
15348 nlmsg_free(msg);
15349 return;
15350 }
15351
68eb5503 15352 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15353 NL80211_MCGRP_MLME, gfp);
98b62183 15354}
947add36 15355EXPORT_SYMBOL(cfg80211_new_sta);
98b62183 15356
cf5ead82
JB
15357void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
15358 struct station_info *sinfo, gfp_t gfp)
ec15e68b 15359{
947add36 15360 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 15361 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ec15e68b 15362 struct sk_buff *msg;
73887fd9 15363 struct station_info empty_sinfo = {};
cf5ead82 15364
73887fd9
JB
15365 if (!sinfo)
15366 sinfo = &empty_sinfo;
ec15e68b 15367
947add36
JB
15368 trace_cfg80211_del_sta(dev, mac_addr);
15369
58050fce 15370 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
7ea3e110
JB
15371 if (!msg) {
15372 cfg80211_sinfo_release_content(sinfo);
73887fd9 15373 return;
7ea3e110 15374 }
ec15e68b 15375
cf5ead82 15376 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
57007121 15377 rdev, dev, mac_addr, sinfo) < 0) {
ec15e68b 15378 nlmsg_free(msg);
73887fd9 15379 return;
ec15e68b
JM
15380 }
15381
68eb5503 15382 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15383 NL80211_MCGRP_MLME, gfp);
ec15e68b 15384}
cf5ead82 15385EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
ec15e68b 15386
947add36
JB
15387void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
15388 enum nl80211_connect_failed_reason reason,
15389 gfp_t gfp)
ed44a951 15390{
947add36 15391 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
f26cbf40 15392 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
ed44a951
PP
15393 struct sk_buff *msg;
15394 void *hdr;
15395
15396 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
15397 if (!msg)
15398 return;
15399
15400 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
15401 if (!hdr) {
15402 nlmsg_free(msg);
15403 return;
15404 }
15405
15406 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15407 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
15408 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
15409 goto nla_put_failure;
15410
15411 genlmsg_end(msg, hdr);
15412
68eb5503 15413 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15414 NL80211_MCGRP_MLME, gfp);
ed44a951
PP
15415 return;
15416
15417 nla_put_failure:
ed44a951
PP
15418 nlmsg_free(msg);
15419}
947add36 15420EXPORT_SYMBOL(cfg80211_conn_failed);
ed44a951 15421
b92ab5d8
JB
15422static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
15423 const u8 *addr, gfp_t gfp)
28946da7
JB
15424{
15425 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 15426 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
28946da7
JB
15427 struct sk_buff *msg;
15428 void *hdr;
6aa7de05 15429 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
28946da7 15430
15e47304 15431 if (!nlportid)
28946da7
JB
15432 return false;
15433
15434 msg = nlmsg_new(100, gfp);
15435 if (!msg)
15436 return true;
15437
b92ab5d8 15438 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
28946da7
JB
15439 if (!hdr) {
15440 nlmsg_free(msg);
15441 return true;
15442 }
15443
9360ffd1
DM
15444 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15445 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15446 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
15447 goto nla_put_failure;
28946da7 15448
9c90a9f6 15449 genlmsg_end(msg, hdr);
15e47304 15450 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
28946da7
JB
15451 return true;
15452
15453 nla_put_failure:
28946da7
JB
15454 nlmsg_free(msg);
15455 return true;
15456}
15457
947add36
JB
15458bool cfg80211_rx_spurious_frame(struct net_device *dev,
15459 const u8 *addr, gfp_t gfp)
b92ab5d8 15460{
947add36
JB
15461 struct wireless_dev *wdev = dev->ieee80211_ptr;
15462 bool ret;
15463
15464 trace_cfg80211_rx_spurious_frame(dev, addr);
15465
15466 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
15467 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
15468 trace_cfg80211_return_bool(false);
15469 return false;
15470 }
15471 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
15472 addr, gfp);
15473 trace_cfg80211_return_bool(ret);
15474 return ret;
b92ab5d8 15475}
947add36 15476EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
b92ab5d8 15477
947add36
JB
15478bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
15479 const u8 *addr, gfp_t gfp)
b92ab5d8 15480{
947add36
JB
15481 struct wireless_dev *wdev = dev->ieee80211_ptr;
15482 bool ret;
15483
15484 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
15485
15486 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
15487 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
15488 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
15489 trace_cfg80211_return_bool(false);
15490 return false;
15491 }
15492 ret = __nl80211_unexpected_frame(dev,
15493 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
15494 addr, gfp);
15495 trace_cfg80211_return_bool(ret);
15496 return ret;
b92ab5d8 15497}
947add36 15498EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
b92ab5d8 15499
2e161f78 15500int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
15e47304 15501 struct wireless_dev *wdev, u32 nlportid,
804483e9 15502 int freq, int sig_dbm,
19504cf5 15503 const u8 *buf, size_t len, u32 flags, gfp_t gfp)
026331c4 15504{
71bbc994 15505 struct net_device *netdev = wdev->netdev;
026331c4
JM
15506 struct sk_buff *msg;
15507 void *hdr;
026331c4 15508
4ef8c1c9 15509 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
15510 if (!msg)
15511 return -ENOMEM;
15512
2e161f78 15513 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
026331c4
JM
15514 if (!hdr) {
15515 nlmsg_free(msg);
15516 return -ENOMEM;
15517 }
15518
9360ffd1 15519 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
15520 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15521 netdev->ifindex)) ||
2dad624e
ND
15522 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15523 NL80211_ATTR_PAD) ||
9360ffd1
DM
15524 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) ||
15525 (sig_dbm &&
15526 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19504cf5
VK
15527 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
15528 (flags &&
15529 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, flags)))
9360ffd1 15530 goto nla_put_failure;
026331c4 15531
3b7b72ee 15532 genlmsg_end(msg, hdr);
026331c4 15533
15e47304 15534 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
026331c4
JM
15535
15536 nla_put_failure:
026331c4
JM
15537 nlmsg_free(msg);
15538 return -ENOBUFS;
15539}
15540
947add36
JB
15541void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
15542 const u8 *buf, size_t len, bool ack, gfp_t gfp)
026331c4 15543{
947add36 15544 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15545 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
71bbc994 15546 struct net_device *netdev = wdev->netdev;
026331c4
JM
15547 struct sk_buff *msg;
15548 void *hdr;
15549
947add36
JB
15550 trace_cfg80211_mgmt_tx_status(wdev, cookie, ack);
15551
4ef8c1c9 15552 msg = nlmsg_new(100 + len, gfp);
026331c4
JM
15553 if (!msg)
15554 return;
15555
2e161f78 15556 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS);
026331c4
JM
15557 if (!hdr) {
15558 nlmsg_free(msg);
15559 return;
15560 }
15561
9360ffd1 15562 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
71bbc994
JB
15563 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
15564 netdev->ifindex)) ||
2dad624e
ND
15565 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15566 NL80211_ATTR_PAD) ||
9360ffd1 15567 nla_put(msg, NL80211_ATTR_FRAME, len, buf) ||
2dad624e
ND
15568 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
15569 NL80211_ATTR_PAD) ||
9360ffd1
DM
15570 (ack && nla_put_flag(msg, NL80211_ATTR_ACK)))
15571 goto nla_put_failure;
026331c4 15572
3b7b72ee 15573 genlmsg_end(msg, hdr);
026331c4 15574
68eb5503 15575 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15576 NL80211_MCGRP_MLME, gfp);
026331c4
JM
15577 return;
15578
15579 nla_put_failure:
026331c4
JM
15580 nlmsg_free(msg);
15581}
947add36 15582EXPORT_SYMBOL(cfg80211_mgmt_tx_status);
026331c4 15583
6a671a50 15584static int __nl80211_rx_control_port(struct net_device *dev,
a948f713 15585 struct sk_buff *skb,
6a671a50
DK
15586 bool unencrypted, gfp_t gfp)
15587{
15588 struct wireless_dev *wdev = dev->ieee80211_ptr;
15589 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
a948f713
DK
15590 struct ethhdr *ehdr = eth_hdr(skb);
15591 const u8 *addr = ehdr->h_source;
15592 u16 proto = be16_to_cpu(skb->protocol);
6a671a50
DK
15593 struct sk_buff *msg;
15594 void *hdr;
a948f713
DK
15595 struct nlattr *frame;
15596
6a671a50
DK
15597 u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
15598
15599 if (!nlportid)
15600 return -ENOENT;
15601
a948f713 15602 msg = nlmsg_new(100 + skb->len, gfp);
6a671a50
DK
15603 if (!msg)
15604 return -ENOMEM;
15605
15606 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
15607 if (!hdr) {
15608 nlmsg_free(msg);
15609 return -ENOBUFS;
15610 }
15611
15612 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15613 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
15614 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
15615 NL80211_ATTR_PAD) ||
6a671a50
DK
15616 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
15617 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
15618 (unencrypted && nla_put_flag(msg,
15619 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
15620 goto nla_put_failure;
15621
a948f713
DK
15622 frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
15623 if (!frame)
15624 goto nla_put_failure;
15625
15626 skb_copy_bits(skb, 0, nla_data(frame), skb->len);
6a671a50
DK
15627 genlmsg_end(msg, hdr);
15628
15629 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
15630
15631 nla_put_failure:
15632 nlmsg_free(msg);
15633 return -ENOBUFS;
15634}
15635
15636bool cfg80211_rx_control_port(struct net_device *dev,
a948f713 15637 struct sk_buff *skb, bool unencrypted)
6a671a50
DK
15638{
15639 int ret;
15640
a948f713
DK
15641 trace_cfg80211_rx_control_port(dev, skb, unencrypted);
15642 ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC);
6a671a50
DK
15643 trace_cfg80211_return_bool(ret == 0);
15644 return ret == 0;
15645}
15646EXPORT_SYMBOL(cfg80211_rx_control_port);
15647
5b97f49d
JB
15648static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
15649 const char *mac, gfp_t gfp)
d6dc1a38 15650{
947add36 15651 struct wireless_dev *wdev = dev->ieee80211_ptr;
5b97f49d
JB
15652 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
15653 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
15654 void **cb;
947add36 15655
d6dc1a38 15656 if (!msg)
5b97f49d 15657 return NULL;
d6dc1a38 15658
5b97f49d
JB
15659 cb = (void **)msg->cb;
15660
15661 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
15662 if (!cb[0]) {
d6dc1a38 15663 nlmsg_free(msg);
5b97f49d 15664 return NULL;
d6dc1a38
JO
15665 }
15666
9360ffd1 15667 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
947add36 15668 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
9360ffd1 15669 goto nla_put_failure;
d6dc1a38 15670
5b97f49d 15671 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
d6dc1a38
JO
15672 goto nla_put_failure;
15673
ae0be8de 15674 cb[1] = nla_nest_start_noflag(msg, NL80211_ATTR_CQM);
5b97f49d 15675 if (!cb[1])
9360ffd1 15676 goto nla_put_failure;
d6dc1a38 15677
5b97f49d 15678 cb[2] = rdev;
d6dc1a38 15679
5b97f49d
JB
15680 return msg;
15681 nla_put_failure:
15682 nlmsg_free(msg);
15683 return NULL;
15684}
15685
15686static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
15687{
15688 void **cb = (void **)msg->cb;
15689 struct cfg80211_registered_device *rdev = cb[2];
15690
15691 nla_nest_end(msg, cb[1]);
15692 genlmsg_end(msg, cb[0]);
15693
15694 memset(msg->cb, 0, sizeof(msg->cb));
d6dc1a38 15695
68eb5503 15696 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15697 NL80211_MCGRP_MLME, gfp);
5b97f49d
JB
15698}
15699
15700void cfg80211_cqm_rssi_notify(struct net_device *dev,
15701 enum nl80211_cqm_rssi_threshold_event rssi_event,
bee427b8 15702 s32 rssi_level, gfp_t gfp)
5b97f49d
JB
15703{
15704 struct sk_buff *msg;
4a4b8169
AZ
15705 struct wireless_dev *wdev = dev->ieee80211_ptr;
15706 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
5b97f49d 15707
bee427b8 15708 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
5b97f49d 15709
98f03342
JB
15710 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
15711 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
15712 return;
15713
4a4b8169
AZ
15714 if (wdev->cqm_config) {
15715 wdev->cqm_config->last_rssi_event_value = rssi_level;
15716
15717 cfg80211_cqm_rssi_update(rdev, dev);
15718
15719 if (rssi_level == 0)
15720 rssi_level = wdev->cqm_config->last_rssi_event_value;
15721 }
15722
5b97f49d
JB
15723 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
15724 if (!msg)
15725 return;
15726
15727 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
15728 rssi_event))
15729 goto nla_put_failure;
15730
bee427b8
AZ
15731 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
15732 rssi_level))
15733 goto nla_put_failure;
15734
5b97f49d
JB
15735 cfg80211_send_cqm(msg, gfp);
15736
d6dc1a38
JO
15737 return;
15738
15739 nla_put_failure:
d6dc1a38
JO
15740 nlmsg_free(msg);
15741}
947add36 15742EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
d6dc1a38 15743
5b97f49d
JB
15744void cfg80211_cqm_txe_notify(struct net_device *dev,
15745 const u8 *peer, u32 num_packets,
15746 u32 rate, u32 intvl, gfp_t gfp)
15747{
15748 struct sk_buff *msg;
15749
15750 msg = cfg80211_prepare_cqm(dev, peer, gfp);
15751 if (!msg)
15752 return;
15753
15754 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
15755 goto nla_put_failure;
15756
15757 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
15758 goto nla_put_failure;
15759
15760 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
15761 goto nla_put_failure;
15762
15763 cfg80211_send_cqm(msg, gfp);
15764 return;
15765
15766 nla_put_failure:
15767 nlmsg_free(msg);
15768}
15769EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
15770
15771void cfg80211_cqm_pktloss_notify(struct net_device *dev,
15772 const u8 *peer, u32 num_packets, gfp_t gfp)
15773{
15774 struct sk_buff *msg;
15775
15776 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
15777
15778 msg = cfg80211_prepare_cqm(dev, peer, gfp);
15779 if (!msg)
15780 return;
15781
15782 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
15783 goto nla_put_failure;
15784
15785 cfg80211_send_cqm(msg, gfp);
15786 return;
15787
15788 nla_put_failure:
15789 nlmsg_free(msg);
15790}
15791EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
15792
98f03342
JB
15793void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
15794{
15795 struct sk_buff *msg;
15796
15797 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
15798 if (!msg)
15799 return;
15800
15801 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
15802 goto nla_put_failure;
15803
15804 cfg80211_send_cqm(msg, gfp);
15805 return;
15806
15807 nla_put_failure:
15808 nlmsg_free(msg);
15809}
15810EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
15811
947add36
JB
15812static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
15813 struct net_device *netdev, const u8 *bssid,
15814 const u8 *replay_ctr, gfp_t gfp)
e5497d76
JB
15815{
15816 struct sk_buff *msg;
15817 struct nlattr *rekey_attr;
15818 void *hdr;
15819
58050fce 15820 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
e5497d76
JB
15821 if (!msg)
15822 return;
15823
15824 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
15825 if (!hdr) {
15826 nlmsg_free(msg);
15827 return;
15828 }
15829
9360ffd1
DM
15830 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15831 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
15832 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
15833 goto nla_put_failure;
e5497d76 15834
ae0be8de 15835 rekey_attr = nla_nest_start_noflag(msg, NL80211_ATTR_REKEY_DATA);
e5497d76
JB
15836 if (!rekey_attr)
15837 goto nla_put_failure;
15838
9360ffd1
DM
15839 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
15840 NL80211_REPLAY_CTR_LEN, replay_ctr))
15841 goto nla_put_failure;
e5497d76
JB
15842
15843 nla_nest_end(msg, rekey_attr);
15844
3b7b72ee 15845 genlmsg_end(msg, hdr);
e5497d76 15846
68eb5503 15847 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15848 NL80211_MCGRP_MLME, gfp);
e5497d76
JB
15849 return;
15850
15851 nla_put_failure:
e5497d76
JB
15852 nlmsg_free(msg);
15853}
15854
947add36
JB
15855void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
15856 const u8 *replay_ctr, gfp_t gfp)
15857{
15858 struct wireless_dev *wdev = dev->ieee80211_ptr;
15859 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15860 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15861
15862 trace_cfg80211_gtk_rekey_notify(dev, bssid);
15863 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
15864}
15865EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
15866
15867static void
15868nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
15869 struct net_device *netdev, int index,
15870 const u8 *bssid, bool preauth, gfp_t gfp)
c9df56b4
JM
15871{
15872 struct sk_buff *msg;
15873 struct nlattr *attr;
15874 void *hdr;
15875
58050fce 15876 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
c9df56b4
JM
15877 if (!msg)
15878 return;
15879
15880 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
15881 if (!hdr) {
15882 nlmsg_free(msg);
15883 return;
15884 }
15885
9360ffd1
DM
15886 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15887 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
15888 goto nla_put_failure;
c9df56b4 15889
ae0be8de 15890 attr = nla_nest_start_noflag(msg, NL80211_ATTR_PMKSA_CANDIDATE);
c9df56b4
JM
15891 if (!attr)
15892 goto nla_put_failure;
15893
9360ffd1
DM
15894 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
15895 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
15896 (preauth &&
15897 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
15898 goto nla_put_failure;
c9df56b4
JM
15899
15900 nla_nest_end(msg, attr);
15901
3b7b72ee 15902 genlmsg_end(msg, hdr);
c9df56b4 15903
68eb5503 15904 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15905 NL80211_MCGRP_MLME, gfp);
c9df56b4
JM
15906 return;
15907
15908 nla_put_failure:
c9df56b4
JM
15909 nlmsg_free(msg);
15910}
15911
947add36
JB
15912void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
15913 const u8 *bssid, bool preauth, gfp_t gfp)
15914{
15915 struct wireless_dev *wdev = dev->ieee80211_ptr;
15916 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15917 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36
JB
15918
15919 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
15920 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
15921}
15922EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
15923
15924static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
15925 struct net_device *netdev,
15926 struct cfg80211_chan_def *chandef,
f8d7552e
LC
15927 gfp_t gfp,
15928 enum nl80211_commands notif,
15929 u8 count)
5314526b
TP
15930{
15931 struct sk_buff *msg;
15932 void *hdr;
15933
58050fce 15934 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
5314526b
TP
15935 if (!msg)
15936 return;
15937
f8d7552e 15938 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
5314526b
TP
15939 if (!hdr) {
15940 nlmsg_free(msg);
15941 return;
15942 }
15943
683b6d3b
JB
15944 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
15945 goto nla_put_failure;
15946
15947 if (nl80211_send_chandef(msg, chandef))
7eab0f64 15948 goto nla_put_failure;
5314526b 15949
f8d7552e
LC
15950 if ((notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) &&
15951 (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count)))
15952 goto nla_put_failure;
15953
5314526b
TP
15954 genlmsg_end(msg, hdr);
15955
68eb5503 15956 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 15957 NL80211_MCGRP_MLME, gfp);
5314526b
TP
15958 return;
15959
15960 nla_put_failure:
5314526b
TP
15961 nlmsg_free(msg);
15962}
15963
947add36
JB
15964void cfg80211_ch_switch_notify(struct net_device *dev,
15965 struct cfg80211_chan_def *chandef)
84f10708 15966{
947add36
JB
15967 struct wireless_dev *wdev = dev->ieee80211_ptr;
15968 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 15969 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
947add36 15970
e487eaeb 15971 ASSERT_WDEV_LOCK(wdev);
947add36 15972
e487eaeb 15973 trace_cfg80211_ch_switch_notify(dev, chandef);
947add36 15974
9e0e2961 15975 wdev->chandef = *chandef;
96f55f12 15976 wdev->preset_chandef = *chandef;
5dc8cdce
SM
15977
15978 if (wdev->iftype == NL80211_IFTYPE_STATION &&
15979 !WARN_ON(!wdev->current_bss))
15980 wdev->current_bss->pub.channel = chandef->chan;
15981
f8d7552e
LC
15982 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
15983 NL80211_CMD_CH_SWITCH_NOTIFY, 0);
947add36
JB
15984}
15985EXPORT_SYMBOL(cfg80211_ch_switch_notify);
15986
f8d7552e
LC
15987void cfg80211_ch_switch_started_notify(struct net_device *dev,
15988 struct cfg80211_chan_def *chandef,
15989 u8 count)
15990{
15991 struct wireless_dev *wdev = dev->ieee80211_ptr;
15992 struct wiphy *wiphy = wdev->wiphy;
15993 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
15994
15995 trace_cfg80211_ch_switch_started_notify(dev, chandef);
15996
15997 nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL,
15998 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, count);
15999}
16000EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
16001
04f39047
SW
16002void
16003nl80211_radar_notify(struct cfg80211_registered_device *rdev,
d2859df5 16004 const struct cfg80211_chan_def *chandef,
04f39047
SW
16005 enum nl80211_radar_event event,
16006 struct net_device *netdev, gfp_t gfp)
16007{
16008 struct sk_buff *msg;
16009 void *hdr;
16010
16011 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16012 if (!msg)
16013 return;
16014
16015 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
16016 if (!hdr) {
16017 nlmsg_free(msg);
16018 return;
16019 }
16020
16021 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
16022 goto nla_put_failure;
16023
16024 /* NOP and radar events don't need a netdev parameter */
16025 if (netdev) {
16026 struct wireless_dev *wdev = netdev->ieee80211_ptr;
16027
16028 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
2dad624e
ND
16029 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16030 NL80211_ATTR_PAD))
04f39047
SW
16031 goto nla_put_failure;
16032 }
16033
16034 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
16035 goto nla_put_failure;
16036
16037 if (nl80211_send_chandef(msg, chandef))
16038 goto nla_put_failure;
16039
9c90a9f6 16040 genlmsg_end(msg, hdr);
04f39047 16041
68eb5503 16042 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16043 NL80211_MCGRP_MLME, gfp);
04f39047
SW
16044 return;
16045
16046 nla_put_failure:
04f39047
SW
16047 nlmsg_free(msg);
16048}
16049
466b9936 16050void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
16051 struct sta_opmode_info *sta_opmode,
16052 gfp_t gfp)
16053{
16054 struct sk_buff *msg;
16055 struct wireless_dev *wdev = dev->ieee80211_ptr;
16056 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
16057 void *hdr;
16058
16059 if (WARN_ON(!mac))
16060 return;
16061
16062 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16063 if (!msg)
16064 return;
16065
16066 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
16067 if (!hdr) {
16068 nlmsg_free(msg);
16069 return;
16070 }
16071
16072 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
16073 goto nla_put_failure;
16074
16075 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
16076 goto nla_put_failure;
16077
16078 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
16079 goto nla_put_failure;
16080
16081 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
16082 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
16083 goto nla_put_failure;
16084
16085 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
16086 nla_put_u8(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
16087 goto nla_put_failure;
16088
16089 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
16090 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
16091 goto nla_put_failure;
16092
16093 genlmsg_end(msg, hdr);
16094
16095 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16096 NL80211_MCGRP_MLME, gfp);
16097
16098 return;
16099
16100nla_put_failure:
16101 nlmsg_free(msg);
16102}
16103EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
16104
7f6cf311 16105void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
c4b50cd3
VN
16106 u64 cookie, bool acked, s32 ack_signal,
16107 bool is_valid_ack_signal, gfp_t gfp)
7f6cf311
JB
16108{
16109 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16110 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
7f6cf311
JB
16111 struct sk_buff *msg;
16112 void *hdr;
7f6cf311 16113
4ee3e063
BL
16114 trace_cfg80211_probe_status(dev, addr, cookie, acked);
16115
58050fce 16116 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
4ee3e063 16117
7f6cf311
JB
16118 if (!msg)
16119 return;
16120
16121 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
16122 if (!hdr) {
16123 nlmsg_free(msg);
16124 return;
16125 }
16126
9360ffd1
DM
16127 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16128 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16129 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
2dad624e
ND
16130 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
16131 NL80211_ATTR_PAD) ||
c4b50cd3
VN
16132 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
16133 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
16134 ack_signal)))
9360ffd1 16135 goto nla_put_failure;
7f6cf311 16136
9c90a9f6 16137 genlmsg_end(msg, hdr);
7f6cf311 16138
68eb5503 16139 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16140 NL80211_MCGRP_MLME, gfp);
7f6cf311
JB
16141 return;
16142
16143 nla_put_failure:
7f6cf311
JB
16144 nlmsg_free(msg);
16145}
16146EXPORT_SYMBOL(cfg80211_probe_status);
16147
5e760230
JB
16148void cfg80211_report_obss_beacon(struct wiphy *wiphy,
16149 const u8 *frame, size_t len,
37c73b5f 16150 int freq, int sig_dbm)
5e760230 16151{
f26cbf40 16152 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
5e760230
JB
16153 struct sk_buff *msg;
16154 void *hdr;
37c73b5f 16155 struct cfg80211_beacon_registration *reg;
5e760230 16156
4ee3e063
BL
16157 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
16158
37c73b5f
BG
16159 spin_lock_bh(&rdev->beacon_registrations_lock);
16160 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
16161 msg = nlmsg_new(len + 100, GFP_ATOMIC);
16162 if (!msg) {
16163 spin_unlock_bh(&rdev->beacon_registrations_lock);
16164 return;
16165 }
5e760230 16166
37c73b5f
BG
16167 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
16168 if (!hdr)
16169 goto nla_put_failure;
5e760230 16170
37c73b5f
BG
16171 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16172 (freq &&
16173 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) ||
16174 (sig_dbm &&
16175 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
16176 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
16177 goto nla_put_failure;
5e760230 16178
37c73b5f 16179 genlmsg_end(msg, hdr);
5e760230 16180
37c73b5f
BG
16181 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
16182 }
16183 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
16184 return;
16185
16186 nla_put_failure:
37c73b5f 16187 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230
JB
16188 nlmsg_free(msg);
16189}
16190EXPORT_SYMBOL(cfg80211_report_obss_beacon);
16191
cd8f7cb4 16192#ifdef CONFIG_PM
8cd4d456
LC
16193static int cfg80211_net_detect_results(struct sk_buff *msg,
16194 struct cfg80211_wowlan_wakeup *wakeup)
16195{
16196 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
16197 struct nlattr *nl_results, *nl_match, *nl_freqs;
16198 int i, j;
16199
ae0be8de
MK
16200 nl_results = nla_nest_start_noflag(msg,
16201 NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
8cd4d456
LC
16202 if (!nl_results)
16203 return -EMSGSIZE;
16204
16205 for (i = 0; i < nd->n_matches; i++) {
16206 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
16207
ae0be8de 16208 nl_match = nla_nest_start_noflag(msg, i);
8cd4d456
LC
16209 if (!nl_match)
16210 break;
16211
16212 /* The SSID attribute is optional in nl80211, but for
16213 * simplicity reasons it's always present in the
16214 * cfg80211 structure. If a driver can't pass the
16215 * SSID, that needs to be changed. A zero length SSID
16216 * is still a valid SSID (wildcard), so it cannot be
16217 * used for this purpose.
16218 */
16219 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
16220 match->ssid.ssid)) {
16221 nla_nest_cancel(msg, nl_match);
16222 goto out;
16223 }
16224
16225 if (match->n_channels) {
ae0be8de
MK
16226 nl_freqs = nla_nest_start_noflag(msg,
16227 NL80211_ATTR_SCAN_FREQUENCIES);
8cd4d456
LC
16228 if (!nl_freqs) {
16229 nla_nest_cancel(msg, nl_match);
16230 goto out;
16231 }
16232
16233 for (j = 0; j < match->n_channels; j++) {
5528fae8 16234 if (nla_put_u32(msg, j, match->channels[j])) {
8cd4d456
LC
16235 nla_nest_cancel(msg, nl_freqs);
16236 nla_nest_cancel(msg, nl_match);
16237 goto out;
16238 }
16239 }
16240
16241 nla_nest_end(msg, nl_freqs);
16242 }
16243
16244 nla_nest_end(msg, nl_match);
16245 }
16246
16247out:
16248 nla_nest_end(msg, nl_results);
16249 return 0;
16250}
16251
cd8f7cb4
JB
16252void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
16253 struct cfg80211_wowlan_wakeup *wakeup,
16254 gfp_t gfp)
16255{
f26cbf40 16256 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
cd8f7cb4
JB
16257 struct sk_buff *msg;
16258 void *hdr;
9c90a9f6 16259 int size = 200;
cd8f7cb4
JB
16260
16261 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
16262
16263 if (wakeup)
16264 size += wakeup->packet_present_len;
16265
16266 msg = nlmsg_new(size, gfp);
16267 if (!msg)
16268 return;
16269
16270 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
16271 if (!hdr)
16272 goto free_msg;
16273
16274 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
16275 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16276 NL80211_ATTR_PAD))
cd8f7cb4
JB
16277 goto free_msg;
16278
16279 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
16280 wdev->netdev->ifindex))
16281 goto free_msg;
16282
16283 if (wakeup) {
16284 struct nlattr *reasons;
16285
ae0be8de
MK
16286 reasons = nla_nest_start_noflag(msg,
16287 NL80211_ATTR_WOWLAN_TRIGGERS);
7fa322c8
JB
16288 if (!reasons)
16289 goto free_msg;
cd8f7cb4
JB
16290
16291 if (wakeup->disconnect &&
16292 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
16293 goto free_msg;
16294 if (wakeup->magic_pkt &&
16295 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
16296 goto free_msg;
16297 if (wakeup->gtk_rekey_failure &&
16298 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
16299 goto free_msg;
16300 if (wakeup->eap_identity_req &&
16301 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
16302 goto free_msg;
16303 if (wakeup->four_way_handshake &&
16304 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
16305 goto free_msg;
16306 if (wakeup->rfkill_release &&
16307 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
16308 goto free_msg;
16309
16310 if (wakeup->pattern_idx >= 0 &&
16311 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
16312 wakeup->pattern_idx))
16313 goto free_msg;
16314
ae917c9f
JB
16315 if (wakeup->tcp_match &&
16316 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
16317 goto free_msg;
2a0e047e 16318
ae917c9f
JB
16319 if (wakeup->tcp_connlost &&
16320 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
16321 goto free_msg;
2a0e047e 16322
ae917c9f
JB
16323 if (wakeup->tcp_nomoretokens &&
16324 nla_put_flag(msg,
16325 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
16326 goto free_msg;
2a0e047e 16327
cd8f7cb4
JB
16328 if (wakeup->packet) {
16329 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
16330 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
16331
16332 if (!wakeup->packet_80211) {
16333 pkt_attr =
16334 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
16335 len_attr =
16336 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
16337 }
16338
16339 if (wakeup->packet_len &&
16340 nla_put_u32(msg, len_attr, wakeup->packet_len))
16341 goto free_msg;
16342
16343 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
16344 wakeup->packet))
16345 goto free_msg;
16346 }
16347
8cd4d456
LC
16348 if (wakeup->net_detect &&
16349 cfg80211_net_detect_results(msg, wakeup))
16350 goto free_msg;
16351
cd8f7cb4
JB
16352 nla_nest_end(msg, reasons);
16353 }
16354
9c90a9f6 16355 genlmsg_end(msg, hdr);
cd8f7cb4 16356
68eb5503 16357 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16358 NL80211_MCGRP_MLME, gfp);
cd8f7cb4
JB
16359 return;
16360
16361 free_msg:
16362 nlmsg_free(msg);
16363}
16364EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
16365#endif
16366
3475b094
JM
16367void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
16368 enum nl80211_tdls_operation oper,
16369 u16 reason_code, gfp_t gfp)
16370{
16371 struct wireless_dev *wdev = dev->ieee80211_ptr;
f26cbf40 16372 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
3475b094
JM
16373 struct sk_buff *msg;
16374 void *hdr;
3475b094
JM
16375
16376 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
16377 reason_code);
16378
16379 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16380 if (!msg)
16381 return;
16382
16383 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
16384 if (!hdr) {
16385 nlmsg_free(msg);
16386 return;
16387 }
16388
16389 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16390 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16391 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
16392 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
16393 (reason_code > 0 &&
16394 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
16395 goto nla_put_failure;
16396
9c90a9f6 16397 genlmsg_end(msg, hdr);
3475b094 16398
68eb5503 16399 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16400 NL80211_MCGRP_MLME, gfp);
3475b094
JM
16401 return;
16402
16403 nla_put_failure:
3475b094
JM
16404 nlmsg_free(msg);
16405}
16406EXPORT_SYMBOL(cfg80211_tdls_oper_request);
16407
026331c4
JM
16408static int nl80211_netlink_notify(struct notifier_block * nb,
16409 unsigned long state,
16410 void *_notify)
16411{
16412 struct netlink_notify *notify = _notify;
16413 struct cfg80211_registered_device *rdev;
16414 struct wireless_dev *wdev;
37c73b5f 16415 struct cfg80211_beacon_registration *reg, *tmp;
026331c4 16416
8f815cdd 16417 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
026331c4
JM
16418 return NOTIFY_DONE;
16419
16420 rcu_read_lock();
16421
5e760230 16422 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
ca986ad9 16423 struct cfg80211_sched_scan_request *sched_scan_req;
753aacfd 16424
ca986ad9
AVS
16425 list_for_each_entry_rcu(sched_scan_req,
16426 &rdev->sched_scan_req_list,
16427 list) {
16428 if (sched_scan_req->owner_nlportid == notify->portid) {
16429 sched_scan_req->nl_owner_dead = true;
753aacfd 16430 schedule_work(&rdev->sched_scan_stop_wk);
ca986ad9 16431 }
753aacfd 16432 }
78f22b6a 16433
53873f13 16434 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
15e47304 16435 cfg80211_mlme_unregister_socket(wdev, notify->portid);
37c73b5f 16436
ab81007a
JB
16437 if (wdev->owner_nlportid == notify->portid) {
16438 wdev->nl_owner_dead = true;
16439 schedule_work(&rdev->destroy_work);
16440 } else if (wdev->conn_owner_nlportid == notify->portid) {
bd2522b1 16441 schedule_work(&wdev->disconnect_wk);
ab81007a 16442 }
9bb7e0f2
JB
16443
16444 cfg80211_release_pmsr(wdev, notify->portid);
78f22b6a
JB
16445 }
16446
37c73b5f
BG
16447 spin_lock_bh(&rdev->beacon_registrations_lock);
16448 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
16449 list) {
16450 if (reg->nlportid == notify->portid) {
16451 list_del(&reg->list);
16452 kfree(reg);
16453 break;
16454 }
16455 }
16456 spin_unlock_bh(&rdev->beacon_registrations_lock);
5e760230 16457 }
026331c4
JM
16458
16459 rcu_read_unlock();
16460
05050753
I
16461 /*
16462 * It is possible that the user space process that is controlling the
16463 * indoor setting disappeared, so notify the regulatory core.
16464 */
16465 regulatory_netlink_notify(notify->portid);
6784c7db 16466 return NOTIFY_OK;
026331c4
JM
16467}
16468
16469static struct notifier_block nl80211_netlink_notifier = {
16470 .notifier_call = nl80211_netlink_notify,
16471};
16472
355199e0
JM
16473void cfg80211_ft_event(struct net_device *netdev,
16474 struct cfg80211_ft_event_params *ft_event)
16475{
16476 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
f26cbf40 16477 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
355199e0
JM
16478 struct sk_buff *msg;
16479 void *hdr;
355199e0
JM
16480
16481 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
16482
16483 if (!ft_event->target_ap)
16484 return;
16485
1039d081
DL
16486 msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
16487 GFP_KERNEL);
355199e0
JM
16488 if (!msg)
16489 return;
16490
16491 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
ae917c9f
JB
16492 if (!hdr)
16493 goto out;
355199e0 16494
ae917c9f
JB
16495 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16496 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16497 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
16498 goto out;
355199e0 16499
ae917c9f
JB
16500 if (ft_event->ies &&
16501 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
16502 goto out;
16503 if (ft_event->ric_ies &&
16504 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
16505 ft_event->ric_ies))
16506 goto out;
355199e0 16507
9c90a9f6 16508 genlmsg_end(msg, hdr);
355199e0 16509
68eb5503 16510 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
2a94fe48 16511 NL80211_MCGRP_MLME, GFP_KERNEL);
ae917c9f
JB
16512 return;
16513 out:
16514 nlmsg_free(msg);
355199e0
JM
16515}
16516EXPORT_SYMBOL(cfg80211_ft_event);
16517
5de17984
AS
16518void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
16519{
16520 struct cfg80211_registered_device *rdev;
16521 struct sk_buff *msg;
16522 void *hdr;
16523 u32 nlportid;
16524
f26cbf40 16525 rdev = wiphy_to_rdev(wdev->wiphy);
5de17984
AS
16526 if (!rdev->crit_proto_nlportid)
16527 return;
16528
16529 nlportid = rdev->crit_proto_nlportid;
16530 rdev->crit_proto_nlportid = 0;
16531
16532 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16533 if (!msg)
16534 return;
16535
16536 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
16537 if (!hdr)
16538 goto nla_put_failure;
16539
16540 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2dad624e
ND
16541 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16542 NL80211_ATTR_PAD))
5de17984
AS
16543 goto nla_put_failure;
16544
16545 genlmsg_end(msg, hdr);
16546
16547 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
16548 return;
16549
16550 nla_put_failure:
5de17984 16551 nlmsg_free(msg);
5de17984
AS
16552}
16553EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
16554
348baf0e
JB
16555void nl80211_send_ap_stopped(struct wireless_dev *wdev)
16556{
16557 struct wiphy *wiphy = wdev->wiphy;
f26cbf40 16558 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
348baf0e
JB
16559 struct sk_buff *msg;
16560 void *hdr;
16561
16562 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
16563 if (!msg)
16564 return;
16565
16566 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
16567 if (!hdr)
16568 goto out;
16569
16570 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16571 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
2dad624e
ND
16572 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
16573 NL80211_ATTR_PAD))
348baf0e
JB
16574 goto out;
16575
16576 genlmsg_end(msg, hdr);
16577
16578 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
16579 NL80211_MCGRP_MLME, GFP_KERNEL);
16580 return;
16581 out:
16582 nlmsg_free(msg);
16583}
16584
40cbfa90
SD
16585int cfg80211_external_auth_request(struct net_device *dev,
16586 struct cfg80211_external_auth_params *params,
16587 gfp_t gfp)
16588{
16589 struct wireless_dev *wdev = dev->ieee80211_ptr;
16590 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
16591 struct sk_buff *msg;
16592 void *hdr;
16593
16594 if (!wdev->conn_owner_nlportid)
16595 return -EINVAL;
16596
16597 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16598 if (!msg)
16599 return -ENOMEM;
16600
16601 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
16602 if (!hdr)
16603 goto nla_put_failure;
16604
16605 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16606 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
16607 nla_put_u32(msg, NL80211_ATTR_AKM_SUITES, params->key_mgmt_suite) ||
16608 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
16609 params->action) ||
16610 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
16611 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
16612 params->ssid.ssid))
16613 goto nla_put_failure;
16614
16615 genlmsg_end(msg, hdr);
16616 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
16617 wdev->conn_owner_nlportid);
16618 return 0;
16619
16620 nla_put_failure:
16621 nlmsg_free(msg);
16622 return -ENOBUFS;
16623}
16624EXPORT_SYMBOL(cfg80211_external_auth_request);
16625
cb74e977
SD
16626void cfg80211_update_owe_info_event(struct net_device *netdev,
16627 struct cfg80211_update_owe_info *owe_info,
16628 gfp_t gfp)
16629{
16630 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
16631 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
16632 struct sk_buff *msg;
16633 void *hdr;
16634
16635 trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
16636
16637 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
16638 if (!msg)
16639 return;
16640
16641 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
16642 if (!hdr)
16643 goto nla_put_failure;
16644
16645 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
16646 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
16647 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
16648 goto nla_put_failure;
16649
16650 if (!owe_info->ie_len ||
16651 nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
16652 goto nla_put_failure;
16653
16654 genlmsg_end(msg, hdr);
16655
16656 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
16657 NL80211_MCGRP_MLME, gfp);
16658 return;
16659
16660nla_put_failure:
16661 genlmsg_cancel(msg, hdr);
16662 nlmsg_free(msg);
16663}
16664EXPORT_SYMBOL(cfg80211_update_owe_info_event);
16665
55682965
JB
16666/* initialisation/exit functions */
16667
56989f6d 16668int __init nl80211_init(void)
55682965 16669{
0d63cbb5 16670 int err;
55682965 16671
489111e5 16672 err = genl_register_family(&nl80211_fam);
55682965
JB
16673 if (err)
16674 return err;
16675
026331c4
JM
16676 err = netlink_register_notifier(&nl80211_netlink_notifier);
16677 if (err)
16678 goto err_out;
16679
55682965
JB
16680 return 0;
16681 err_out:
16682 genl_unregister_family(&nl80211_fam);
16683 return err;
16684}
16685
16686void nl80211_exit(void)
16687{
026331c4 16688 netlink_unregister_notifier(&nl80211_netlink_notifier);
55682965
JB
16689 genl_unregister_family(&nl80211_fam);
16690}