printf: Remove unused 'bprintf'
[drm/drm-misc.git] / net / wireless / nl80211.c
blob9d2edb71f981dc968ad02670164348c3564729cd
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * This is the new netlink-based wireless configuration interface.
5 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2013-2014 Intel Mobile Communications GmbH
7 * Copyright 2015-2017 Intel Deutschland GmbH
8 * Copyright (C) 2018-2024 Intel Corporation
9 */
11 #include <linux/if.h>
12 #include <linux/module.h>
13 #include <linux/err.h>
14 #include <linux/slab.h>
15 #include <linux/list.h>
16 #include <linux/if_ether.h>
17 #include <linux/ieee80211.h>
18 #include <linux/nl80211.h>
19 #include <linux/rtnetlink.h>
20 #include <linux/netlink.h>
21 #include <linux/nospec.h>
22 #include <linux/etherdevice.h>
23 #include <linux/if_vlan.h>
24 #include <net/net_namespace.h>
25 #include <net/genetlink.h>
26 #include <net/cfg80211.h>
27 #include <net/sock.h>
28 #include <net/inet_connection_sock.h>
29 #include "core.h"
30 #include "nl80211.h"
31 #include "reg.h"
32 #include "rdev-ops.h"
34 static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
35 struct genl_info *info,
36 struct cfg80211_crypto_settings *settings,
37 int cipher_limit);
39 /* the netlink family */
40 static struct genl_family nl80211_fam;
42 /* multicast groups */
43 enum nl80211_multicast_groups {
44 NL80211_MCGRP_CONFIG,
45 NL80211_MCGRP_SCAN,
46 NL80211_MCGRP_REGULATORY,
47 NL80211_MCGRP_MLME,
48 NL80211_MCGRP_VENDOR,
49 NL80211_MCGRP_NAN,
50 NL80211_MCGRP_TESTMODE /* keep last - ifdef! */
53 static const struct genl_multicast_group nl80211_mcgrps[] = {
54 [NL80211_MCGRP_CONFIG] = { .name = NL80211_MULTICAST_GROUP_CONFIG },
55 [NL80211_MCGRP_SCAN] = { .name = NL80211_MULTICAST_GROUP_SCAN },
56 [NL80211_MCGRP_REGULATORY] = { .name = NL80211_MULTICAST_GROUP_REG },
57 [NL80211_MCGRP_MLME] = { .name = NL80211_MULTICAST_GROUP_MLME },
58 [NL80211_MCGRP_VENDOR] = { .name = NL80211_MULTICAST_GROUP_VENDOR },
59 [NL80211_MCGRP_NAN] = { .name = NL80211_MULTICAST_GROUP_NAN },
60 #ifdef CONFIG_NL80211_TESTMODE
61 [NL80211_MCGRP_TESTMODE] = { .name = NL80211_MULTICAST_GROUP_TESTMODE }
62 #endif
65 /* returns ERR_PTR values */
66 static struct wireless_dev *
67 __cfg80211_wdev_from_attrs(struct cfg80211_registered_device *rdev,
68 struct net *netns, struct nlattr **attrs)
70 struct wireless_dev *result = NULL;
71 bool have_ifidx = attrs[NL80211_ATTR_IFINDEX];
72 bool have_wdev_id = attrs[NL80211_ATTR_WDEV];
73 u64 wdev_id = 0;
74 int wiphy_idx = -1;
75 int ifidx = -1;
77 if (!have_ifidx && !have_wdev_id)
78 return ERR_PTR(-EINVAL);
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;
87 if (rdev) {
88 struct wireless_dev *wdev;
90 lockdep_assert_held(&rdev->wiphy.mtx);
92 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
93 if (have_ifidx && wdev->netdev &&
94 wdev->netdev->ifindex == ifidx) {
95 result = wdev;
96 break;
98 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
99 result = wdev;
100 break;
104 return result ?: ERR_PTR(-ENODEV);
107 ASSERT_RTNL();
109 for_each_rdev(rdev) {
110 struct wireless_dev *wdev;
112 if (wiphy_net(&rdev->wiphy) != netns)
113 continue;
115 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
116 continue;
118 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
119 if (have_ifidx && wdev->netdev &&
120 wdev->netdev->ifindex == ifidx) {
121 result = wdev;
122 break;
124 if (have_wdev_id && wdev->identifier == (u32)wdev_id) {
125 result = wdev;
126 break;
130 if (result)
131 break;
134 if (result)
135 return result;
136 return ERR_PTR(-ENODEV);
139 static struct cfg80211_registered_device *
140 __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
142 struct cfg80211_registered_device *rdev = NULL, *tmp;
143 struct net_device *netdev;
145 ASSERT_RTNL();
147 if (!attrs[NL80211_ATTR_WIPHY] &&
148 !attrs[NL80211_ATTR_IFINDEX] &&
149 !attrs[NL80211_ATTR_WDEV])
150 return ERR_PTR(-EINVAL);
152 if (attrs[NL80211_ATTR_WIPHY])
153 rdev = cfg80211_rdev_by_wiphy_idx(
154 nla_get_u32(attrs[NL80211_ATTR_WIPHY]));
156 if (attrs[NL80211_ATTR_WDEV]) {
157 u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]);
158 struct wireless_dev *wdev;
159 bool found = false;
161 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
162 if (tmp) {
163 /* make sure wdev exists */
164 list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
165 if (wdev->identifier != (u32)wdev_id)
166 continue;
167 found = true;
168 break;
171 if (!found)
172 tmp = NULL;
174 if (rdev && tmp != rdev)
175 return ERR_PTR(-EINVAL);
176 rdev = tmp;
180 if (attrs[NL80211_ATTR_IFINDEX]) {
181 int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
183 netdev = __dev_get_by_index(netns, ifindex);
184 if (netdev) {
185 if (netdev->ieee80211_ptr)
186 tmp = wiphy_to_rdev(
187 netdev->ieee80211_ptr->wiphy);
188 else
189 tmp = NULL;
191 /* not wireless device -- return error */
192 if (!tmp)
193 return ERR_PTR(-EINVAL);
195 /* mismatch -- return error */
196 if (rdev && tmp != rdev)
197 return ERR_PTR(-EINVAL);
199 rdev = tmp;
203 if (!rdev)
204 return ERR_PTR(-ENODEV);
206 if (netns != wiphy_net(&rdev->wiphy))
207 return ERR_PTR(-ENODEV);
209 return rdev;
213 * This function returns a pointer to the driver
214 * that the genl_info item that is passed refers to.
216 * The result of this can be a PTR_ERR and hence must
217 * be checked with IS_ERR() for errors.
219 static struct cfg80211_registered_device *
220 cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
222 return __cfg80211_rdev_from_attrs(netns, info->attrs);
225 static int validate_beacon_head(const struct nlattr *attr,
226 struct netlink_ext_ack *extack)
228 const u8 *data = nla_data(attr);
229 unsigned int len = nla_len(attr);
230 const struct element *elem;
231 const struct ieee80211_mgmt *mgmt = (void *)data;
232 unsigned int fixedlen, hdrlen;
233 bool s1g_bcn;
235 if (len < offsetofend(typeof(*mgmt), frame_control))
236 goto err;
238 s1g_bcn = ieee80211_is_s1g_beacon(mgmt->frame_control);
239 if (s1g_bcn) {
240 fixedlen = offsetof(struct ieee80211_ext,
241 u.s1g_beacon.variable);
242 hdrlen = offsetof(struct ieee80211_ext, u.s1g_beacon);
243 } else {
244 fixedlen = offsetof(struct ieee80211_mgmt,
245 u.beacon.variable);
246 hdrlen = offsetof(struct ieee80211_mgmt, u.beacon);
249 if (len < fixedlen)
250 goto err;
252 if (ieee80211_hdrlen(mgmt->frame_control) != hdrlen)
253 goto err;
255 data += fixedlen;
256 len -= fixedlen;
258 for_each_element(elem, data, len) {
259 /* nothing */
262 if (for_each_element_completed(elem, data, len))
263 return 0;
265 err:
266 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
267 return -EINVAL;
270 static int validate_ie_attr(const struct nlattr *attr,
271 struct netlink_ext_ack *extack)
273 const u8 *data = nla_data(attr);
274 unsigned int len = nla_len(attr);
275 const struct element *elem;
277 for_each_element(elem, data, len) {
278 /* nothing */
281 if (for_each_element_completed(elem, data, len))
282 return 0;
284 NL_SET_ERR_MSG_ATTR(extack, attr, "malformed information elements");
285 return -EINVAL;
288 static int validate_he_capa(const struct nlattr *attr,
289 struct netlink_ext_ack *extack)
291 if (!ieee80211_he_capa_size_ok(nla_data(attr), nla_len(attr)))
292 return -EINVAL;
294 return 0;
297 /* policy for the attributes */
298 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR];
300 static const struct nla_policy
301 nl80211_ftm_responder_policy[NL80211_FTM_RESP_ATTR_MAX + 1] = {
302 [NL80211_FTM_RESP_ATTR_ENABLED] = { .type = NLA_FLAG, },
303 [NL80211_FTM_RESP_ATTR_LCI] = { .type = NLA_BINARY,
304 .len = U8_MAX },
305 [NL80211_FTM_RESP_ATTR_CIVICLOC] = { .type = NLA_BINARY,
306 .len = U8_MAX },
309 static const struct nla_policy
310 nl80211_pmsr_ftm_req_attr_policy[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1] = {
311 [NL80211_PMSR_FTM_REQ_ATTR_ASAP] = { .type = NLA_FLAG },
312 [NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE] = { .type = NLA_U32 },
313 [NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP] =
314 NLA_POLICY_MAX(NLA_U8, 15),
315 [NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD] = { .type = NLA_U16 },
316 [NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION] =
317 NLA_POLICY_MAX(NLA_U8, 15),
318 [NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST] = { .type = NLA_U8 },
319 [NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES] = { .type = NLA_U8 },
320 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI] = { .type = NLA_FLAG },
321 [NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC] = { .type = NLA_FLAG },
322 [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG },
323 [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG },
324 [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG },
325 [NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR] = { .type = NLA_U8 },
328 static const struct nla_policy
329 nl80211_pmsr_req_data_policy[NL80211_PMSR_TYPE_MAX + 1] = {
330 [NL80211_PMSR_TYPE_FTM] =
331 NLA_POLICY_NESTED(nl80211_pmsr_ftm_req_attr_policy),
334 static const struct nla_policy
335 nl80211_pmsr_req_attr_policy[NL80211_PMSR_REQ_ATTR_MAX + 1] = {
336 [NL80211_PMSR_REQ_ATTR_DATA] =
337 NLA_POLICY_NESTED(nl80211_pmsr_req_data_policy),
338 [NL80211_PMSR_REQ_ATTR_GET_AP_TSF] = { .type = NLA_FLAG },
341 static const struct nla_policy
342 nl80211_pmsr_peer_attr_policy[NL80211_PMSR_PEER_ATTR_MAX + 1] = {
343 [NL80211_PMSR_PEER_ATTR_ADDR] = NLA_POLICY_ETH_ADDR,
344 [NL80211_PMSR_PEER_ATTR_CHAN] = NLA_POLICY_NESTED(nl80211_policy),
345 [NL80211_PMSR_PEER_ATTR_REQ] =
346 NLA_POLICY_NESTED(nl80211_pmsr_req_attr_policy),
347 [NL80211_PMSR_PEER_ATTR_RESP] = { .type = NLA_REJECT },
350 static const struct nla_policy
351 nl80211_pmsr_attr_policy[NL80211_PMSR_ATTR_MAX + 1] = {
352 [NL80211_PMSR_ATTR_MAX_PEERS] = { .type = NLA_REJECT },
353 [NL80211_PMSR_ATTR_REPORT_AP_TSF] = { .type = NLA_REJECT },
354 [NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR] = { .type = NLA_REJECT },
355 [NL80211_PMSR_ATTR_TYPE_CAPA] = { .type = NLA_REJECT },
356 [NL80211_PMSR_ATTR_PEERS] =
357 NLA_POLICY_NESTED_ARRAY(nl80211_pmsr_peer_attr_policy),
360 static const struct nla_policy
361 he_obss_pd_policy[NL80211_HE_OBSS_PD_ATTR_MAX + 1] = {
362 [NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET] =
363 NLA_POLICY_RANGE(NLA_U8, 1, 20),
364 [NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET] =
365 NLA_POLICY_RANGE(NLA_U8, 1, 20),
366 [NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET] =
367 NLA_POLICY_RANGE(NLA_U8, 1, 20),
368 [NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP] =
369 NLA_POLICY_EXACT_LEN(8),
370 [NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP] =
371 NLA_POLICY_EXACT_LEN(8),
372 [NL80211_HE_OBSS_PD_ATTR_SR_CTRL] = { .type = NLA_U8 },
375 static const struct nla_policy
376 he_bss_color_policy[NL80211_HE_BSS_COLOR_ATTR_MAX + 1] = {
377 [NL80211_HE_BSS_COLOR_ATTR_COLOR] = NLA_POLICY_RANGE(NLA_U8, 1, 63),
378 [NL80211_HE_BSS_COLOR_ATTR_DISABLED] = { .type = NLA_FLAG },
379 [NL80211_HE_BSS_COLOR_ATTR_PARTIAL] = { .type = NLA_FLAG },
382 static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
383 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
384 .len = NL80211_MAX_SUPP_RATES },
385 [NL80211_TXRATE_HT] = { .type = NLA_BINARY,
386 .len = NL80211_MAX_SUPP_HT_RATES },
387 [NL80211_TXRATE_VHT] = NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_txrate_vht)),
388 [NL80211_TXRATE_GI] = { .type = NLA_U8 },
389 [NL80211_TXRATE_HE] = NLA_POLICY_EXACT_LEN(sizeof(struct nl80211_txrate_he)),
390 [NL80211_TXRATE_HE_GI] = NLA_POLICY_RANGE(NLA_U8,
391 NL80211_RATE_INFO_HE_GI_0_8,
392 NL80211_RATE_INFO_HE_GI_3_2),
393 [NL80211_TXRATE_HE_LTF] = NLA_POLICY_RANGE(NLA_U8,
394 NL80211_RATE_INFO_HE_1XLTF,
395 NL80211_RATE_INFO_HE_4XLTF),
398 static const struct nla_policy
399 nl80211_tid_config_attr_policy[NL80211_TID_CONFIG_ATTR_MAX + 1] = {
400 [NL80211_TID_CONFIG_ATTR_VIF_SUPP] = { .type = NLA_U64 },
401 [NL80211_TID_CONFIG_ATTR_PEER_SUPP] = { .type = NLA_U64 },
402 [NL80211_TID_CONFIG_ATTR_OVERRIDE] = { .type = NLA_FLAG },
403 [NL80211_TID_CONFIG_ATTR_TIDS] = NLA_POLICY_RANGE(NLA_U16, 1, 0xff),
404 [NL80211_TID_CONFIG_ATTR_NOACK] =
405 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
406 [NL80211_TID_CONFIG_ATTR_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
407 [NL80211_TID_CONFIG_ATTR_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
408 [NL80211_TID_CONFIG_ATTR_AMPDU_CTRL] =
409 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
410 [NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL] =
411 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
412 [NL80211_TID_CONFIG_ATTR_AMSDU_CTRL] =
413 NLA_POLICY_MAX(NLA_U8, NL80211_TID_CONFIG_DISABLE),
414 [NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE] =
415 NLA_POLICY_MAX(NLA_U8, NL80211_TX_RATE_FIXED),
416 [NL80211_TID_CONFIG_ATTR_TX_RATE] =
417 NLA_POLICY_NESTED(nl80211_txattr_policy),
420 static const struct nla_policy
421 nl80211_fils_discovery_policy[NL80211_FILS_DISCOVERY_ATTR_MAX + 1] = {
422 [NL80211_FILS_DISCOVERY_ATTR_INT_MIN] = NLA_POLICY_MAX(NLA_U32, 10000),
423 [NL80211_FILS_DISCOVERY_ATTR_INT_MAX] = NLA_POLICY_MAX(NLA_U32, 10000),
424 [NL80211_FILS_DISCOVERY_ATTR_TMPL] =
425 NLA_POLICY_RANGE(NLA_BINARY,
426 NL80211_FILS_DISCOVERY_TMPL_MIN_LEN,
427 IEEE80211_MAX_DATA_LEN),
430 static const struct nla_policy
431 nl80211_unsol_bcast_probe_resp_policy[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1] = {
432 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] = NLA_POLICY_MAX(NLA_U32, 20),
433 [NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL] = { .type = NLA_BINARY,
434 .len = IEEE80211_MAX_DATA_LEN }
437 static const struct nla_policy
438 sar_specs_policy[NL80211_SAR_ATTR_SPECS_MAX + 1] = {
439 [NL80211_SAR_ATTR_SPECS_POWER] = { .type = NLA_S32 },
440 [NL80211_SAR_ATTR_SPECS_RANGE_INDEX] = {.type = NLA_U32 },
443 static const struct nla_policy
444 sar_policy[NL80211_SAR_ATTR_MAX + 1] = {
445 [NL80211_SAR_ATTR_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_SAR_TYPE),
446 [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy),
449 static const struct nla_policy
450 nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = {
451 [NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES] = NLA_POLICY_MIN(NLA_U8, 2),
452 [NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY] =
453 NLA_POLICY_MIN(NLA_U8, 1),
454 [NL80211_MBSSID_CONFIG_ATTR_INDEX] = { .type = NLA_U8 },
455 [NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 },
456 [NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG },
459 static const struct nla_policy
460 nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] = {
461 [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 },
462 [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 },
465 static const struct netlink_range_validation nl80211_punct_bitmap_range = {
466 .min = 0,
467 .max = 0xffff,
470 static const struct netlink_range_validation q_range = {
471 .max = INT_MAX,
474 static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
475 [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD },
476 [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
477 [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
478 .len = 20-1 },
479 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
481 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
482 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
483 [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = NLA_POLICY_RANGE(NLA_U8,
484 NL80211_EDMG_CHANNELS_MIN,
485 NL80211_EDMG_CHANNELS_MAX),
486 [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = NLA_POLICY_RANGE(NLA_U8,
487 NL80211_EDMG_BW_CONFIG_MIN,
488 NL80211_EDMG_BW_CONFIG_MAX),
490 [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 },
491 [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 },
492 [NL80211_ATTR_CENTER_FREQ1_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
493 [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 },
495 [NL80211_ATTR_WIPHY_RETRY_SHORT] = NLA_POLICY_MIN(NLA_U8, 1),
496 [NL80211_ATTR_WIPHY_RETRY_LONG] = NLA_POLICY_MIN(NLA_U8, 1),
497 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
498 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
499 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
500 [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG },
502 [NL80211_ATTR_IFTYPE] = NLA_POLICY_MAX(NLA_U32, NL80211_IFTYPE_MAX),
503 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
504 [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
506 [NL80211_ATTR_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
507 [NL80211_ATTR_PREV_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
509 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
510 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
511 .len = WLAN_MAX_KEY_LEN },
512 [NL80211_ATTR_KEY_IDX] = NLA_POLICY_MAX(NLA_U8, 7),
513 [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
514 [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
515 [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
516 [NL80211_ATTR_KEY_TYPE] =
517 NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES),
519 [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
520 [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
521 [NL80211_ATTR_BEACON_HEAD] =
522 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head,
523 IEEE80211_MAX_DATA_LEN),
524 [NL80211_ATTR_BEACON_TAIL] =
525 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
526 IEEE80211_MAX_DATA_LEN),
527 [NL80211_ATTR_STA_AID] =
528 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
529 [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED },
530 [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 },
531 [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY,
532 .len = NL80211_MAX_SUPP_RATES },
533 [NL80211_ATTR_STA_PLINK_ACTION] =
534 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_ACTIONS - 1),
535 [NL80211_ATTR_STA_TX_POWER_SETTING] =
536 NLA_POLICY_RANGE(NLA_U8,
537 NL80211_TX_POWER_AUTOMATIC,
538 NL80211_TX_POWER_FIXED),
539 [NL80211_ATTR_STA_TX_POWER] = { .type = NLA_S16 },
540 [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 },
541 [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ },
542 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
543 .len = IEEE80211_MAX_MESH_ID_LEN },
544 [NL80211_ATTR_MPATH_NEXT_HOP] = NLA_POLICY_ETH_ADDR_COMPAT,
546 /* allow 3 for NUL-termination, we used to declare this NLA_STRING */
547 [NL80211_ATTR_REG_ALPHA2] = NLA_POLICY_RANGE(NLA_BINARY, 2, 3),
548 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
550 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
551 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
552 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
553 [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY,
554 .len = NL80211_MAX_SUPP_RATES },
555 [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 },
557 [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
558 [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
560 [NL80211_ATTR_HT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_HT_CAPABILITY_LEN),
562 [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
563 [NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
564 validate_ie_attr,
565 IEEE80211_MAX_DATA_LEN),
566 [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED },
567 [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED },
569 [NL80211_ATTR_SSID] = { .type = NLA_BINARY,
570 .len = IEEE80211_MAX_SSID_LEN },
571 [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
572 [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
573 [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
574 [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
575 [NL80211_ATTR_USE_MFP] = NLA_POLICY_RANGE(NLA_U32,
576 NL80211_MFP_NO,
577 NL80211_MFP_OPTIONAL),
578 [NL80211_ATTR_STA_FLAGS2] =
579 NLA_POLICY_EXACT_LEN_WARN(sizeof(struct nl80211_sta_flag_update)),
580 [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
581 [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 },
582 [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG },
583 [NL80211_ATTR_CONTROL_PORT_OVER_NL80211] = { .type = NLA_FLAG },
584 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
585 [NL80211_ATTR_STATUS_CODE] = { .type = NLA_U16 },
586 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
587 [NL80211_ATTR_WPA_VERSIONS] =
588 NLA_POLICY_RANGE(NLA_U32, 0,
589 NL80211_WPA_VERSION_1 |
590 NL80211_WPA_VERSION_2 |
591 NL80211_WPA_VERSION_3),
592 [NL80211_ATTR_PID] = { .type = NLA_U32 },
593 [NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
594 [NL80211_ATTR_PMKID] = NLA_POLICY_EXACT_LEN_WARN(WLAN_PMKID_LEN),
595 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
596 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
597 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
598 [NL80211_ATTR_FRAME] = { .type = NLA_BINARY,
599 .len = IEEE80211_MAX_DATA_LEN },
600 [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, },
601 [NL80211_ATTR_PS_STATE] = NLA_POLICY_RANGE(NLA_U32,
602 NL80211_PS_DISABLED,
603 NL80211_PS_ENABLED),
604 [NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
605 [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
606 [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
607 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
608 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
609 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
610 [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
611 [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
612 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
613 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
614 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
615 [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED },
616 [NL80211_ATTR_STA_PLINK_STATE] =
617 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_PLINK_STATES - 1),
618 [NL80211_ATTR_MEASUREMENT_DURATION] = { .type = NLA_U16 },
619 [NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY] = { .type = NLA_FLAG },
620 [NL80211_ATTR_MESH_PEER_AID] =
621 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
622 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
623 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
624 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
625 [NL80211_ATTR_HIDDEN_SSID] =
626 NLA_POLICY_RANGE(NLA_U32,
627 NL80211_HIDDEN_SSID_NOT_IN_USE,
628 NL80211_HIDDEN_SSID_ZERO_CONTENTS),
629 [NL80211_ATTR_IE_PROBE_RESP] =
630 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
631 IEEE80211_MAX_DATA_LEN),
632 [NL80211_ATTR_IE_ASSOC_RESP] =
633 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
634 IEEE80211_MAX_DATA_LEN),
635 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
636 [NL80211_ATTR_STA_WME] = NLA_POLICY_NESTED(nl80211_sta_wme_policy),
637 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
638 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
639 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
640 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
641 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
642 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
643 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
644 [NL80211_ATTR_TDLS_INITIATOR] = { .type = NLA_FLAG },
645 [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG },
646 [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
647 .len = IEEE80211_MAX_DATA_LEN },
648 [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 },
649 [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG },
650 [NL80211_ATTR_HT_CAPABILITY_MASK] = {
651 .len = NL80211_HT_CAPABILITY_LEN
653 [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
654 [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 },
655 [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 },
656 [NL80211_ATTR_WDEV] = { .type = NLA_U64 },
657 [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
659 /* need to include at least Auth Transaction and Status Code */
660 [NL80211_ATTR_AUTH_DATA] = NLA_POLICY_MIN_LEN(4),
662 [NL80211_ATTR_VHT_CAPABILITY] = NLA_POLICY_EXACT_LEN_WARN(NL80211_VHT_CAPABILITY_LEN),
663 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
664 [NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
665 [NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
666 [NL80211_ATTR_LOCAL_MESH_POWER_MODE] =
667 NLA_POLICY_RANGE(NLA_U32,
668 NL80211_MESH_POWER_UNKNOWN + 1,
669 NL80211_MESH_POWER_MAX),
670 [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
671 [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
672 [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
673 [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, },
674 [NL80211_ATTR_SPLIT_WIPHY_DUMP] = { .type = NLA_FLAG, },
675 [NL80211_ATTR_DISABLE_VHT] = { .type = NLA_FLAG },
676 [NL80211_ATTR_VHT_CAPABILITY_MASK] = {
677 .len = NL80211_VHT_CAPABILITY_LEN,
679 [NL80211_ATTR_MDID] = { .type = NLA_U16 },
680 [NL80211_ATTR_IE_RIC] = { .type = NLA_BINARY,
681 .len = IEEE80211_MAX_DATA_LEN },
682 [NL80211_ATTR_CRIT_PROT_ID] = { .type = NLA_U16 },
683 [NL80211_ATTR_MAX_CRIT_PROT_DURATION] =
684 NLA_POLICY_MAX(NLA_U16, NL80211_CRIT_PROTO_MAX_DURATION),
685 [NL80211_ATTR_PEER_AID] =
686 NLA_POLICY_RANGE(NLA_U16, 1, IEEE80211_MAX_AID),
687 [NL80211_ATTR_CH_SWITCH_COUNT] = { .type = NLA_U32 },
688 [NL80211_ATTR_CH_SWITCH_BLOCK_TX] = { .type = NLA_FLAG },
689 [NL80211_ATTR_CSA_IES] = { .type = NLA_NESTED },
690 [NL80211_ATTR_CNTDWN_OFFS_BEACON] = { .type = NLA_BINARY },
691 [NL80211_ATTR_CNTDWN_OFFS_PRESP] = { .type = NLA_BINARY },
692 [NL80211_ATTR_STA_SUPPORTED_CHANNELS] = NLA_POLICY_MIN_LEN(2),
694 * The value of the Length field of the Supported Operating
695 * Classes element is between 2 and 253.
697 [NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES] =
698 NLA_POLICY_RANGE(NLA_BINARY, 2, 253),
699 [NL80211_ATTR_HANDLE_DFS] = { .type = NLA_FLAG },
700 [NL80211_ATTR_OPMODE_NOTIF] = { .type = NLA_U8 },
701 [NL80211_ATTR_VENDOR_ID] = { .type = NLA_U32 },
702 [NL80211_ATTR_VENDOR_SUBCMD] = { .type = NLA_U32 },
703 [NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
704 [NL80211_ATTR_QOS_MAP] = NLA_POLICY_RANGE(NLA_BINARY,
705 IEEE80211_QOS_MAP_LEN_MIN,
706 IEEE80211_QOS_MAP_LEN_MAX),
707 [NL80211_ATTR_MAC_HINT] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
708 [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
709 [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
710 [NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
711 [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY },
712 [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG },
713 [NL80211_ATTR_TSID] = NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_TIDS - 1),
714 [NL80211_ATTR_USER_PRIO] =
715 NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
716 [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
717 [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
718 [NL80211_ATTR_OPER_CLASS] = { .type = NLA_U8 },
719 [NL80211_ATTR_MAC_MASK] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
720 [NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
721 [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
722 [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
723 [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
724 [NL80211_ATTR_PBSS] = { .type = NLA_FLAG },
725 [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED },
726 [NL80211_ATTR_STA_SUPPORT_P2P_PS] =
727 NLA_POLICY_MAX(NLA_U8, NUM_NL80211_P2P_PS_STATUS - 1),
728 [NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
729 .len = VHT_MUMIMO_GROUPS_DATA_LEN
731 [NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
732 [NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
733 [NL80211_ATTR_BANDS] = { .type = NLA_U32 },
734 [NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
735 [NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
736 .len = FILS_MAX_KEK_LEN },
737 [NL80211_ATTR_FILS_NONCES] = NLA_POLICY_EXACT_LEN_WARN(2 * FILS_NONCE_LEN),
738 [NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
739 [NL80211_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
740 [NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
741 [NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
742 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
744 [NL80211_ATTR_TIMEOUT_REASON] = { .type = NLA_U32 },
745 [NL80211_ATTR_FILS_ERP_USERNAME] = { .type = NLA_BINARY,
746 .len = FILS_ERP_MAX_USERNAME_LEN },
747 [NL80211_ATTR_FILS_ERP_REALM] = { .type = NLA_BINARY,
748 .len = FILS_ERP_MAX_REALM_LEN },
749 [NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
750 [NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
751 .len = FILS_ERP_MAX_RRK_LEN },
752 [NL80211_ATTR_FILS_CACHE_ID] = NLA_POLICY_EXACT_LEN_WARN(2),
753 [NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
754 [NL80211_ATTR_PMKR0_NAME] = NLA_POLICY_EXACT_LEN(WLAN_PMK_NAME_LEN),
755 [NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
756 [NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
758 [NL80211_ATTR_TXQ_LIMIT] = { .type = NLA_U32 },
759 [NL80211_ATTR_TXQ_MEMORY_LIMIT] = { .type = NLA_U32 },
760 [NL80211_ATTR_TXQ_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &q_range),
761 [NL80211_ATTR_HE_CAPABILITY] =
762 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_he_capa,
763 NL80211_HE_MAX_CAPABILITY_LEN),
764 [NL80211_ATTR_FTM_RESPONDER] =
765 NLA_POLICY_NESTED(nl80211_ftm_responder_policy),
766 [NL80211_ATTR_TIMEOUT] = NLA_POLICY_MIN(NLA_U32, 1),
767 [NL80211_ATTR_PEER_MEASUREMENTS] =
768 NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
769 [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
770 [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
771 .len = SAE_PASSWORD_MAX_LEN },
772 [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
773 [NL80211_ATTR_HE_OBSS_PD] = NLA_POLICY_NESTED(he_obss_pd_policy),
774 [NL80211_ATTR_VLAN_ID] = NLA_POLICY_RANGE(NLA_U16, 1, VLAN_N_VID - 2),
775 [NL80211_ATTR_HE_BSS_COLOR] = NLA_POLICY_NESTED(he_bss_color_policy),
776 [NL80211_ATTR_TID_CONFIG] =
777 NLA_POLICY_NESTED_ARRAY(nl80211_tid_config_attr_policy),
778 [NL80211_ATTR_CONTROL_PORT_NO_PREAUTH] = { .type = NLA_FLAG },
779 [NL80211_ATTR_PMK_LIFETIME] = NLA_POLICY_MIN(NLA_U32, 1),
780 [NL80211_ATTR_PMK_REAUTH_THRESHOLD] = NLA_POLICY_RANGE(NLA_U8, 1, 100),
781 [NL80211_ATTR_RECEIVE_MULTICAST] = { .type = NLA_FLAG },
782 [NL80211_ATTR_WIPHY_FREQ_OFFSET] = NLA_POLICY_RANGE(NLA_U32, 0, 999),
783 [NL80211_ATTR_SCAN_FREQ_KHZ] = { .type = NLA_NESTED },
784 [NL80211_ATTR_HE_6GHZ_CAPABILITY] =
785 NLA_POLICY_EXACT_LEN(sizeof(struct ieee80211_he_6ghz_capa)),
786 [NL80211_ATTR_FILS_DISCOVERY] =
787 NLA_POLICY_NESTED(nl80211_fils_discovery_policy),
788 [NL80211_ATTR_UNSOL_BCAST_PROBE_RESP] =
789 NLA_POLICY_NESTED(nl80211_unsol_bcast_probe_resp_policy),
790 [NL80211_ATTR_S1G_CAPABILITY] =
791 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
792 [NL80211_ATTR_S1G_CAPABILITY_MASK] =
793 NLA_POLICY_EXACT_LEN(IEEE80211_S1G_CAPABILITY_LEN),
794 [NL80211_ATTR_SAE_PWE] =
795 NLA_POLICY_RANGE(NLA_U8, NL80211_SAE_PWE_HUNT_AND_PECK,
796 NL80211_SAE_PWE_BOTH),
797 [NL80211_ATTR_RECONNECT_REQUESTED] = { .type = NLA_REJECT },
798 [NL80211_ATTR_SAR_SPEC] = NLA_POLICY_NESTED(sar_policy),
799 [NL80211_ATTR_DISABLE_HE] = { .type = NLA_FLAG },
800 [NL80211_ATTR_OBSS_COLOR_BITMAP] = { .type = NLA_U64 },
801 [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 },
802 [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 },
803 [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy),
804 [NL80211_ATTR_MBSSID_CONFIG] =
805 NLA_POLICY_NESTED(nl80211_mbssid_config_policy),
806 [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED },
807 [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG },
808 [NL80211_ATTR_AP_SETTINGS_FLAGS] = { .type = NLA_U32 },
809 [NL80211_ATTR_EHT_CAPABILITY] =
810 NLA_POLICY_RANGE(NLA_BINARY,
811 NL80211_EHT_MIN_CAPABILITY_LEN,
812 NL80211_EHT_MAX_CAPABILITY_LEN),
813 [NL80211_ATTR_DISABLE_EHT] = { .type = NLA_FLAG },
814 [NL80211_ATTR_MLO_LINKS] =
815 NLA_POLICY_NESTED_ARRAY(nl80211_policy),
816 [NL80211_ATTR_MLO_LINK_ID] =
817 NLA_POLICY_RANGE(NLA_U8, 0, IEEE80211_MLD_MAX_NUM_LINKS),
818 [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN),
819 [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG },
820 [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT },
821 [NL80211_ATTR_PUNCT_BITMAP] =
822 NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range),
824 [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 },
825 [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG },
826 [NL80211_ATTR_EMA_RNR_ELEMS] = { .type = NLA_NESTED },
827 [NL80211_ATTR_MLO_LINK_DISABLED] = { .type = NLA_FLAG },
828 [NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA] = { .type = NLA_FLAG },
829 [NL80211_ATTR_MLO_TTLM_DLINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
830 [NL80211_ATTR_MLO_TTLM_ULINK] = NLA_POLICY_EXACT_LEN(sizeof(u16) * 8),
831 [NL80211_ATTR_ASSOC_SPP_AMSDU] = { .type = NLA_FLAG },
832 [NL80211_ATTR_VIF_RADIO_MASK] = { .type = NLA_U32 },
835 /* policy for the key attributes */
836 static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = {
837 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
838 [NL80211_KEY_IDX] = { .type = NLA_U8 },
839 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
840 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 },
841 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
842 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
843 [NL80211_KEY_TYPE] = NLA_POLICY_MAX(NLA_U32, NUM_NL80211_KEYTYPES - 1),
844 [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
845 [NL80211_KEY_MODE] = NLA_POLICY_RANGE(NLA_U8, 0, NL80211_KEY_SET_TX),
848 /* policy for the key default flags */
849 static const struct nla_policy
850 nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = {
851 [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG },
852 [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG },
855 #ifdef CONFIG_PM
856 /* policy for WoWLAN attributes */
857 static const struct nla_policy
858 nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
859 [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
860 [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
861 [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
862 [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
863 [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
864 [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
865 [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
866 [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
867 [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED },
868 [NL80211_WOWLAN_TRIG_NET_DETECT] = { .type = NLA_NESTED },
871 static const struct nla_policy
872 nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
873 [NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
874 [NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
875 [NL80211_WOWLAN_TCP_DST_MAC] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
876 [NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
877 [NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
878 [NL80211_WOWLAN_TCP_DATA_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
879 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
880 .len = sizeof(struct nl80211_wowlan_tcp_data_seq)
882 [NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN] = {
883 .len = sizeof(struct nl80211_wowlan_tcp_data_token)
885 [NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
886 [NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = NLA_POLICY_MIN_LEN(1),
887 [NL80211_WOWLAN_TCP_WAKE_MASK] = NLA_POLICY_MIN_LEN(1),
889 #endif /* CONFIG_PM */
891 /* policy for coalesce rule attributes */
892 static const struct nla_policy
893 nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
894 [NL80211_ATTR_COALESCE_RULE_DELAY] = { .type = NLA_U32 },
895 [NL80211_ATTR_COALESCE_RULE_CONDITION] =
896 NLA_POLICY_RANGE(NLA_U32,
897 NL80211_COALESCE_CONDITION_MATCH,
898 NL80211_COALESCE_CONDITION_NO_MATCH),
899 [NL80211_ATTR_COALESCE_RULE_PKT_PATTERN] = { .type = NLA_NESTED },
902 /* policy for GTK rekey offload attributes */
903 static const struct nla_policy
904 nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
905 [NL80211_REKEY_DATA_KEK] = {
906 .type = NLA_BINARY,
907 .len = NL80211_KEK_EXT_LEN
909 [NL80211_REKEY_DATA_KCK] = {
910 .type = NLA_BINARY,
911 .len = NL80211_KCK_EXT_LEN_32
913 [NL80211_REKEY_DATA_REPLAY_CTR] = NLA_POLICY_EXACT_LEN(NL80211_REPLAY_CTR_LEN),
914 [NL80211_REKEY_DATA_AKM] = { .type = NLA_U32 },
917 static const struct nla_policy
918 nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
919 [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
920 .len = IEEE80211_MAX_SSID_LEN },
921 [NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
922 [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
925 static const struct nla_policy
926 nl80211_plan_policy[NL80211_SCHED_SCAN_PLAN_MAX + 1] = {
927 [NL80211_SCHED_SCAN_PLAN_INTERVAL] = { .type = NLA_U32 },
928 [NL80211_SCHED_SCAN_PLAN_ITERATIONS] = { .type = NLA_U32 },
931 static const struct nla_policy
932 nl80211_bss_select_policy[NL80211_BSS_SELECT_ATTR_MAX + 1] = {
933 [NL80211_BSS_SELECT_ATTR_RSSI] = { .type = NLA_FLAG },
934 [NL80211_BSS_SELECT_ATTR_BAND_PREF] = { .type = NLA_U32 },
935 [NL80211_BSS_SELECT_ATTR_RSSI_ADJUST] = {
936 .len = sizeof(struct nl80211_bss_select_rssi_adjust)
940 /* policy for NAN function attributes */
941 static const struct nla_policy
942 nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
943 [NL80211_NAN_FUNC_TYPE] =
944 NLA_POLICY_MAX(NLA_U8, NL80211_NAN_FUNC_MAX_TYPE),
945 [NL80211_NAN_FUNC_SERVICE_ID] = {
946 .len = NL80211_NAN_FUNC_SERVICE_ID_LEN },
947 [NL80211_NAN_FUNC_PUBLISH_TYPE] = { .type = NLA_U8 },
948 [NL80211_NAN_FUNC_PUBLISH_BCAST] = { .type = NLA_FLAG },
949 [NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
950 [NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
951 [NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
952 [NL80211_NAN_FUNC_FOLLOW_UP_DEST] = NLA_POLICY_EXACT_LEN_WARN(ETH_ALEN),
953 [NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
954 [NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
955 [NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
956 .len = NL80211_NAN_FUNC_SERVICE_SPEC_INFO_MAX_LEN },
957 [NL80211_NAN_FUNC_SRF] = { .type = NLA_NESTED },
958 [NL80211_NAN_FUNC_RX_MATCH_FILTER] = { .type = NLA_NESTED },
959 [NL80211_NAN_FUNC_TX_MATCH_FILTER] = { .type = NLA_NESTED },
960 [NL80211_NAN_FUNC_INSTANCE_ID] = { .type = NLA_U8 },
961 [NL80211_NAN_FUNC_TERM_REASON] = { .type = NLA_U8 },
964 /* policy for Service Response Filter attributes */
965 static const struct nla_policy
966 nl80211_nan_srf_policy[NL80211_NAN_SRF_ATTR_MAX + 1] = {
967 [NL80211_NAN_SRF_INCLUDE] = { .type = NLA_FLAG },
968 [NL80211_NAN_SRF_BF] = { .type = NLA_BINARY,
969 .len = NL80211_NAN_FUNC_SRF_MAX_LEN },
970 [NL80211_NAN_SRF_BF_IDX] = { .type = NLA_U8 },
971 [NL80211_NAN_SRF_MAC_ADDRS] = { .type = NLA_NESTED },
974 /* policy for packet pattern attributes */
975 static const struct nla_policy
976 nl80211_packet_pattern_policy[MAX_NL80211_PKTPAT + 1] = {
977 [NL80211_PKTPAT_MASK] = { .type = NLA_BINARY, },
978 [NL80211_PKTPAT_PATTERN] = { .type = NLA_BINARY, },
979 [NL80211_PKTPAT_OFFSET] = { .type = NLA_U32 },
982 static int nl80211_prepare_wdev_dump(struct netlink_callback *cb,
983 struct cfg80211_registered_device **rdev,
984 struct wireless_dev **wdev,
985 struct nlattr **attrbuf)
987 int err;
989 if (!cb->args[0]) {
990 struct nlattr **attrbuf_free = NULL;
992 if (!attrbuf) {
993 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
994 GFP_KERNEL);
995 if (!attrbuf)
996 return -ENOMEM;
997 attrbuf_free = attrbuf;
1000 err = nlmsg_parse_deprecated(cb->nlh,
1001 GENL_HDRLEN + nl80211_fam.hdrsize,
1002 attrbuf, nl80211_fam.maxattr,
1003 nl80211_policy, NULL);
1004 if (err) {
1005 kfree(attrbuf_free);
1006 return err;
1009 rtnl_lock();
1010 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(cb->skb->sk),
1011 attrbuf);
1012 kfree(attrbuf_free);
1013 if (IS_ERR(*wdev)) {
1014 rtnl_unlock();
1015 return PTR_ERR(*wdev);
1017 *rdev = wiphy_to_rdev((*wdev)->wiphy);
1018 mutex_lock(&(*rdev)->wiphy.mtx);
1019 rtnl_unlock();
1020 /* 0 is the first index - add 1 to parse only once */
1021 cb->args[0] = (*rdev)->wiphy_idx + 1;
1022 cb->args[1] = (*wdev)->identifier;
1023 } else {
1024 /* subtract the 1 again here */
1025 struct wiphy *wiphy;
1026 struct wireless_dev *tmp;
1028 rtnl_lock();
1029 wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
1030 if (!wiphy) {
1031 rtnl_unlock();
1032 return -ENODEV;
1034 *rdev = wiphy_to_rdev(wiphy);
1035 *wdev = NULL;
1037 list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
1038 if (tmp->identifier == cb->args[1]) {
1039 *wdev = tmp;
1040 break;
1044 if (!*wdev) {
1045 rtnl_unlock();
1046 return -ENODEV;
1048 mutex_lock(&(*rdev)->wiphy.mtx);
1049 rtnl_unlock();
1052 return 0;
1055 /* message building helper */
1056 void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq,
1057 int flags, u8 cmd)
1059 /* since there is no private header just add the generic one */
1060 return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd);
1063 static int nl80211_msg_put_wmm_rules(struct sk_buff *msg,
1064 const struct ieee80211_reg_rule *rule)
1066 int j;
1067 struct nlattr *nl_wmm_rules =
1068 nla_nest_start_noflag(msg, NL80211_FREQUENCY_ATTR_WMM);
1070 if (!nl_wmm_rules)
1071 goto nla_put_failure;
1073 for (j = 0; j < IEEE80211_NUM_ACS; j++) {
1074 struct nlattr *nl_wmm_rule = nla_nest_start_noflag(msg, j);
1076 if (!nl_wmm_rule)
1077 goto nla_put_failure;
1079 if (nla_put_u16(msg, NL80211_WMMR_CW_MIN,
1080 rule->wmm_rule.client[j].cw_min) ||
1081 nla_put_u16(msg, NL80211_WMMR_CW_MAX,
1082 rule->wmm_rule.client[j].cw_max) ||
1083 nla_put_u8(msg, NL80211_WMMR_AIFSN,
1084 rule->wmm_rule.client[j].aifsn) ||
1085 nla_put_u16(msg, NL80211_WMMR_TXOP,
1086 rule->wmm_rule.client[j].cot))
1087 goto nla_put_failure;
1089 nla_nest_end(msg, nl_wmm_rule);
1091 nla_nest_end(msg, nl_wmm_rules);
1093 return 0;
1095 nla_put_failure:
1096 return -ENOBUFS;
1099 static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy,
1100 struct ieee80211_channel *chan,
1101 bool large)
1103 /* Some channels must be completely excluded from the
1104 * list to protect old user-space tools from breaking
1106 if (!large && chan->flags &
1107 (IEEE80211_CHAN_NO_10MHZ | IEEE80211_CHAN_NO_20MHZ))
1108 return 0;
1109 if (!large && chan->freq_offset)
1110 return 0;
1112 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ,
1113 chan->center_freq))
1114 goto nla_put_failure;
1116 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset))
1117 goto nla_put_failure;
1119 if ((chan->flags & IEEE80211_CHAN_PSD) &&
1120 nla_put_s8(msg, NL80211_FREQUENCY_ATTR_PSD, chan->psd))
1121 goto nla_put_failure;
1123 if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
1124 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
1125 goto nla_put_failure;
1126 if (chan->flags & IEEE80211_CHAN_NO_IR) {
1127 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR))
1128 goto nla_put_failure;
1129 if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS))
1130 goto nla_put_failure;
1132 if (chan->flags & IEEE80211_CHAN_RADAR) {
1133 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
1134 goto nla_put_failure;
1135 if (large) {
1136 u32 time;
1138 time = elapsed_jiffies_msecs(chan->dfs_state_entered);
1140 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
1141 chan->dfs_state))
1142 goto nla_put_failure;
1143 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME,
1144 time))
1145 goto nla_put_failure;
1146 if (nla_put_u32(msg,
1147 NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
1148 chan->dfs_cac_ms))
1149 goto nla_put_failure;
1153 if (large) {
1154 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
1155 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
1156 goto nla_put_failure;
1157 if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) &&
1158 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS))
1159 goto nla_put_failure;
1160 if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) &&
1161 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ))
1162 goto nla_put_failure;
1163 if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) &&
1164 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ))
1165 goto nla_put_failure;
1166 if ((chan->flags & IEEE80211_CHAN_INDOOR_ONLY) &&
1167 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_INDOOR_ONLY))
1168 goto nla_put_failure;
1169 if ((chan->flags & IEEE80211_CHAN_IR_CONCURRENT) &&
1170 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_IR_CONCURRENT))
1171 goto nla_put_failure;
1172 if ((chan->flags & IEEE80211_CHAN_NO_20MHZ) &&
1173 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_20MHZ))
1174 goto nla_put_failure;
1175 if ((chan->flags & IEEE80211_CHAN_NO_10MHZ) &&
1176 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_10MHZ))
1177 goto nla_put_failure;
1178 if ((chan->flags & IEEE80211_CHAN_NO_HE) &&
1179 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HE))
1180 goto nla_put_failure;
1181 if ((chan->flags & IEEE80211_CHAN_1MHZ) &&
1182 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_1MHZ))
1183 goto nla_put_failure;
1184 if ((chan->flags & IEEE80211_CHAN_2MHZ) &&
1185 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_2MHZ))
1186 goto nla_put_failure;
1187 if ((chan->flags & IEEE80211_CHAN_4MHZ) &&
1188 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_4MHZ))
1189 goto nla_put_failure;
1190 if ((chan->flags & IEEE80211_CHAN_8MHZ) &&
1191 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_8MHZ))
1192 goto nla_put_failure;
1193 if ((chan->flags & IEEE80211_CHAN_16MHZ) &&
1194 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_16MHZ))
1195 goto nla_put_failure;
1196 if ((chan->flags & IEEE80211_CHAN_NO_320MHZ) &&
1197 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_320MHZ))
1198 goto nla_put_failure;
1199 if ((chan->flags & IEEE80211_CHAN_NO_EHT) &&
1200 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_EHT))
1201 goto nla_put_failure;
1202 if ((chan->flags & IEEE80211_CHAN_DFS_CONCURRENT) &&
1203 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DFS_CONCURRENT))
1204 goto nla_put_failure;
1205 if ((chan->flags & IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT) &&
1206 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_6GHZ_VLP_CLIENT))
1207 goto nla_put_failure;
1208 if ((chan->flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT) &&
1209 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_6GHZ_AFC_CLIENT))
1210 goto nla_put_failure;
1211 if ((chan->flags & IEEE80211_CHAN_CAN_MONITOR) &&
1212 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_CAN_MONITOR))
1213 goto nla_put_failure;
1214 if ((chan->flags & IEEE80211_CHAN_ALLOW_6GHZ_VLP_AP) &&
1215 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_ALLOW_6GHZ_VLP_AP))
1216 goto nla_put_failure;
1219 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
1220 DBM_TO_MBM(chan->max_power)))
1221 goto nla_put_failure;
1223 if (large) {
1224 const struct ieee80211_reg_rule *rule =
1225 freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
1227 if (!IS_ERR_OR_NULL(rule) && rule->has_wmm) {
1228 if (nl80211_msg_put_wmm_rules(msg, rule))
1229 goto nla_put_failure;
1233 return 0;
1235 nla_put_failure:
1236 return -ENOBUFS;
1239 static bool nl80211_put_txq_stats(struct sk_buff *msg,
1240 struct cfg80211_txq_stats *txqstats,
1241 int attrtype)
1243 struct nlattr *txqattr;
1245 #define PUT_TXQVAL_U32(attr, memb) do { \
1246 if (txqstats->filled & BIT(NL80211_TXQ_STATS_ ## attr) && \
1247 nla_put_u32(msg, NL80211_TXQ_STATS_ ## attr, txqstats->memb)) \
1248 return false; \
1249 } while (0)
1251 txqattr = nla_nest_start_noflag(msg, attrtype);
1252 if (!txqattr)
1253 return false;
1255 PUT_TXQVAL_U32(BACKLOG_BYTES, backlog_bytes);
1256 PUT_TXQVAL_U32(BACKLOG_PACKETS, backlog_packets);
1257 PUT_TXQVAL_U32(FLOWS, flows);
1258 PUT_TXQVAL_U32(DROPS, drops);
1259 PUT_TXQVAL_U32(ECN_MARKS, ecn_marks);
1260 PUT_TXQVAL_U32(OVERLIMIT, overlimit);
1261 PUT_TXQVAL_U32(OVERMEMORY, overmemory);
1262 PUT_TXQVAL_U32(COLLISIONS, collisions);
1263 PUT_TXQVAL_U32(TX_BYTES, tx_bytes);
1264 PUT_TXQVAL_U32(TX_PACKETS, tx_packets);
1265 PUT_TXQVAL_U32(MAX_FLOWS, max_flows);
1266 nla_nest_end(msg, txqattr);
1268 #undef PUT_TXQVAL_U32
1269 return true;
1272 /* netlink command implementations */
1275 * nl80211_link_id - return link ID
1276 * @attrs: attributes to look at
1278 * Returns: the link ID or 0 if not given
1280 * Note this function doesn't do any validation of the link
1281 * ID validity wrt. links that were actually added, so it must
1282 * be called only from ops with %NL80211_FLAG_MLO_VALID_LINK_ID
1283 * or if additional validation is done.
1285 static unsigned int nl80211_link_id(struct nlattr **attrs)
1287 struct nlattr *linkid = attrs[NL80211_ATTR_MLO_LINK_ID];
1289 return nla_get_u8_default(linkid, 0);
1292 static int nl80211_link_id_or_invalid(struct nlattr **attrs)
1294 struct nlattr *linkid = attrs[NL80211_ATTR_MLO_LINK_ID];
1296 if (!linkid)
1297 return -1;
1299 return nla_get_u8(linkid);
1302 struct key_parse {
1303 struct key_params p;
1304 int idx;
1305 int type;
1306 bool def, defmgmt, defbeacon;
1307 bool def_uni, def_multi;
1310 static int nl80211_parse_key_new(struct genl_info *info, struct nlattr *key,
1311 struct key_parse *k)
1313 struct nlattr *tb[NL80211_KEY_MAX + 1];
1314 int err = nla_parse_nested_deprecated(tb, NL80211_KEY_MAX, key,
1315 nl80211_key_policy,
1316 info->extack);
1317 if (err)
1318 return err;
1320 k->def = !!tb[NL80211_KEY_DEFAULT];
1321 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
1322 k->defbeacon = !!tb[NL80211_KEY_DEFAULT_BEACON];
1324 if (k->def) {
1325 k->def_uni = true;
1326 k->def_multi = true;
1328 if (k->defmgmt || k->defbeacon)
1329 k->def_multi = true;
1331 if (tb[NL80211_KEY_IDX])
1332 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
1334 if (tb[NL80211_KEY_DATA]) {
1335 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
1336 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
1339 if (tb[NL80211_KEY_SEQ]) {
1340 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
1341 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
1344 if (tb[NL80211_KEY_CIPHER])
1345 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
1347 if (tb[NL80211_KEY_TYPE])
1348 k->type = nla_get_u32(tb[NL80211_KEY_TYPE]);
1350 if (tb[NL80211_KEY_DEFAULT_TYPES]) {
1351 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
1353 err = nla_parse_nested_deprecated(kdt,
1354 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1355 tb[NL80211_KEY_DEFAULT_TYPES],
1356 nl80211_key_default_policy,
1357 info->extack);
1358 if (err)
1359 return err;
1361 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1362 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1365 if (tb[NL80211_KEY_MODE])
1366 k->p.mode = nla_get_u8(tb[NL80211_KEY_MODE]);
1368 return 0;
1371 static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
1373 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
1374 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
1375 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1378 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1379 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1380 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1383 if (info->attrs[NL80211_ATTR_KEY_IDX])
1384 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1386 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
1387 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1389 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
1390 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
1392 if (k->def) {
1393 k->def_uni = true;
1394 k->def_multi = true;
1396 if (k->defmgmt)
1397 k->def_multi = true;
1399 if (info->attrs[NL80211_ATTR_KEY_TYPE])
1400 k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
1402 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) {
1403 struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES];
1404 int err = nla_parse_nested_deprecated(kdt,
1405 NUM_NL80211_KEY_DEFAULT_TYPES - 1,
1406 info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES],
1407 nl80211_key_default_policy,
1408 info->extack);
1409 if (err)
1410 return err;
1412 k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST];
1413 k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST];
1416 return 0;
1419 static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
1421 int err;
1423 memset(k, 0, sizeof(*k));
1424 k->idx = -1;
1425 k->type = -1;
1427 if (info->attrs[NL80211_ATTR_KEY])
1428 err = nl80211_parse_key_new(info, info->attrs[NL80211_ATTR_KEY], k);
1429 else
1430 err = nl80211_parse_key_old(info, k);
1432 if (err)
1433 return err;
1435 if ((k->def ? 1 : 0) + (k->defmgmt ? 1 : 0) +
1436 (k->defbeacon ? 1 : 0) > 1) {
1437 GENL_SET_ERR_MSG(info,
1438 "key with multiple default flags is invalid");
1439 return -EINVAL;
1442 if (k->defmgmt || k->defbeacon) {
1443 if (k->def_uni || !k->def_multi) {
1444 GENL_SET_ERR_MSG(info,
1445 "defmgmt/defbeacon key must be mcast");
1446 return -EINVAL;
1450 if (k->idx != -1) {
1451 if (k->defmgmt) {
1452 if (k->idx < 4 || k->idx > 5) {
1453 GENL_SET_ERR_MSG(info,
1454 "defmgmt key idx not 4 or 5");
1455 return -EINVAL;
1457 } else if (k->defbeacon) {
1458 if (k->idx < 6 || k->idx > 7) {
1459 GENL_SET_ERR_MSG(info,
1460 "defbeacon key idx not 6 or 7");
1461 return -EINVAL;
1463 } else if (k->def) {
1464 if (k->idx < 0 || k->idx > 3) {
1465 GENL_SET_ERR_MSG(info, "def key idx not 0-3");
1466 return -EINVAL;
1468 } else {
1469 if (k->idx < 0 || k->idx > 7) {
1470 GENL_SET_ERR_MSG(info, "key idx not 0-7");
1471 return -EINVAL;
1476 return 0;
1479 static struct cfg80211_cached_keys *
1480 nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
1481 struct genl_info *info, bool *no_ht)
1483 struct nlattr *keys = info->attrs[NL80211_ATTR_KEYS];
1484 struct key_parse parse;
1485 struct nlattr *key;
1486 struct cfg80211_cached_keys *result;
1487 int rem, err, def = 0;
1488 bool have_key = false;
1490 nla_for_each_nested(key, keys, rem) {
1491 have_key = true;
1492 break;
1495 if (!have_key)
1496 return NULL;
1498 result = kzalloc(sizeof(*result), GFP_KERNEL);
1499 if (!result)
1500 return ERR_PTR(-ENOMEM);
1502 result->def = -1;
1504 nla_for_each_nested(key, keys, rem) {
1505 memset(&parse, 0, sizeof(parse));
1506 parse.idx = -1;
1508 err = nl80211_parse_key_new(info, key, &parse);
1509 if (err)
1510 goto error;
1511 err = -EINVAL;
1512 if (!parse.p.key)
1513 goto error;
1514 if (parse.idx < 0 || parse.idx > 3) {
1515 GENL_SET_ERR_MSG(info, "key index out of range [0-3]");
1516 goto error;
1518 if (parse.def) {
1519 if (def) {
1520 GENL_SET_ERR_MSG(info,
1521 "only one key can be default");
1522 goto error;
1524 def = 1;
1525 result->def = parse.idx;
1526 if (!parse.def_uni || !parse.def_multi)
1527 goto error;
1528 } else if (parse.defmgmt)
1529 goto error;
1530 err = cfg80211_validate_key_settings(rdev, &parse.p,
1531 parse.idx, false, NULL);
1532 if (err)
1533 goto error;
1534 if (parse.p.cipher != WLAN_CIPHER_SUITE_WEP40 &&
1535 parse.p.cipher != WLAN_CIPHER_SUITE_WEP104) {
1536 GENL_SET_ERR_MSG(info, "connect key must be WEP");
1537 err = -EINVAL;
1538 goto error;
1540 result->params[parse.idx].cipher = parse.p.cipher;
1541 result->params[parse.idx].key_len = parse.p.key_len;
1542 result->params[parse.idx].key = result->data[parse.idx];
1543 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
1545 /* must be WEP key if we got here */
1546 if (no_ht)
1547 *no_ht = true;
1550 if (result->def < 0) {
1551 err = -EINVAL;
1552 GENL_SET_ERR_MSG(info, "need a default/TX key");
1553 goto error;
1556 return result;
1557 error:
1558 kfree(result);
1559 return ERR_PTR(err);
1562 static int nl80211_key_allowed(struct wireless_dev *wdev)
1564 lockdep_assert_wiphy(wdev->wiphy);
1566 switch (wdev->iftype) {
1567 case NL80211_IFTYPE_AP:
1568 case NL80211_IFTYPE_AP_VLAN:
1569 case NL80211_IFTYPE_P2P_GO:
1570 case NL80211_IFTYPE_MESH_POINT:
1571 break;
1572 case NL80211_IFTYPE_ADHOC:
1573 if (wdev->u.ibss.current_bss)
1574 return 0;
1575 return -ENOLINK;
1576 case NL80211_IFTYPE_STATION:
1577 case NL80211_IFTYPE_P2P_CLIENT:
1578 if (wdev->connected)
1579 return 0;
1580 return -ENOLINK;
1581 case NL80211_IFTYPE_NAN:
1582 if (wiphy_ext_feature_isset(wdev->wiphy,
1583 NL80211_EXT_FEATURE_SECURE_NAN))
1584 return 0;
1585 return -EINVAL;
1586 case NL80211_IFTYPE_UNSPECIFIED:
1587 case NL80211_IFTYPE_OCB:
1588 case NL80211_IFTYPE_MONITOR:
1589 case NL80211_IFTYPE_P2P_DEVICE:
1590 case NL80211_IFTYPE_WDS:
1591 case NUM_NL80211_IFTYPES:
1592 return -EINVAL;
1595 return 0;
1598 static struct ieee80211_channel *nl80211_get_valid_chan(struct wiphy *wiphy,
1599 u32 freq)
1601 struct ieee80211_channel *chan;
1603 chan = ieee80211_get_channel_khz(wiphy, freq);
1604 if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
1605 return NULL;
1606 return chan;
1609 static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes)
1611 struct nlattr *nl_modes = nla_nest_start_noflag(msg, attr);
1612 int i;
1614 if (!nl_modes)
1615 goto nla_put_failure;
1617 i = 0;
1618 while (ifmodes) {
1619 if ((ifmodes & 1) && nla_put_flag(msg, i))
1620 goto nla_put_failure;
1621 ifmodes >>= 1;
1622 i++;
1625 nla_nest_end(msg, nl_modes);
1626 return 0;
1628 nla_put_failure:
1629 return -ENOBUFS;
1632 static int nl80211_put_ifcomb_data(struct sk_buff *msg, bool large, int idx,
1633 const struct ieee80211_iface_combination *c,
1634 u16 nested)
1636 struct nlattr *nl_combi, *nl_limits;
1637 int i;
1639 nl_combi = nla_nest_start_noflag(msg, idx | nested);
1640 if (!nl_combi)
1641 goto nla_put_failure;
1643 nl_limits = nla_nest_start_noflag(msg, NL80211_IFACE_COMB_LIMITS |
1644 nested);
1645 if (!nl_limits)
1646 goto nla_put_failure;
1648 for (i = 0; i < c->n_limits; i++) {
1649 struct nlattr *nl_limit;
1651 nl_limit = nla_nest_start_noflag(msg, i + 1);
1652 if (!nl_limit)
1653 goto nla_put_failure;
1654 if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX, c->limits[i].max))
1655 goto nla_put_failure;
1656 if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES,
1657 c->limits[i].types))
1658 goto nla_put_failure;
1659 nla_nest_end(msg, nl_limit);
1662 nla_nest_end(msg, nl_limits);
1664 if (c->beacon_int_infra_match &&
1665 nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH))
1666 goto nla_put_failure;
1667 if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS,
1668 c->num_different_channels) ||
1669 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
1670 c->max_interfaces))
1671 goto nla_put_failure;
1672 if (large &&
1673 (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
1674 c->radar_detect_widths) ||
1675 nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
1676 c->radar_detect_regions)))
1677 goto nla_put_failure;
1678 if (c->beacon_int_min_gcd &&
1679 nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD,
1680 c->beacon_int_min_gcd))
1681 goto nla_put_failure;
1683 nla_nest_end(msg, nl_combi);
1685 return 0;
1686 nla_put_failure:
1687 return -ENOBUFS;
1690 static int nl80211_put_iface_combinations(struct wiphy *wiphy,
1691 struct sk_buff *msg,
1692 int attr, int radio,
1693 bool large, u16 nested)
1695 const struct ieee80211_iface_combination *c;
1696 struct nlattr *nl_combis;
1697 int i, n;
1699 nl_combis = nla_nest_start_noflag(msg, attr | nested);
1700 if (!nl_combis)
1701 goto nla_put_failure;
1703 if (radio >= 0) {
1704 c = wiphy->radio[0].iface_combinations;
1705 n = wiphy->radio[0].n_iface_combinations;
1706 } else {
1707 c = wiphy->iface_combinations;
1708 n = wiphy->n_iface_combinations;
1710 for (i = 0; i < n; i++)
1711 if (nl80211_put_ifcomb_data(msg, large, i + 1, &c[i], nested))
1712 goto nla_put_failure;
1714 nla_nest_end(msg, nl_combis);
1716 return 0;
1717 nla_put_failure:
1718 return -ENOBUFS;
1721 #ifdef CONFIG_PM
1722 static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
1723 struct sk_buff *msg)
1725 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
1726 struct nlattr *nl_tcp;
1728 if (!tcp)
1729 return 0;
1731 nl_tcp = nla_nest_start_noflag(msg,
1732 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
1733 if (!nl_tcp)
1734 return -ENOBUFS;
1736 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1737 tcp->data_payload_max))
1738 return -ENOBUFS;
1740 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
1741 tcp->data_payload_max))
1742 return -ENOBUFS;
1744 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
1745 return -ENOBUFS;
1747 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
1748 sizeof(*tcp->tok), tcp->tok))
1749 return -ENOBUFS;
1751 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
1752 tcp->data_interval_max))
1753 return -ENOBUFS;
1755 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
1756 tcp->wake_payload_max))
1757 return -ENOBUFS;
1759 nla_nest_end(msg, nl_tcp);
1760 return 0;
1763 static int nl80211_send_wowlan(struct sk_buff *msg,
1764 struct cfg80211_registered_device *rdev,
1765 bool large)
1767 struct nlattr *nl_wowlan;
1769 if (!rdev->wiphy.wowlan)
1770 return 0;
1772 nl_wowlan = nla_nest_start_noflag(msg,
1773 NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
1774 if (!nl_wowlan)
1775 return -ENOBUFS;
1777 if (((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
1778 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
1779 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
1780 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
1781 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
1782 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
1783 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
1784 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
1785 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
1786 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
1787 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
1788 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
1789 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
1790 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
1791 ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
1792 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
1793 return -ENOBUFS;
1795 if (rdev->wiphy.wowlan->n_patterns) {
1796 struct nl80211_pattern_support pat = {
1797 .max_patterns = rdev->wiphy.wowlan->n_patterns,
1798 .min_pattern_len = rdev->wiphy.wowlan->pattern_min_len,
1799 .max_pattern_len = rdev->wiphy.wowlan->pattern_max_len,
1800 .max_pkt_offset = rdev->wiphy.wowlan->max_pkt_offset,
1803 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
1804 sizeof(pat), &pat))
1805 return -ENOBUFS;
1808 if ((rdev->wiphy.wowlan->flags & WIPHY_WOWLAN_NET_DETECT) &&
1809 nla_put_u32(msg, NL80211_WOWLAN_TRIG_NET_DETECT,
1810 rdev->wiphy.wowlan->max_nd_match_sets))
1811 return -ENOBUFS;
1813 if (large && nl80211_send_wowlan_tcp_caps(rdev, msg))
1814 return -ENOBUFS;
1816 nla_nest_end(msg, nl_wowlan);
1818 return 0;
1820 #endif
1822 static int nl80211_send_coalesce(struct sk_buff *msg,
1823 struct cfg80211_registered_device *rdev)
1825 struct nl80211_coalesce_rule_support rule;
1827 if (!rdev->wiphy.coalesce)
1828 return 0;
1830 rule.max_rules = rdev->wiphy.coalesce->n_rules;
1831 rule.max_delay = rdev->wiphy.coalesce->max_delay;
1832 rule.pat.max_patterns = rdev->wiphy.coalesce->n_patterns;
1833 rule.pat.min_pattern_len = rdev->wiphy.coalesce->pattern_min_len;
1834 rule.pat.max_pattern_len = rdev->wiphy.coalesce->pattern_max_len;
1835 rule.pat.max_pkt_offset = rdev->wiphy.coalesce->max_pkt_offset;
1837 if (nla_put(msg, NL80211_ATTR_COALESCE_RULE, sizeof(rule), &rule))
1838 return -ENOBUFS;
1840 return 0;
1843 static int
1844 nl80211_send_iftype_data(struct sk_buff *msg,
1845 const struct ieee80211_supported_band *sband,
1846 const struct ieee80211_sband_iftype_data *iftdata)
1848 const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap;
1849 const struct ieee80211_sta_eht_cap *eht_cap = &iftdata->eht_cap;
1851 if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES,
1852 iftdata->types_mask))
1853 return -ENOBUFS;
1855 if (he_cap->has_he) {
1856 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MAC,
1857 sizeof(he_cap->he_cap_elem.mac_cap_info),
1858 he_cap->he_cap_elem.mac_cap_info) ||
1859 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PHY,
1860 sizeof(he_cap->he_cap_elem.phy_cap_info),
1861 he_cap->he_cap_elem.phy_cap_info) ||
1862 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_MCS_SET,
1863 sizeof(he_cap->he_mcs_nss_supp),
1864 &he_cap->he_mcs_nss_supp) ||
1865 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE,
1866 sizeof(he_cap->ppe_thres), he_cap->ppe_thres))
1867 return -ENOBUFS;
1870 if (eht_cap->has_eht && he_cap->has_he) {
1871 u8 mcs_nss_size, ppe_thresh_size;
1872 u16 ppe_thres_hdr;
1873 bool is_ap;
1875 is_ap = iftdata->types_mask & BIT(NL80211_IFTYPE_AP) ||
1876 iftdata->types_mask & BIT(NL80211_IFTYPE_P2P_GO);
1878 mcs_nss_size =
1879 ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem,
1880 &eht_cap->eht_cap_elem,
1881 is_ap);
1883 ppe_thres_hdr = get_unaligned_le16(&eht_cap->eht_ppe_thres[0]);
1884 ppe_thresh_size =
1885 ieee80211_eht_ppe_size(ppe_thres_hdr,
1886 eht_cap->eht_cap_elem.phy_cap_info);
1888 if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC,
1889 sizeof(eht_cap->eht_cap_elem.mac_cap_info),
1890 eht_cap->eht_cap_elem.mac_cap_info) ||
1891 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
1892 sizeof(eht_cap->eht_cap_elem.phy_cap_info),
1893 eht_cap->eht_cap_elem.phy_cap_info) ||
1894 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
1895 mcs_nss_size, &eht_cap->eht_mcs_nss_supp) ||
1896 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
1897 ppe_thresh_size, eht_cap->eht_ppe_thres))
1898 return -ENOBUFS;
1901 if (sband->band == NL80211_BAND_6GHZ &&
1902 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA,
1903 sizeof(iftdata->he_6ghz_capa),
1904 &iftdata->he_6ghz_capa))
1905 return -ENOBUFS;
1907 if (iftdata->vendor_elems.data && iftdata->vendor_elems.len &&
1908 nla_put(msg, NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS,
1909 iftdata->vendor_elems.len, iftdata->vendor_elems.data))
1910 return -ENOBUFS;
1912 return 0;
1915 static int nl80211_send_band_rateinfo(struct sk_buff *msg,
1916 struct ieee80211_supported_band *sband,
1917 bool large)
1919 struct nlattr *nl_rates, *nl_rate;
1920 struct ieee80211_rate *rate;
1921 int i;
1923 /* add HT info */
1924 if (sband->ht_cap.ht_supported &&
1925 (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET,
1926 sizeof(sband->ht_cap.mcs),
1927 &sband->ht_cap.mcs) ||
1928 nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA,
1929 sband->ht_cap.cap) ||
1930 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
1931 sband->ht_cap.ampdu_factor) ||
1932 nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
1933 sband->ht_cap.ampdu_density)))
1934 return -ENOBUFS;
1936 /* add VHT info */
1937 if (sband->vht_cap.vht_supported &&
1938 (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET,
1939 sizeof(sband->vht_cap.vht_mcs),
1940 &sband->vht_cap.vht_mcs) ||
1941 nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA,
1942 sband->vht_cap.cap)))
1943 return -ENOBUFS;
1945 if (large && sband->n_iftype_data) {
1946 struct nlattr *nl_iftype_data =
1947 nla_nest_start_noflag(msg,
1948 NL80211_BAND_ATTR_IFTYPE_DATA);
1949 const struct ieee80211_sband_iftype_data *iftd;
1950 int err;
1952 if (!nl_iftype_data)
1953 return -ENOBUFS;
1955 for_each_sband_iftype_data(sband, i, iftd) {
1956 struct nlattr *iftdata;
1958 iftdata = nla_nest_start_noflag(msg, i + 1);
1959 if (!iftdata)
1960 return -ENOBUFS;
1962 err = nl80211_send_iftype_data(msg, sband, iftd);
1963 if (err)
1964 return err;
1966 nla_nest_end(msg, iftdata);
1969 nla_nest_end(msg, nl_iftype_data);
1972 /* add EDMG info */
1973 if (large && sband->edmg_cap.channels &&
1974 (nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_CHANNELS,
1975 sband->edmg_cap.channels) ||
1976 nla_put_u8(msg, NL80211_BAND_ATTR_EDMG_BW_CONFIG,
1977 sband->edmg_cap.bw_config)))
1979 return -ENOBUFS;
1981 /* add bitrates */
1982 nl_rates = nla_nest_start_noflag(msg, NL80211_BAND_ATTR_RATES);
1983 if (!nl_rates)
1984 return -ENOBUFS;
1986 for (i = 0; i < sband->n_bitrates; i++) {
1987 nl_rate = nla_nest_start_noflag(msg, i);
1988 if (!nl_rate)
1989 return -ENOBUFS;
1991 rate = &sband->bitrates[i];
1992 if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE,
1993 rate->bitrate))
1994 return -ENOBUFS;
1995 if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
1996 nla_put_flag(msg,
1997 NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE))
1998 return -ENOBUFS;
2000 nla_nest_end(msg, nl_rate);
2003 nla_nest_end(msg, nl_rates);
2005 /* S1G capabilities */
2006 if (sband->band == NL80211_BAND_S1GHZ && sband->s1g_cap.s1g &&
2007 (nla_put(msg, NL80211_BAND_ATTR_S1G_CAPA,
2008 sizeof(sband->s1g_cap.cap),
2009 sband->s1g_cap.cap) ||
2010 nla_put(msg, NL80211_BAND_ATTR_S1G_MCS_NSS_SET,
2011 sizeof(sband->s1g_cap.nss_mcs),
2012 sband->s1g_cap.nss_mcs)))
2013 return -ENOBUFS;
2015 return 0;
2018 static int
2019 nl80211_send_mgmt_stypes(struct sk_buff *msg,
2020 const struct ieee80211_txrx_stypes *mgmt_stypes)
2022 u16 stypes;
2023 struct nlattr *nl_ftypes, *nl_ifs;
2024 enum nl80211_iftype ift;
2025 int i;
2027 if (!mgmt_stypes)
2028 return 0;
2030 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_TX_FRAME_TYPES);
2031 if (!nl_ifs)
2032 return -ENOBUFS;
2034 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
2035 nl_ftypes = nla_nest_start_noflag(msg, ift);
2036 if (!nl_ftypes)
2037 return -ENOBUFS;
2038 i = 0;
2039 stypes = mgmt_stypes[ift].tx;
2040 while (stypes) {
2041 if ((stypes & 1) &&
2042 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
2043 (i << 4) | IEEE80211_FTYPE_MGMT))
2044 return -ENOBUFS;
2045 stypes >>= 1;
2046 i++;
2048 nla_nest_end(msg, nl_ftypes);
2051 nla_nest_end(msg, nl_ifs);
2053 nl_ifs = nla_nest_start_noflag(msg, NL80211_ATTR_RX_FRAME_TYPES);
2054 if (!nl_ifs)
2055 return -ENOBUFS;
2057 for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) {
2058 nl_ftypes = nla_nest_start_noflag(msg, ift);
2059 if (!nl_ftypes)
2060 return -ENOBUFS;
2061 i = 0;
2062 stypes = mgmt_stypes[ift].rx;
2063 while (stypes) {
2064 if ((stypes & 1) &&
2065 nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE,
2066 (i << 4) | IEEE80211_FTYPE_MGMT))
2067 return -ENOBUFS;
2068 stypes >>= 1;
2069 i++;
2071 nla_nest_end(msg, nl_ftypes);
2073 nla_nest_end(msg, nl_ifs);
2075 return 0;
2078 #define CMD(op, n) \
2079 do { \
2080 if (rdev->ops->op) { \
2081 i++; \
2082 if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \
2083 goto nla_put_failure; \
2085 } while (0)
2087 static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
2088 struct sk_buff *msg)
2090 int i = 0;
2093 * do *NOT* add anything into this function, new things need to be
2094 * advertised only to new versions of userspace that can deal with
2095 * the split (and they can't possibly care about new features...
2097 CMD(add_virtual_intf, NEW_INTERFACE);
2098 CMD(change_virtual_intf, SET_INTERFACE);
2099 CMD(add_key, NEW_KEY);
2100 CMD(start_ap, START_AP);
2101 CMD(add_station, NEW_STATION);
2102 CMD(add_mpath, NEW_MPATH);
2103 CMD(update_mesh_config, SET_MESH_CONFIG);
2104 CMD(change_bss, SET_BSS);
2105 CMD(auth, AUTHENTICATE);
2106 CMD(assoc, ASSOCIATE);
2107 CMD(deauth, DEAUTHENTICATE);
2108 CMD(disassoc, DISASSOCIATE);
2109 CMD(join_ibss, JOIN_IBSS);
2110 CMD(join_mesh, JOIN_MESH);
2111 CMD(set_pmksa, SET_PMKSA);
2112 CMD(del_pmksa, DEL_PMKSA);
2113 CMD(flush_pmksa, FLUSH_PMKSA);
2114 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)
2115 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
2116 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
2117 CMD(mgmt_tx, FRAME);
2118 CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL);
2119 if (rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
2120 i++;
2121 if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS))
2122 goto nla_put_failure;
2124 if (rdev->ops->set_monitor_channel || rdev->ops->start_ap ||
2125 rdev->ops->join_mesh) {
2126 i++;
2127 if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL))
2128 goto nla_put_failure;
2130 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
2131 CMD(tdls_mgmt, TDLS_MGMT);
2132 CMD(tdls_oper, TDLS_OPER);
2134 if (rdev->wiphy.max_sched_scan_reqs)
2135 CMD(sched_scan_start, START_SCHED_SCAN);
2136 CMD(probe_client, PROBE_CLIENT);
2137 CMD(set_noack_map, SET_NOACK_MAP);
2138 if (rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
2139 i++;
2140 if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS))
2141 goto nla_put_failure;
2143 CMD(start_p2p_device, START_P2P_DEVICE);
2144 CMD(set_mcast_rate, SET_MCAST_RATE);
2145 #ifdef CONFIG_NL80211_TESTMODE
2146 CMD(testmode_cmd, TESTMODE);
2147 #endif
2149 if (rdev->ops->connect || rdev->ops->auth) {
2150 i++;
2151 if (nla_put_u32(msg, i, NL80211_CMD_CONNECT))
2152 goto nla_put_failure;
2155 if (rdev->ops->disconnect || rdev->ops->deauth) {
2156 i++;
2157 if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT))
2158 goto nla_put_failure;
2161 return i;
2162 nla_put_failure:
2163 return -ENOBUFS;
2166 static int
2167 nl80211_send_pmsr_ftm_capa(const struct cfg80211_pmsr_capabilities *cap,
2168 struct sk_buff *msg)
2170 struct nlattr *ftm;
2172 if (!cap->ftm.supported)
2173 return 0;
2175 ftm = nla_nest_start_noflag(msg, NL80211_PMSR_TYPE_FTM);
2176 if (!ftm)
2177 return -ENOBUFS;
2179 if (cap->ftm.asap && nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_ASAP))
2180 return -ENOBUFS;
2181 if (cap->ftm.non_asap &&
2182 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_ASAP))
2183 return -ENOBUFS;
2184 if (cap->ftm.request_lci &&
2185 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_LCI))
2186 return -ENOBUFS;
2187 if (cap->ftm.request_civicloc &&
2188 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_REQ_CIVICLOC))
2189 return -ENOBUFS;
2190 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_PREAMBLES,
2191 cap->ftm.preambles))
2192 return -ENOBUFS;
2193 if (nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_BANDWIDTHS,
2194 cap->ftm.bandwidths))
2195 return -ENOBUFS;
2196 if (cap->ftm.max_bursts_exponent >= 0 &&
2197 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_BURSTS_EXPONENT,
2198 cap->ftm.max_bursts_exponent))
2199 return -ENOBUFS;
2200 if (cap->ftm.max_ftms_per_burst &&
2201 nla_put_u32(msg, NL80211_PMSR_FTM_CAPA_ATTR_MAX_FTMS_PER_BURST,
2202 cap->ftm.max_ftms_per_burst))
2203 return -ENOBUFS;
2204 if (cap->ftm.trigger_based &&
2205 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_TRIGGER_BASED))
2206 return -ENOBUFS;
2207 if (cap->ftm.non_trigger_based &&
2208 nla_put_flag(msg, NL80211_PMSR_FTM_CAPA_ATTR_NON_TRIGGER_BASED))
2209 return -ENOBUFS;
2211 nla_nest_end(msg, ftm);
2212 return 0;
2215 static int nl80211_send_pmsr_capa(struct cfg80211_registered_device *rdev,
2216 struct sk_buff *msg)
2218 const struct cfg80211_pmsr_capabilities *cap = rdev->wiphy.pmsr_capa;
2219 struct nlattr *pmsr, *caps;
2221 if (!cap)
2222 return 0;
2225 * we don't need to clean up anything here since the caller
2226 * will genlmsg_cancel() if we fail
2229 pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS);
2230 if (!pmsr)
2231 return -ENOBUFS;
2233 if (nla_put_u32(msg, NL80211_PMSR_ATTR_MAX_PEERS, cap->max_peers))
2234 return -ENOBUFS;
2236 if (cap->report_ap_tsf &&
2237 nla_put_flag(msg, NL80211_PMSR_ATTR_REPORT_AP_TSF))
2238 return -ENOBUFS;
2240 if (cap->randomize_mac_addr &&
2241 nla_put_flag(msg, NL80211_PMSR_ATTR_RANDOMIZE_MAC_ADDR))
2242 return -ENOBUFS;
2244 caps = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_TYPE_CAPA);
2245 if (!caps)
2246 return -ENOBUFS;
2248 if (nl80211_send_pmsr_ftm_capa(cap, msg))
2249 return -ENOBUFS;
2251 nla_nest_end(msg, caps);
2252 nla_nest_end(msg, pmsr);
2254 return 0;
2257 static int
2258 nl80211_put_iftype_akm_suites(struct cfg80211_registered_device *rdev,
2259 struct sk_buff *msg)
2261 int i;
2262 struct nlattr *nested, *nested_akms;
2263 const struct wiphy_iftype_akm_suites *iftype_akms;
2265 if (!rdev->wiphy.num_iftype_akm_suites ||
2266 !rdev->wiphy.iftype_akm_suites)
2267 return 0;
2269 nested = nla_nest_start(msg, NL80211_ATTR_IFTYPE_AKM_SUITES);
2270 if (!nested)
2271 return -ENOBUFS;
2273 for (i = 0; i < rdev->wiphy.num_iftype_akm_suites; i++) {
2274 nested_akms = nla_nest_start(msg, i + 1);
2275 if (!nested_akms)
2276 return -ENOBUFS;
2278 iftype_akms = &rdev->wiphy.iftype_akm_suites[i];
2280 if (nl80211_put_iftypes(msg, NL80211_IFTYPE_AKM_ATTR_IFTYPES,
2281 iftype_akms->iftypes_mask))
2282 return -ENOBUFS;
2284 if (nla_put(msg, NL80211_IFTYPE_AKM_ATTR_SUITES,
2285 sizeof(u32) * iftype_akms->n_akm_suites,
2286 iftype_akms->akm_suites)) {
2287 return -ENOBUFS;
2289 nla_nest_end(msg, nested_akms);
2292 nla_nest_end(msg, nested);
2294 return 0;
2297 static int
2298 nl80211_put_tid_config_support(struct cfg80211_registered_device *rdev,
2299 struct sk_buff *msg)
2301 struct nlattr *supp;
2303 if (!rdev->wiphy.tid_config_support.vif &&
2304 !rdev->wiphy.tid_config_support.peer)
2305 return 0;
2307 supp = nla_nest_start(msg, NL80211_ATTR_TID_CONFIG);
2308 if (!supp)
2309 return -ENOSPC;
2311 if (rdev->wiphy.tid_config_support.vif &&
2312 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_VIF_SUPP,
2313 rdev->wiphy.tid_config_support.vif,
2314 NL80211_TID_CONFIG_ATTR_PAD))
2315 goto fail;
2317 if (rdev->wiphy.tid_config_support.peer &&
2318 nla_put_u64_64bit(msg, NL80211_TID_CONFIG_ATTR_PEER_SUPP,
2319 rdev->wiphy.tid_config_support.peer,
2320 NL80211_TID_CONFIG_ATTR_PAD))
2321 goto fail;
2323 /* for now we just use the same value ... makes more sense */
2324 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
2325 rdev->wiphy.tid_config_support.max_retry))
2326 goto fail;
2327 if (nla_put_u8(msg, NL80211_TID_CONFIG_ATTR_RETRY_LONG,
2328 rdev->wiphy.tid_config_support.max_retry))
2329 goto fail;
2331 nla_nest_end(msg, supp);
2333 return 0;
2334 fail:
2335 nla_nest_cancel(msg, supp);
2336 return -ENOBUFS;
2339 static int
2340 nl80211_put_sar_specs(struct cfg80211_registered_device *rdev,
2341 struct sk_buff *msg)
2343 struct nlattr *sar_capa, *specs, *sub_freq_range;
2344 u8 num_freq_ranges;
2345 int i;
2347 if (!rdev->wiphy.sar_capa)
2348 return 0;
2350 num_freq_ranges = rdev->wiphy.sar_capa->num_freq_ranges;
2352 sar_capa = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
2353 if (!sar_capa)
2354 return -ENOSPC;
2356 if (nla_put_u32(msg, NL80211_SAR_ATTR_TYPE, rdev->wiphy.sar_capa->type))
2357 goto fail;
2359 specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
2360 if (!specs)
2361 goto fail;
2363 /* report supported freq_ranges */
2364 for (i = 0; i < num_freq_ranges; i++) {
2365 sub_freq_range = nla_nest_start(msg, i + 1);
2366 if (!sub_freq_range)
2367 goto fail;
2369 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_START_FREQ,
2370 rdev->wiphy.sar_capa->freq_ranges[i].start_freq))
2371 goto fail;
2373 if (nla_put_u32(msg, NL80211_SAR_ATTR_SPECS_END_FREQ,
2374 rdev->wiphy.sar_capa->freq_ranges[i].end_freq))
2375 goto fail;
2377 nla_nest_end(msg, sub_freq_range);
2380 nla_nest_end(msg, specs);
2381 nla_nest_end(msg, sar_capa);
2383 return 0;
2384 fail:
2385 nla_nest_cancel(msg, sar_capa);
2386 return -ENOBUFS;
2389 static int nl80211_put_mbssid_support(struct wiphy *wiphy, struct sk_buff *msg)
2391 struct nlattr *config;
2393 if (!wiphy->mbssid_max_interfaces)
2394 return 0;
2396 config = nla_nest_start(msg, NL80211_ATTR_MBSSID_CONFIG);
2397 if (!config)
2398 return -ENOBUFS;
2400 if (nla_put_u8(msg, NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES,
2401 wiphy->mbssid_max_interfaces))
2402 goto fail;
2404 if (wiphy->ema_max_profile_periodicity &&
2405 nla_put_u8(msg,
2406 NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY,
2407 wiphy->ema_max_profile_periodicity))
2408 goto fail;
2410 nla_nest_end(msg, config);
2411 return 0;
2413 fail:
2414 nla_nest_cancel(msg, config);
2415 return -ENOBUFS;
2418 static int nl80211_put_radio(struct wiphy *wiphy, struct sk_buff *msg, int idx)
2420 const struct wiphy_radio *r = &wiphy->radio[idx];
2421 struct nlattr *radio, *freq;
2422 int i;
2424 radio = nla_nest_start(msg, idx);
2425 if (!radio)
2426 return -ENOBUFS;
2428 if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx))
2429 goto nla_put_failure;
2431 if (r->antenna_mask &&
2432 nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_ANTENNA_MASK,
2433 r->antenna_mask))
2434 goto nla_put_failure;
2436 for (i = 0; i < r->n_freq_range; i++) {
2437 const struct wiphy_radio_freq_range *range = &r->freq_range[i];
2439 freq = nla_nest_start(msg, NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE);
2440 if (!freq)
2441 goto nla_put_failure;
2443 if (nla_put_u32(msg, NL80211_WIPHY_RADIO_FREQ_ATTR_START,
2444 range->start_freq) ||
2445 nla_put_u32(msg, NL80211_WIPHY_RADIO_FREQ_ATTR_END,
2446 range->end_freq))
2447 goto nla_put_failure;
2449 nla_nest_end(msg, freq);
2452 for (i = 0; i < r->n_iface_combinations; i++)
2453 if (nl80211_put_ifcomb_data(msg, true,
2454 NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION,
2455 &r->iface_combinations[i],
2456 NLA_F_NESTED))
2457 goto nla_put_failure;
2459 nla_nest_end(msg, radio);
2461 return 0;
2463 nla_put_failure:
2464 return -ENOBUFS;
2467 static int nl80211_put_radios(struct wiphy *wiphy, struct sk_buff *msg)
2469 struct nlattr *radios;
2470 int i;
2472 if (!wiphy->n_radio)
2473 return 0;
2475 radios = nla_nest_start(msg, NL80211_ATTR_WIPHY_RADIOS);
2476 if (!radios)
2477 return -ENOBUFS;
2479 for (i = 0; i < wiphy->n_radio; i++)
2480 if (nl80211_put_radio(wiphy, msg, i))
2481 goto fail;
2483 nla_nest_end(msg, radios);
2485 if (nl80211_put_iface_combinations(wiphy, msg,
2486 NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS,
2487 -1, true, NLA_F_NESTED))
2488 return -ENOBUFS;
2490 return 0;
2492 fail:
2493 nla_nest_cancel(msg, radios);
2494 return -ENOBUFS;
2497 struct nl80211_dump_wiphy_state {
2498 s64 filter_wiphy;
2499 long start;
2500 long split_start, band_start, chan_start, capa_start;
2501 bool split;
2504 static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
2505 enum nl80211_commands cmd,
2506 struct sk_buff *msg, u32 portid, u32 seq,
2507 int flags, struct nl80211_dump_wiphy_state *state)
2509 void *hdr;
2510 struct nlattr *nl_bands, *nl_band;
2511 struct nlattr *nl_freqs, *nl_freq;
2512 struct nlattr *nl_cmds;
2513 enum nl80211_band band;
2514 struct ieee80211_channel *chan;
2515 int i;
2516 const struct ieee80211_txrx_stypes *mgmt_stypes =
2517 rdev->wiphy.mgmt_stypes;
2518 u32 features;
2520 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
2521 if (!hdr)
2522 return -ENOBUFS;
2524 if (WARN_ON(!state))
2525 return -EINVAL;
2527 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
2528 nla_put_string(msg, NL80211_ATTR_WIPHY_NAME,
2529 wiphy_name(&rdev->wiphy)) ||
2530 nla_put_u32(msg, NL80211_ATTR_GENERATION,
2531 cfg80211_rdev_list_generation))
2532 goto nla_put_failure;
2534 if (cmd != NL80211_CMD_NEW_WIPHY)
2535 goto finish;
2537 switch (state->split_start) {
2538 case 0:
2539 if (nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
2540 rdev->wiphy.retry_short) ||
2541 nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
2542 rdev->wiphy.retry_long) ||
2543 nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
2544 rdev->wiphy.frag_threshold) ||
2545 nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
2546 rdev->wiphy.rts_threshold) ||
2547 nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
2548 rdev->wiphy.coverage_class) ||
2549 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
2550 rdev->wiphy.max_scan_ssids) ||
2551 nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS,
2552 rdev->wiphy.max_sched_scan_ssids) ||
2553 nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
2554 rdev->wiphy.max_scan_ie_len) ||
2555 nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN,
2556 rdev->wiphy.max_sched_scan_ie_len) ||
2557 nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS,
2558 rdev->wiphy.max_match_sets))
2559 goto nla_put_failure;
2561 if ((rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) &&
2562 nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN))
2563 goto nla_put_failure;
2564 if ((rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) &&
2565 nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH))
2566 goto nla_put_failure;
2567 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) &&
2568 nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD))
2569 goto nla_put_failure;
2570 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) &&
2571 nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT))
2572 goto nla_put_failure;
2573 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
2574 nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT))
2575 goto nla_put_failure;
2576 if ((rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) &&
2577 nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP))
2578 goto nla_put_failure;
2579 state->split_start++;
2580 if (state->split)
2581 break;
2582 fallthrough;
2583 case 1:
2584 if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES,
2585 sizeof(u32) * rdev->wiphy.n_cipher_suites,
2586 rdev->wiphy.cipher_suites))
2587 goto nla_put_failure;
2589 if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS,
2590 rdev->wiphy.max_num_pmkids))
2591 goto nla_put_failure;
2593 if ((rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
2594 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
2595 goto nla_put_failure;
2597 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
2598 rdev->wiphy.available_antennas_tx) ||
2599 nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
2600 rdev->wiphy.available_antennas_rx))
2601 goto nla_put_failure;
2603 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
2604 nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD,
2605 rdev->wiphy.probe_resp_offload))
2606 goto nla_put_failure;
2608 if ((rdev->wiphy.available_antennas_tx ||
2609 rdev->wiphy.available_antennas_rx) &&
2610 rdev->ops->get_antenna) {
2611 u32 tx_ant = 0, rx_ant = 0;
2612 int res;
2614 res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
2615 if (!res) {
2616 if (nla_put_u32(msg,
2617 NL80211_ATTR_WIPHY_ANTENNA_TX,
2618 tx_ant) ||
2619 nla_put_u32(msg,
2620 NL80211_ATTR_WIPHY_ANTENNA_RX,
2621 rx_ant))
2622 goto nla_put_failure;
2626 state->split_start++;
2627 if (state->split)
2628 break;
2629 fallthrough;
2630 case 2:
2631 if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES,
2632 rdev->wiphy.interface_modes))
2633 goto nla_put_failure;
2634 state->split_start++;
2635 if (state->split)
2636 break;
2637 fallthrough;
2638 case 3:
2639 nl_bands = nla_nest_start_noflag(msg,
2640 NL80211_ATTR_WIPHY_BANDS);
2641 if (!nl_bands)
2642 goto nla_put_failure;
2644 for (band = state->band_start;
2645 band < (state->split ?
2646 NUM_NL80211_BANDS :
2647 NL80211_BAND_60GHZ + 1);
2648 band++) {
2649 struct ieee80211_supported_band *sband;
2651 /* omit higher bands for ancient software */
2652 if (band > NL80211_BAND_5GHZ && !state->split)
2653 break;
2655 sband = rdev->wiphy.bands[band];
2657 if (!sband)
2658 continue;
2660 nl_band = nla_nest_start_noflag(msg, band);
2661 if (!nl_band)
2662 goto nla_put_failure;
2664 switch (state->chan_start) {
2665 case 0:
2666 if (nl80211_send_band_rateinfo(msg, sband,
2667 state->split))
2668 goto nla_put_failure;
2669 state->chan_start++;
2670 if (state->split)
2671 break;
2672 fallthrough;
2673 default:
2674 /* add frequencies */
2675 nl_freqs = nla_nest_start_noflag(msg,
2676 NL80211_BAND_ATTR_FREQS);
2677 if (!nl_freqs)
2678 goto nla_put_failure;
2680 for (i = state->chan_start - 1;
2681 i < sband->n_channels;
2682 i++) {
2683 nl_freq = nla_nest_start_noflag(msg,
2685 if (!nl_freq)
2686 goto nla_put_failure;
2688 chan = &sband->channels[i];
2690 if (nl80211_msg_put_channel(
2691 msg, &rdev->wiphy, chan,
2692 state->split))
2693 goto nla_put_failure;
2695 nla_nest_end(msg, nl_freq);
2696 if (state->split)
2697 break;
2699 if (i < sband->n_channels)
2700 state->chan_start = i + 2;
2701 else
2702 state->chan_start = 0;
2703 nla_nest_end(msg, nl_freqs);
2706 nla_nest_end(msg, nl_band);
2708 if (state->split) {
2709 /* start again here */
2710 if (state->chan_start)
2711 band--;
2712 break;
2715 nla_nest_end(msg, nl_bands);
2717 if (band < NUM_NL80211_BANDS)
2718 state->band_start = band + 1;
2719 else
2720 state->band_start = 0;
2722 /* if bands & channels are done, continue outside */
2723 if (state->band_start == 0 && state->chan_start == 0)
2724 state->split_start++;
2725 if (state->split)
2726 break;
2727 fallthrough;
2728 case 4:
2729 nl_cmds = nla_nest_start_noflag(msg,
2730 NL80211_ATTR_SUPPORTED_COMMANDS);
2731 if (!nl_cmds)
2732 goto nla_put_failure;
2734 i = nl80211_add_commands_unsplit(rdev, msg);
2735 if (i < 0)
2736 goto nla_put_failure;
2737 if (state->split) {
2738 CMD(crit_proto_start, CRIT_PROTOCOL_START);
2739 CMD(crit_proto_stop, CRIT_PROTOCOL_STOP);
2740 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH)
2741 CMD(channel_switch, CHANNEL_SWITCH);
2742 CMD(set_qos_map, SET_QOS_MAP);
2743 if (rdev->wiphy.features &
2744 NL80211_FEATURE_SUPPORTS_WMM_ADMISSION)
2745 CMD(add_tx_ts, ADD_TX_TS);
2746 CMD(set_multicast_to_unicast, SET_MULTICAST_TO_UNICAST);
2747 CMD(update_connect_params, UPDATE_CONNECT_PARAMS);
2748 CMD(update_ft_ies, UPDATE_FT_IES);
2749 if (rdev->wiphy.sar_capa)
2750 CMD(set_sar_specs, SET_SAR_SPECS);
2752 #undef CMD
2754 nla_nest_end(msg, nl_cmds);
2755 state->split_start++;
2756 if (state->split)
2757 break;
2758 fallthrough;
2759 case 5:
2760 if (rdev->ops->remain_on_channel &&
2761 (rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) &&
2762 nla_put_u32(msg,
2763 NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
2764 rdev->wiphy.max_remain_on_channel_duration))
2765 goto nla_put_failure;
2767 if ((rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) &&
2768 nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK))
2769 goto nla_put_failure;
2771 state->split_start++;
2772 if (state->split)
2773 break;
2774 fallthrough;
2775 case 6:
2776 #ifdef CONFIG_PM
2777 if (nl80211_send_wowlan(msg, rdev, state->split))
2778 goto nla_put_failure;
2779 state->split_start++;
2780 if (state->split)
2781 break;
2782 #else
2783 state->split_start++;
2784 #endif
2785 fallthrough;
2786 case 7:
2787 if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES,
2788 rdev->wiphy.software_iftypes))
2789 goto nla_put_failure;
2791 if (nl80211_put_iface_combinations(&rdev->wiphy, msg,
2792 NL80211_ATTR_INTERFACE_COMBINATIONS,
2793 rdev->wiphy.n_radio ? 0 : -1,
2794 state->split, 0))
2795 goto nla_put_failure;
2797 state->split_start++;
2798 if (state->split)
2799 break;
2800 fallthrough;
2801 case 8:
2802 if ((rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) &&
2803 nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME,
2804 rdev->wiphy.ap_sme_capa))
2805 goto nla_put_failure;
2807 features = rdev->wiphy.features;
2809 * We can only add the per-channel limit information if the
2810 * dump is split, otherwise it makes it too big. Therefore
2811 * only advertise it in that case.
2813 if (state->split)
2814 features |= NL80211_FEATURE_ADVERTISE_CHAN_LIMITS;
2815 if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, features))
2816 goto nla_put_failure;
2818 if (rdev->wiphy.ht_capa_mod_mask &&
2819 nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK,
2820 sizeof(*rdev->wiphy.ht_capa_mod_mask),
2821 rdev->wiphy.ht_capa_mod_mask))
2822 goto nla_put_failure;
2824 if (rdev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME &&
2825 rdev->wiphy.max_acl_mac_addrs &&
2826 nla_put_u32(msg, NL80211_ATTR_MAC_ACL_MAX,
2827 rdev->wiphy.max_acl_mac_addrs))
2828 goto nla_put_failure;
2831 * Any information below this point is only available to
2832 * applications that can deal with it being split. This
2833 * helps ensure that newly added capabilities don't break
2834 * older tools by overrunning their buffers.
2836 * We still increment split_start so that in the split
2837 * case we'll continue with more data in the next round,
2838 * but break unconditionally so unsplit data stops here.
2840 if (state->split)
2841 state->split_start++;
2842 else
2843 state->split_start = 0;
2844 break;
2845 case 9:
2846 if (nl80211_send_mgmt_stypes(msg, mgmt_stypes))
2847 goto nla_put_failure;
2849 if (nla_put_u32(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS,
2850 rdev->wiphy.max_sched_scan_plans) ||
2851 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL,
2852 rdev->wiphy.max_sched_scan_plan_interval) ||
2853 nla_put_u32(msg, NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
2854 rdev->wiphy.max_sched_scan_plan_iterations))
2855 goto nla_put_failure;
2857 if (rdev->wiphy.extended_capabilities &&
2858 (nla_put(msg, NL80211_ATTR_EXT_CAPA,
2859 rdev->wiphy.extended_capabilities_len,
2860 rdev->wiphy.extended_capabilities) ||
2861 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
2862 rdev->wiphy.extended_capabilities_len,
2863 rdev->wiphy.extended_capabilities_mask)))
2864 goto nla_put_failure;
2866 if (rdev->wiphy.vht_capa_mod_mask &&
2867 nla_put(msg, NL80211_ATTR_VHT_CAPABILITY_MASK,
2868 sizeof(*rdev->wiphy.vht_capa_mod_mask),
2869 rdev->wiphy.vht_capa_mod_mask))
2870 goto nla_put_failure;
2872 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
2873 rdev->wiphy.perm_addr))
2874 goto nla_put_failure;
2876 if (!is_zero_ether_addr(rdev->wiphy.addr_mask) &&
2877 nla_put(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN,
2878 rdev->wiphy.addr_mask))
2879 goto nla_put_failure;
2881 if (rdev->wiphy.n_addresses > 1) {
2882 void *attr;
2884 attr = nla_nest_start(msg, NL80211_ATTR_MAC_ADDRS);
2885 if (!attr)
2886 goto nla_put_failure;
2888 for (i = 0; i < rdev->wiphy.n_addresses; i++)
2889 if (nla_put(msg, i + 1, ETH_ALEN,
2890 rdev->wiphy.addresses[i].addr))
2891 goto nla_put_failure;
2893 nla_nest_end(msg, attr);
2896 state->split_start++;
2897 break;
2898 case 10:
2899 if (nl80211_send_coalesce(msg, rdev))
2900 goto nla_put_failure;
2902 if ((rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) &&
2903 (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) ||
2904 nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ)))
2905 goto nla_put_failure;
2907 if (rdev->wiphy.max_ap_assoc_sta &&
2908 nla_put_u32(msg, NL80211_ATTR_MAX_AP_ASSOC_STA,
2909 rdev->wiphy.max_ap_assoc_sta))
2910 goto nla_put_failure;
2912 state->split_start++;
2913 break;
2914 case 11:
2915 if (rdev->wiphy.n_vendor_commands) {
2916 const struct nl80211_vendor_cmd_info *info;
2917 struct nlattr *nested;
2919 nested = nla_nest_start_noflag(msg,
2920 NL80211_ATTR_VENDOR_DATA);
2921 if (!nested)
2922 goto nla_put_failure;
2924 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
2925 info = &rdev->wiphy.vendor_commands[i].info;
2926 if (nla_put(msg, i + 1, sizeof(*info), info))
2927 goto nla_put_failure;
2929 nla_nest_end(msg, nested);
2932 if (rdev->wiphy.n_vendor_events) {
2933 const struct nl80211_vendor_cmd_info *info;
2934 struct nlattr *nested;
2936 nested = nla_nest_start_noflag(msg,
2937 NL80211_ATTR_VENDOR_EVENTS);
2938 if (!nested)
2939 goto nla_put_failure;
2941 for (i = 0; i < rdev->wiphy.n_vendor_events; i++) {
2942 info = &rdev->wiphy.vendor_events[i];
2943 if (nla_put(msg, i + 1, sizeof(*info), info))
2944 goto nla_put_failure;
2946 nla_nest_end(msg, nested);
2948 state->split_start++;
2949 break;
2950 case 12:
2951 if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH &&
2952 nla_put_u8(msg, NL80211_ATTR_MAX_CSA_COUNTERS,
2953 rdev->wiphy.max_num_csa_counters))
2954 goto nla_put_failure;
2956 if (rdev->wiphy.regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
2957 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
2958 goto nla_put_failure;
2960 if (rdev->wiphy.max_sched_scan_reqs &&
2961 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
2962 rdev->wiphy.max_sched_scan_reqs))
2963 goto nla_put_failure;
2965 if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
2966 sizeof(rdev->wiphy.ext_features),
2967 rdev->wiphy.ext_features))
2968 goto nla_put_failure;
2970 if (rdev->wiphy.bss_select_support) {
2971 struct nlattr *nested;
2972 u32 bss_select_support = rdev->wiphy.bss_select_support;
2974 nested = nla_nest_start_noflag(msg,
2975 NL80211_ATTR_BSS_SELECT);
2976 if (!nested)
2977 goto nla_put_failure;
2979 i = 0;
2980 while (bss_select_support) {
2981 if ((bss_select_support & 1) &&
2982 nla_put_flag(msg, i))
2983 goto nla_put_failure;
2984 i++;
2985 bss_select_support >>= 1;
2987 nla_nest_end(msg, nested);
2990 state->split_start++;
2991 break;
2992 case 13:
2993 if (rdev->wiphy.num_iftype_ext_capab &&
2994 rdev->wiphy.iftype_ext_capab) {
2995 struct nlattr *nested_ext_capab, *nested;
2997 nested = nla_nest_start_noflag(msg,
2998 NL80211_ATTR_IFTYPE_EXT_CAPA);
2999 if (!nested)
3000 goto nla_put_failure;
3002 for (i = state->capa_start;
3003 i < rdev->wiphy.num_iftype_ext_capab; i++) {
3004 const struct wiphy_iftype_ext_capab *capab;
3006 capab = &rdev->wiphy.iftype_ext_capab[i];
3008 nested_ext_capab = nla_nest_start_noflag(msg,
3010 if (!nested_ext_capab ||
3011 nla_put_u32(msg, NL80211_ATTR_IFTYPE,
3012 capab->iftype) ||
3013 nla_put(msg, NL80211_ATTR_EXT_CAPA,
3014 capab->extended_capabilities_len,
3015 capab->extended_capabilities) ||
3016 nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK,
3017 capab->extended_capabilities_len,
3018 capab->extended_capabilities_mask))
3019 goto nla_put_failure;
3021 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_MLO &&
3022 (nla_put_u16(msg,
3023 NL80211_ATTR_EML_CAPABILITY,
3024 capab->eml_capabilities) ||
3025 nla_put_u16(msg,
3026 NL80211_ATTR_MLD_CAPA_AND_OPS,
3027 capab->mld_capa_and_ops)))
3028 goto nla_put_failure;
3030 nla_nest_end(msg, nested_ext_capab);
3031 if (state->split)
3032 break;
3034 nla_nest_end(msg, nested);
3035 if (i < rdev->wiphy.num_iftype_ext_capab) {
3036 state->capa_start = i + 1;
3037 break;
3041 if (nla_put_u32(msg, NL80211_ATTR_BANDS,
3042 rdev->wiphy.nan_supported_bands))
3043 goto nla_put_failure;
3045 if (wiphy_ext_feature_isset(&rdev->wiphy,
3046 NL80211_EXT_FEATURE_TXQS)) {
3047 struct cfg80211_txq_stats txqstats = {};
3048 int res;
3050 res = rdev_get_txq_stats(rdev, NULL, &txqstats);
3051 if (!res &&
3052 !nl80211_put_txq_stats(msg, &txqstats,
3053 NL80211_ATTR_TXQ_STATS))
3054 goto nla_put_failure;
3056 if (nla_put_u32(msg, NL80211_ATTR_TXQ_LIMIT,
3057 rdev->wiphy.txq_limit))
3058 goto nla_put_failure;
3059 if (nla_put_u32(msg, NL80211_ATTR_TXQ_MEMORY_LIMIT,
3060 rdev->wiphy.txq_memory_limit))
3061 goto nla_put_failure;
3062 if (nla_put_u32(msg, NL80211_ATTR_TXQ_QUANTUM,
3063 rdev->wiphy.txq_quantum))
3064 goto nla_put_failure;
3067 state->split_start++;
3068 break;
3069 case 14:
3070 if (nl80211_send_pmsr_capa(rdev, msg))
3071 goto nla_put_failure;
3073 state->split_start++;
3074 break;
3075 case 15:
3076 if (rdev->wiphy.akm_suites &&
3077 nla_put(msg, NL80211_ATTR_AKM_SUITES,
3078 sizeof(u32) * rdev->wiphy.n_akm_suites,
3079 rdev->wiphy.akm_suites))
3080 goto nla_put_failure;
3082 if (nl80211_put_iftype_akm_suites(rdev, msg))
3083 goto nla_put_failure;
3085 if (nl80211_put_tid_config_support(rdev, msg))
3086 goto nla_put_failure;
3087 state->split_start++;
3088 break;
3089 case 16:
3090 if (nl80211_put_sar_specs(rdev, msg))
3091 goto nla_put_failure;
3093 if (nl80211_put_mbssid_support(&rdev->wiphy, msg))
3094 goto nla_put_failure;
3096 if (nla_put_u16(msg, NL80211_ATTR_MAX_NUM_AKM_SUITES,
3097 rdev->wiphy.max_num_akm_suites))
3098 goto nla_put_failure;
3100 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_MLO)
3101 nla_put_flag(msg, NL80211_ATTR_MLO_SUPPORT);
3103 if (rdev->wiphy.hw_timestamp_max_peers &&
3104 nla_put_u16(msg, NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS,
3105 rdev->wiphy.hw_timestamp_max_peers))
3106 goto nla_put_failure;
3108 state->split_start++;
3109 break;
3110 case 17:
3111 if (nl80211_put_radios(&rdev->wiphy, msg))
3112 goto nla_put_failure;
3114 /* done */
3115 state->split_start = 0;
3116 break;
3118 finish:
3119 genlmsg_end(msg, hdr);
3120 return 0;
3122 nla_put_failure:
3123 genlmsg_cancel(msg, hdr);
3124 return -EMSGSIZE;
3127 static int nl80211_dump_wiphy_parse(struct sk_buff *skb,
3128 struct netlink_callback *cb,
3129 struct nl80211_dump_wiphy_state *state)
3131 struct nlattr **tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
3132 int ret;
3134 if (!tb)
3135 return -ENOMEM;
3137 ret = nlmsg_parse_deprecated(cb->nlh,
3138 GENL_HDRLEN + nl80211_fam.hdrsize,
3139 tb, nl80211_fam.maxattr,
3140 nl80211_policy, NULL);
3141 /* ignore parse errors for backward compatibility */
3142 if (ret) {
3143 ret = 0;
3144 goto out;
3147 state->split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP];
3148 if (tb[NL80211_ATTR_WIPHY])
3149 state->filter_wiphy = nla_get_u32(tb[NL80211_ATTR_WIPHY]);
3150 if (tb[NL80211_ATTR_WDEV])
3151 state->filter_wiphy = nla_get_u64(tb[NL80211_ATTR_WDEV]) >> 32;
3152 if (tb[NL80211_ATTR_IFINDEX]) {
3153 struct net_device *netdev;
3154 struct cfg80211_registered_device *rdev;
3155 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
3157 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
3158 if (!netdev) {
3159 ret = -ENODEV;
3160 goto out;
3162 if (netdev->ieee80211_ptr) {
3163 rdev = wiphy_to_rdev(
3164 netdev->ieee80211_ptr->wiphy);
3165 state->filter_wiphy = rdev->wiphy_idx;
3169 ret = 0;
3170 out:
3171 kfree(tb);
3172 return ret;
3175 static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
3177 int idx = 0, ret;
3178 struct nl80211_dump_wiphy_state *state = (void *)cb->args[0];
3179 struct cfg80211_registered_device *rdev;
3181 rtnl_lock();
3182 if (!state) {
3183 state = kzalloc(sizeof(*state), GFP_KERNEL);
3184 if (!state) {
3185 rtnl_unlock();
3186 return -ENOMEM;
3188 state->filter_wiphy = -1;
3189 ret = nl80211_dump_wiphy_parse(skb, cb, state);
3190 if (ret) {
3191 kfree(state);
3192 rtnl_unlock();
3193 return ret;
3195 cb->args[0] = (long)state;
3198 for_each_rdev(rdev) {
3199 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
3200 continue;
3201 if (++idx <= state->start)
3202 continue;
3203 if (state->filter_wiphy != -1 &&
3204 state->filter_wiphy != rdev->wiphy_idx)
3205 continue;
3206 wiphy_lock(&rdev->wiphy);
3207 /* attempt to fit multiple wiphy data chunks into the skb */
3208 do {
3209 ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
3210 skb,
3211 NETLINK_CB(cb->skb).portid,
3212 cb->nlh->nlmsg_seq,
3213 NLM_F_MULTI, state);
3214 if (ret < 0) {
3216 * If sending the wiphy data didn't fit (ENOBUFS
3217 * or EMSGSIZE returned), this SKB is still
3218 * empty (so it's not too big because another
3219 * wiphy dataset is already in the skb) and
3220 * we've not tried to adjust the dump allocation
3221 * yet ... then adjust the alloc size to be
3222 * bigger, and return 1 but with the empty skb.
3223 * This results in an empty message being RX'ed
3224 * in userspace, but that is ignored.
3226 * We can then retry with the larger buffer.
3228 if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
3229 !skb->len && !state->split &&
3230 cb->min_dump_alloc < 4096) {
3231 cb->min_dump_alloc = 4096;
3232 state->split_start = 0;
3233 wiphy_unlock(&rdev->wiphy);
3234 rtnl_unlock();
3235 return 1;
3237 idx--;
3238 break;
3240 } while (state->split_start > 0);
3241 wiphy_unlock(&rdev->wiphy);
3242 break;
3244 rtnl_unlock();
3246 state->start = idx;
3248 return skb->len;
3251 static int nl80211_dump_wiphy_done(struct netlink_callback *cb)
3253 kfree((void *)cb->args[0]);
3254 return 0;
3257 static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
3259 struct sk_buff *msg;
3260 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3261 struct nl80211_dump_wiphy_state state = {};
3263 msg = nlmsg_new(4096, GFP_KERNEL);
3264 if (!msg)
3265 return -ENOMEM;
3267 if (nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY, msg,
3268 info->snd_portid, info->snd_seq, 0,
3269 &state) < 0) {
3270 nlmsg_free(msg);
3271 return -ENOBUFS;
3274 return genlmsg_reply(msg, info);
3277 static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = {
3278 [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 },
3279 [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 },
3280 [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 },
3281 [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 },
3282 [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 },
3285 static int parse_txq_params(struct nlattr *tb[],
3286 struct ieee80211_txq_params *txq_params)
3288 u8 ac;
3290 if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] ||
3291 !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] ||
3292 !tb[NL80211_TXQ_ATTR_AIFS])
3293 return -EINVAL;
3295 ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]);
3296 txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]);
3297 txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]);
3298 txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]);
3299 txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]);
3301 if (ac >= NL80211_NUM_ACS)
3302 return -EINVAL;
3303 txq_params->ac = array_index_nospec(ac, NL80211_NUM_ACS);
3304 return 0;
3307 static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev)
3310 * You can only set the channel explicitly for some interfaces,
3311 * most have their channel managed via their respective
3312 * "establish a connection" command (connect, join, ...)
3314 * For AP/GO and mesh mode, the channel can be set with the
3315 * channel userspace API, but is only stored and passed to the
3316 * low-level driver when the AP starts or the mesh is joined.
3317 * This is for backward compatibility, userspace can also give
3318 * the channel in the start-ap or join-mesh commands instead.
3320 * Monitors are special as they are normally slaved to
3321 * whatever else is going on, so they have their own special
3322 * operation to set the monitor channel if possible.
3324 return !wdev ||
3325 wdev->iftype == NL80211_IFTYPE_AP ||
3326 wdev->iftype == NL80211_IFTYPE_MESH_POINT ||
3327 wdev->iftype == NL80211_IFTYPE_MONITOR ||
3328 wdev->iftype == NL80211_IFTYPE_P2P_GO;
3331 static int _nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
3332 struct genl_info *info, bool monitor,
3333 struct cfg80211_chan_def *chandef)
3335 struct netlink_ext_ack *extack = info->extack;
3336 struct nlattr **attrs = info->attrs;
3337 u32 control_freq;
3339 if (!attrs[NL80211_ATTR_WIPHY_FREQ]) {
3340 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
3341 "Frequency is missing");
3342 return -EINVAL;
3345 control_freq = MHZ_TO_KHZ(
3346 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
3347 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
3348 control_freq +=
3349 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
3351 memset(chandef, 0, sizeof(*chandef));
3352 chandef->chan = ieee80211_get_channel_khz(&rdev->wiphy, control_freq);
3353 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
3354 chandef->center_freq1 = KHZ_TO_MHZ(control_freq);
3355 chandef->freq1_offset = control_freq % 1000;
3356 chandef->center_freq2 = 0;
3358 if (!chandef->chan) {
3359 NL_SET_ERR_MSG_ATTR(extack, attrs[NL80211_ATTR_WIPHY_FREQ],
3360 "Unknown channel");
3361 return -EINVAL;
3364 if (attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) {
3365 enum nl80211_channel_type chantype;
3367 chantype = nla_get_u32(attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]);
3369 switch (chantype) {
3370 case NL80211_CHAN_NO_HT:
3371 case NL80211_CHAN_HT20:
3372 case NL80211_CHAN_HT40PLUS:
3373 case NL80211_CHAN_HT40MINUS:
3374 cfg80211_chandef_create(chandef, chandef->chan,
3375 chantype);
3376 /* user input for center_freq is incorrect */
3377 if (attrs[NL80211_ATTR_CENTER_FREQ1] &&
3378 chandef->center_freq1 != nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1])) {
3379 NL_SET_ERR_MSG_ATTR(extack,
3380 attrs[NL80211_ATTR_CENTER_FREQ1],
3381 "bad center frequency 1");
3382 return -EINVAL;
3384 /* center_freq2 must be zero */
3385 if (attrs[NL80211_ATTR_CENTER_FREQ2] &&
3386 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2])) {
3387 NL_SET_ERR_MSG_ATTR(extack,
3388 attrs[NL80211_ATTR_CENTER_FREQ2],
3389 "center frequency 2 can't be used");
3390 return -EINVAL;
3392 break;
3393 default:
3394 NL_SET_ERR_MSG_ATTR(extack,
3395 attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE],
3396 "invalid channel type");
3397 return -EINVAL;
3399 } else if (attrs[NL80211_ATTR_CHANNEL_WIDTH]) {
3400 chandef->width =
3401 nla_get_u32(attrs[NL80211_ATTR_CHANNEL_WIDTH]);
3402 if (chandef->chan->band == NL80211_BAND_S1GHZ) {
3403 /* User input error for channel width doesn't match channel */
3404 if (chandef->width != ieee80211_s1g_channel_width(chandef->chan)) {
3405 NL_SET_ERR_MSG_ATTR(extack,
3406 attrs[NL80211_ATTR_CHANNEL_WIDTH],
3407 "bad channel width");
3408 return -EINVAL;
3411 if (attrs[NL80211_ATTR_CENTER_FREQ1]) {
3412 chandef->center_freq1 =
3413 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ1]);
3414 chandef->freq1_offset =
3415 nla_get_u32_default(attrs[NL80211_ATTR_CENTER_FREQ1_OFFSET],
3418 if (attrs[NL80211_ATTR_CENTER_FREQ2])
3419 chandef->center_freq2 =
3420 nla_get_u32(attrs[NL80211_ATTR_CENTER_FREQ2]);
3423 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
3424 chandef->edmg.channels =
3425 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
3427 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
3428 chandef->edmg.bw_config =
3429 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
3430 } else {
3431 chandef->edmg.bw_config = 0;
3432 chandef->edmg.channels = 0;
3435 if (info->attrs[NL80211_ATTR_PUNCT_BITMAP]) {
3436 chandef->punctured =
3437 nla_get_u32(info->attrs[NL80211_ATTR_PUNCT_BITMAP]);
3439 if (chandef->punctured &&
3440 !wiphy_ext_feature_isset(&rdev->wiphy,
3441 NL80211_EXT_FEATURE_PUNCT)) {
3442 NL_SET_ERR_MSG(extack,
3443 "driver doesn't support puncturing");
3444 return -EINVAL;
3448 if (!cfg80211_chandef_valid(chandef)) {
3449 NL_SET_ERR_MSG(extack, "invalid channel definition");
3450 return -EINVAL;
3453 if (!_cfg80211_chandef_usable(&rdev->wiphy, chandef,
3454 IEEE80211_CHAN_DISABLED,
3455 monitor ? IEEE80211_CHAN_CAN_MONITOR : 0)) {
3456 NL_SET_ERR_MSG(extack, "(extension) channel is disabled");
3457 return -EINVAL;
3460 if ((chandef->width == NL80211_CHAN_WIDTH_5 ||
3461 chandef->width == NL80211_CHAN_WIDTH_10) &&
3462 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ)) {
3463 NL_SET_ERR_MSG(extack, "5/10 MHz not supported");
3464 return -EINVAL;
3467 return 0;
3470 int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
3471 struct genl_info *info,
3472 struct cfg80211_chan_def *chandef)
3474 return _nl80211_parse_chandef(rdev, info, false, chandef);
3477 static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
3478 struct net_device *dev,
3479 struct genl_info *info,
3480 int _link_id)
3482 struct cfg80211_chan_def chandef;
3483 int result;
3484 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
3485 struct wireless_dev *wdev = NULL;
3486 int link_id = _link_id;
3488 if (dev)
3489 wdev = dev->ieee80211_ptr;
3490 if (!nl80211_can_set_dev_channel(wdev))
3491 return -EOPNOTSUPP;
3492 if (wdev)
3493 iftype = wdev->iftype;
3495 if (link_id < 0) {
3496 if (wdev && wdev->valid_links)
3497 return -EINVAL;
3498 link_id = 0;
3501 result = _nl80211_parse_chandef(rdev, info,
3502 iftype == NL80211_IFTYPE_MONITOR,
3503 &chandef);
3504 if (result)
3505 return result;
3507 switch (iftype) {
3508 case NL80211_IFTYPE_AP:
3509 case NL80211_IFTYPE_P2P_GO:
3510 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
3511 iftype))
3512 return -EINVAL;
3513 if (wdev->links[link_id].ap.beacon_interval) {
3514 struct ieee80211_channel *cur_chan;
3516 if (!dev || !rdev->ops->set_ap_chanwidth ||
3517 !(rdev->wiphy.features &
3518 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE))
3519 return -EBUSY;
3521 /* Only allow dynamic channel width changes */
3522 cur_chan = wdev->links[link_id].ap.chandef.chan;
3523 if (chandef.chan != cur_chan)
3524 return -EBUSY;
3526 /* only allow this for regular channel widths */
3527 switch (wdev->links[link_id].ap.chandef.width) {
3528 case NL80211_CHAN_WIDTH_20_NOHT:
3529 case NL80211_CHAN_WIDTH_20:
3530 case NL80211_CHAN_WIDTH_40:
3531 case NL80211_CHAN_WIDTH_80:
3532 case NL80211_CHAN_WIDTH_80P80:
3533 case NL80211_CHAN_WIDTH_160:
3534 case NL80211_CHAN_WIDTH_320:
3535 break;
3536 default:
3537 return -EINVAL;
3540 switch (chandef.width) {
3541 case NL80211_CHAN_WIDTH_20_NOHT:
3542 case NL80211_CHAN_WIDTH_20:
3543 case NL80211_CHAN_WIDTH_40:
3544 case NL80211_CHAN_WIDTH_80:
3545 case NL80211_CHAN_WIDTH_80P80:
3546 case NL80211_CHAN_WIDTH_160:
3547 case NL80211_CHAN_WIDTH_320:
3548 break;
3549 default:
3550 return -EINVAL;
3553 result = rdev_set_ap_chanwidth(rdev, dev, link_id,
3554 &chandef);
3555 if (result)
3556 return result;
3557 wdev->links[link_id].ap.chandef = chandef;
3558 } else {
3559 wdev->u.ap.preset_chandef = chandef;
3561 return 0;
3562 case NL80211_IFTYPE_MESH_POINT:
3563 return cfg80211_set_mesh_channel(rdev, wdev, &chandef);
3564 case NL80211_IFTYPE_MONITOR:
3565 return cfg80211_set_monitor_channel(rdev, dev, &chandef);
3566 default:
3567 break;
3570 return -EINVAL;
3573 static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info)
3575 struct cfg80211_registered_device *rdev = info->user_ptr[0];
3576 int link_id = nl80211_link_id_or_invalid(info->attrs);
3577 struct net_device *netdev = info->user_ptr[1];
3579 return __nl80211_set_channel(rdev, netdev, info, link_id);
3582 static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
3584 struct cfg80211_registered_device *rdev = NULL;
3585 struct net_device *netdev = NULL;
3586 struct wireless_dev *wdev;
3587 int result = 0, rem_txq_params = 0;
3588 struct nlattr *nl_txq_params;
3589 u32 changed;
3590 u8 retry_short = 0, retry_long = 0;
3591 u32 frag_threshold = 0, rts_threshold = 0;
3592 u8 coverage_class = 0;
3593 u32 txq_limit = 0, txq_memory_limit = 0, txq_quantum = 0;
3595 rtnl_lock();
3597 * Try to find the wiphy and netdev. Normally this
3598 * function shouldn't need the netdev, but this is
3599 * done for backward compatibility -- previously
3600 * setting the channel was done per wiphy, but now
3601 * it is per netdev. Previous userland like hostapd
3602 * also passed a netdev to set_wiphy, so that it is
3603 * possible to let that go to the right netdev!
3606 if (info->attrs[NL80211_ATTR_IFINDEX]) {
3607 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
3609 netdev = __dev_get_by_index(genl_info_net(info), ifindex);
3610 if (netdev && netdev->ieee80211_ptr)
3611 rdev = wiphy_to_rdev(netdev->ieee80211_ptr->wiphy);
3612 else
3613 netdev = NULL;
3616 if (!netdev) {
3617 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
3618 info->attrs);
3619 if (IS_ERR(rdev)) {
3620 rtnl_unlock();
3621 return PTR_ERR(rdev);
3623 wdev = NULL;
3624 netdev = NULL;
3625 result = 0;
3626 } else
3627 wdev = netdev->ieee80211_ptr;
3629 wiphy_lock(&rdev->wiphy);
3632 * end workaround code, by now the rdev is available
3633 * and locked, and wdev may or may not be NULL.
3636 if (info->attrs[NL80211_ATTR_WIPHY_NAME])
3637 result = cfg80211_dev_rename(
3638 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
3639 rtnl_unlock();
3641 if (result)
3642 goto out;
3644 if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) {
3645 struct ieee80211_txq_params txq_params;
3646 struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1];
3648 if (!rdev->ops->set_txq_params) {
3649 result = -EOPNOTSUPP;
3650 goto out;
3653 if (!netdev) {
3654 result = -EINVAL;
3655 goto out;
3658 if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
3659 netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
3660 result = -EINVAL;
3661 goto out;
3664 if (!netif_running(netdev)) {
3665 result = -ENETDOWN;
3666 goto out;
3669 nla_for_each_nested(nl_txq_params,
3670 info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
3671 rem_txq_params) {
3672 result = nla_parse_nested_deprecated(tb,
3673 NL80211_TXQ_ATTR_MAX,
3674 nl_txq_params,
3675 txq_params_policy,
3676 info->extack);
3677 if (result)
3678 goto out;
3679 result = parse_txq_params(tb, &txq_params);
3680 if (result)
3681 goto out;
3683 txq_params.link_id =
3684 nl80211_link_id_or_invalid(info->attrs);
3686 if (txq_params.link_id >= 0 &&
3687 !(netdev->ieee80211_ptr->valid_links &
3688 BIT(txq_params.link_id)))
3689 result = -ENOLINK;
3690 else if (txq_params.link_id >= 0 &&
3691 !netdev->ieee80211_ptr->valid_links)
3692 result = -EINVAL;
3693 else
3694 result = rdev_set_txq_params(rdev, netdev,
3695 &txq_params);
3696 if (result)
3697 goto out;
3701 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
3702 int link_id = nl80211_link_id_or_invalid(info->attrs);
3704 if (wdev) {
3705 result = __nl80211_set_channel(
3706 rdev,
3707 nl80211_can_set_dev_channel(wdev) ? netdev : NULL,
3708 info, link_id);
3709 } else {
3710 result = __nl80211_set_channel(rdev, netdev, info, link_id);
3713 if (result)
3714 goto out;
3717 if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) {
3718 struct wireless_dev *txp_wdev = wdev;
3719 enum nl80211_tx_power_setting type;
3720 int idx, mbm = 0;
3722 if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER))
3723 txp_wdev = NULL;
3725 if (!rdev->ops->set_tx_power) {
3726 result = -EOPNOTSUPP;
3727 goto out;
3730 idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING;
3731 type = nla_get_u32(info->attrs[idx]);
3733 if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] &&
3734 (type != NL80211_TX_POWER_AUTOMATIC)) {
3735 result = -EINVAL;
3736 goto out;
3739 if (type != NL80211_TX_POWER_AUTOMATIC) {
3740 idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL;
3741 mbm = nla_get_u32(info->attrs[idx]);
3744 result = rdev_set_tx_power(rdev, txp_wdev, type, mbm);
3745 if (result)
3746 goto out;
3749 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
3750 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
3751 u32 tx_ant, rx_ant;
3753 if ((!rdev->wiphy.available_antennas_tx &&
3754 !rdev->wiphy.available_antennas_rx) ||
3755 !rdev->ops->set_antenna) {
3756 result = -EOPNOTSUPP;
3757 goto out;
3760 tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
3761 rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
3763 /* reject antenna configurations which don't match the
3764 * available antenna masks, except for the "all" mask */
3765 if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
3766 (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
3767 result = -EINVAL;
3768 goto out;
3771 tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
3772 rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
3774 result = rdev_set_antenna(rdev, tx_ant, rx_ant);
3775 if (result)
3776 goto out;
3779 changed = 0;
3781 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
3782 retry_short = nla_get_u8(
3783 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
3785 changed |= WIPHY_PARAM_RETRY_SHORT;
3788 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
3789 retry_long = nla_get_u8(
3790 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
3792 changed |= WIPHY_PARAM_RETRY_LONG;
3795 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
3796 frag_threshold = nla_get_u32(
3797 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
3798 if (frag_threshold < 256) {
3799 result = -EINVAL;
3800 goto out;
3803 if (frag_threshold != (u32) -1) {
3805 * Fragments (apart from the last one) are required to
3806 * have even length. Make the fragmentation code
3807 * simpler by stripping LSB should someone try to use
3808 * odd threshold value.
3810 frag_threshold &= ~0x1;
3812 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
3815 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
3816 rts_threshold = nla_get_u32(
3817 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
3818 changed |= WIPHY_PARAM_RTS_THRESHOLD;
3821 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
3822 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
3823 result = -EINVAL;
3824 goto out;
3827 coverage_class = nla_get_u8(
3828 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
3829 changed |= WIPHY_PARAM_COVERAGE_CLASS;
3832 if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) {
3833 if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION)) {
3834 result = -EOPNOTSUPP;
3835 goto out;
3838 changed |= WIPHY_PARAM_DYN_ACK;
3841 if (info->attrs[NL80211_ATTR_TXQ_LIMIT]) {
3842 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3843 NL80211_EXT_FEATURE_TXQS)) {
3844 result = -EOPNOTSUPP;
3845 goto out;
3847 txq_limit = nla_get_u32(
3848 info->attrs[NL80211_ATTR_TXQ_LIMIT]);
3849 changed |= WIPHY_PARAM_TXQ_LIMIT;
3852 if (info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]) {
3853 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3854 NL80211_EXT_FEATURE_TXQS)) {
3855 result = -EOPNOTSUPP;
3856 goto out;
3858 txq_memory_limit = nla_get_u32(
3859 info->attrs[NL80211_ATTR_TXQ_MEMORY_LIMIT]);
3860 changed |= WIPHY_PARAM_TXQ_MEMORY_LIMIT;
3863 if (info->attrs[NL80211_ATTR_TXQ_QUANTUM]) {
3864 if (!wiphy_ext_feature_isset(&rdev->wiphy,
3865 NL80211_EXT_FEATURE_TXQS)) {
3866 result = -EOPNOTSUPP;
3867 goto out;
3869 txq_quantum = nla_get_u32(
3870 info->attrs[NL80211_ATTR_TXQ_QUANTUM]);
3871 changed |= WIPHY_PARAM_TXQ_QUANTUM;
3874 if (changed) {
3875 u8 old_retry_short, old_retry_long;
3876 u32 old_frag_threshold, old_rts_threshold;
3877 u8 old_coverage_class;
3878 u32 old_txq_limit, old_txq_memory_limit, old_txq_quantum;
3880 if (!rdev->ops->set_wiphy_params) {
3881 result = -EOPNOTSUPP;
3882 goto out;
3885 old_retry_short = rdev->wiphy.retry_short;
3886 old_retry_long = rdev->wiphy.retry_long;
3887 old_frag_threshold = rdev->wiphy.frag_threshold;
3888 old_rts_threshold = rdev->wiphy.rts_threshold;
3889 old_coverage_class = rdev->wiphy.coverage_class;
3890 old_txq_limit = rdev->wiphy.txq_limit;
3891 old_txq_memory_limit = rdev->wiphy.txq_memory_limit;
3892 old_txq_quantum = rdev->wiphy.txq_quantum;
3894 if (changed & WIPHY_PARAM_RETRY_SHORT)
3895 rdev->wiphy.retry_short = retry_short;
3896 if (changed & WIPHY_PARAM_RETRY_LONG)
3897 rdev->wiphy.retry_long = retry_long;
3898 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
3899 rdev->wiphy.frag_threshold = frag_threshold;
3900 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
3901 rdev->wiphy.rts_threshold = rts_threshold;
3902 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
3903 rdev->wiphy.coverage_class = coverage_class;
3904 if (changed & WIPHY_PARAM_TXQ_LIMIT)
3905 rdev->wiphy.txq_limit = txq_limit;
3906 if (changed & WIPHY_PARAM_TXQ_MEMORY_LIMIT)
3907 rdev->wiphy.txq_memory_limit = txq_memory_limit;
3908 if (changed & WIPHY_PARAM_TXQ_QUANTUM)
3909 rdev->wiphy.txq_quantum = txq_quantum;
3911 result = rdev_set_wiphy_params(rdev, changed);
3912 if (result) {
3913 rdev->wiphy.retry_short = old_retry_short;
3914 rdev->wiphy.retry_long = old_retry_long;
3915 rdev->wiphy.frag_threshold = old_frag_threshold;
3916 rdev->wiphy.rts_threshold = old_rts_threshold;
3917 rdev->wiphy.coverage_class = old_coverage_class;
3918 rdev->wiphy.txq_limit = old_txq_limit;
3919 rdev->wiphy.txq_memory_limit = old_txq_memory_limit;
3920 rdev->wiphy.txq_quantum = old_txq_quantum;
3921 goto out;
3925 result = 0;
3927 out:
3928 wiphy_unlock(&rdev->wiphy);
3929 return result;
3932 int nl80211_send_chandef(struct sk_buff *msg, const struct cfg80211_chan_def *chandef)
3934 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
3935 return -EINVAL;
3937 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
3938 chandef->chan->center_freq))
3939 return -ENOBUFS;
3940 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
3941 chandef->chan->freq_offset))
3942 return -ENOBUFS;
3943 switch (chandef->width) {
3944 case NL80211_CHAN_WIDTH_20_NOHT:
3945 case NL80211_CHAN_WIDTH_20:
3946 case NL80211_CHAN_WIDTH_40:
3947 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
3948 cfg80211_get_chandef_type(chandef)))
3949 return -ENOBUFS;
3950 break;
3951 default:
3952 break;
3954 if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width))
3955 return -ENOBUFS;
3956 if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1))
3957 return -ENOBUFS;
3958 if (chandef->center_freq2 &&
3959 nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2))
3960 return -ENOBUFS;
3961 if (chandef->punctured &&
3962 nla_put_u32(msg, NL80211_ATTR_PUNCT_BITMAP, chandef->punctured))
3963 return -ENOBUFS;
3965 return 0;
3967 EXPORT_SYMBOL(nl80211_send_chandef);
3969 static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
3970 struct cfg80211_registered_device *rdev,
3971 struct wireless_dev *wdev,
3972 enum nl80211_commands cmd)
3974 struct net_device *dev = wdev->netdev;
3975 void *hdr;
3977 lockdep_assert_wiphy(&rdev->wiphy);
3979 WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
3980 cmd != NL80211_CMD_DEL_INTERFACE &&
3981 cmd != NL80211_CMD_SET_INTERFACE);
3983 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
3984 if (!hdr)
3985 return -1;
3987 if (dev &&
3988 (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
3989 nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name)))
3990 goto nla_put_failure;
3992 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
3993 nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) ||
3994 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
3995 NL80211_ATTR_PAD) ||
3996 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) ||
3997 nla_put_u32(msg, NL80211_ATTR_GENERATION,
3998 rdev->devlist_generation ^
3999 (cfg80211_rdev_list_generation << 2)) ||
4000 nla_put_u8(msg, NL80211_ATTR_4ADDR, wdev->use_4addr) ||
4001 nla_put_u32(msg, NL80211_ATTR_VIF_RADIO_MASK, wdev->radio_mask))
4002 goto nla_put_failure;
4004 if (rdev->ops->get_channel && !wdev->valid_links) {
4005 struct cfg80211_chan_def chandef = {};
4006 int ret;
4008 ret = rdev_get_channel(rdev, wdev, 0, &chandef);
4009 if (ret == 0 && nl80211_send_chandef(msg, &chandef))
4010 goto nla_put_failure;
4013 if (rdev->ops->get_tx_power) {
4014 int dbm, ret;
4016 ret = rdev_get_tx_power(rdev, wdev, &dbm);
4017 if (ret == 0 &&
4018 nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
4019 DBM_TO_MBM(dbm)))
4020 goto nla_put_failure;
4023 switch (wdev->iftype) {
4024 case NL80211_IFTYPE_AP:
4025 case NL80211_IFTYPE_P2P_GO:
4026 if (wdev->u.ap.ssid_len &&
4027 nla_put(msg, NL80211_ATTR_SSID, wdev->u.ap.ssid_len,
4028 wdev->u.ap.ssid))
4029 goto nla_put_failure;
4030 break;
4031 case NL80211_IFTYPE_STATION:
4032 case NL80211_IFTYPE_P2P_CLIENT:
4033 if (wdev->u.client.ssid_len &&
4034 nla_put(msg, NL80211_ATTR_SSID, wdev->u.client.ssid_len,
4035 wdev->u.client.ssid))
4036 goto nla_put_failure;
4037 break;
4038 case NL80211_IFTYPE_ADHOC:
4039 if (wdev->u.ibss.ssid_len &&
4040 nla_put(msg, NL80211_ATTR_SSID, wdev->u.ibss.ssid_len,
4041 wdev->u.ibss.ssid))
4042 goto nla_put_failure;
4043 break;
4044 default:
4045 /* nothing */
4046 break;
4049 if (rdev->ops->get_txq_stats) {
4050 struct cfg80211_txq_stats txqstats = {};
4051 int ret = rdev_get_txq_stats(rdev, wdev, &txqstats);
4053 if (ret == 0 &&
4054 !nl80211_put_txq_stats(msg, &txqstats,
4055 NL80211_ATTR_TXQ_STATS))
4056 goto nla_put_failure;
4059 if (wdev->valid_links) {
4060 unsigned int link_id;
4061 struct nlattr *links = nla_nest_start(msg,
4062 NL80211_ATTR_MLO_LINKS);
4064 if (!links)
4065 goto nla_put_failure;
4067 for_each_valid_link(wdev, link_id) {
4068 struct nlattr *link = nla_nest_start(msg, link_id + 1);
4069 struct cfg80211_chan_def chandef = {};
4070 int ret;
4072 if (!link)
4073 goto nla_put_failure;
4075 if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
4076 goto nla_put_failure;
4077 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
4078 wdev->links[link_id].addr))
4079 goto nla_put_failure;
4081 ret = rdev_get_channel(rdev, wdev, link_id, &chandef);
4082 if (ret == 0 && nl80211_send_chandef(msg, &chandef))
4083 goto nla_put_failure;
4085 nla_nest_end(msg, link);
4088 nla_nest_end(msg, links);
4091 genlmsg_end(msg, hdr);
4092 return 0;
4094 nla_put_failure:
4095 genlmsg_cancel(msg, hdr);
4096 return -EMSGSIZE;
4099 static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb)
4101 int wp_idx = 0;
4102 int if_idx = 0;
4103 int wp_start = cb->args[0];
4104 int if_start = cb->args[1];
4105 int filter_wiphy = -1;
4106 struct cfg80211_registered_device *rdev;
4107 struct wireless_dev *wdev;
4108 int ret;
4110 rtnl_lock();
4111 if (!cb->args[2]) {
4112 struct nl80211_dump_wiphy_state state = {
4113 .filter_wiphy = -1,
4116 ret = nl80211_dump_wiphy_parse(skb, cb, &state);
4117 if (ret)
4118 goto out_unlock;
4120 filter_wiphy = state.filter_wiphy;
4123 * if filtering, set cb->args[2] to +1 since 0 is the default
4124 * value needed to determine that parsing is necessary.
4126 if (filter_wiphy >= 0)
4127 cb->args[2] = filter_wiphy + 1;
4128 else
4129 cb->args[2] = -1;
4130 } else if (cb->args[2] > 0) {
4131 filter_wiphy = cb->args[2] - 1;
4134 for_each_rdev(rdev) {
4135 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
4136 continue;
4137 if (wp_idx < wp_start) {
4138 wp_idx++;
4139 continue;
4142 if (filter_wiphy >= 0 && filter_wiphy != rdev->wiphy_idx)
4143 continue;
4145 if_idx = 0;
4147 wiphy_lock(&rdev->wiphy);
4148 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
4149 if (if_idx < if_start) {
4150 if_idx++;
4151 continue;
4153 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
4154 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4155 rdev, wdev,
4156 NL80211_CMD_NEW_INTERFACE) < 0) {
4157 wiphy_unlock(&rdev->wiphy);
4158 goto out;
4160 if_idx++;
4162 wiphy_unlock(&rdev->wiphy);
4164 if_start = 0;
4165 wp_idx++;
4167 out:
4168 cb->args[0] = wp_idx;
4169 cb->args[1] = if_idx;
4171 ret = skb->len;
4172 out_unlock:
4173 rtnl_unlock();
4175 return ret;
4178 static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
4180 struct sk_buff *msg;
4181 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4182 struct wireless_dev *wdev = info->user_ptr[1];
4184 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4185 if (!msg)
4186 return -ENOMEM;
4188 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
4189 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
4190 nlmsg_free(msg);
4191 return -ENOBUFS;
4194 return genlmsg_reply(msg, info);
4197 static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = {
4198 [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG },
4199 [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG },
4200 [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG },
4201 [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG },
4202 [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG },
4203 [NL80211_MNTR_FLAG_ACTIVE] = { .type = NLA_FLAG },
4204 [NL80211_MNTR_FLAG_SKIP_TX] = { .type = NLA_FLAG },
4207 static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags)
4209 struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1];
4210 int flag;
4212 *mntrflags = 0;
4214 if (!nla)
4215 return -EINVAL;
4217 if (nla_parse_nested_deprecated(flags, NL80211_MNTR_FLAG_MAX, nla, mntr_flags_policy, NULL))
4218 return -EINVAL;
4220 for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++)
4221 if (flags[flag])
4222 *mntrflags |= (1<<flag);
4224 *mntrflags |= MONITOR_FLAG_CHANGED;
4226 return 0;
4229 static int nl80211_parse_mon_options(struct cfg80211_registered_device *rdev,
4230 enum nl80211_iftype type,
4231 struct genl_info *info,
4232 struct vif_params *params)
4234 bool change = false;
4235 int err;
4237 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
4238 if (type != NL80211_IFTYPE_MONITOR)
4239 return -EINVAL;
4241 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
4242 &params->flags);
4243 if (err)
4244 return err;
4246 change = true;
4249 if (params->flags & MONITOR_FLAG_ACTIVE &&
4250 !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR))
4251 return -EOPNOTSUPP;
4253 if (info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]) {
4254 const u8 *mumimo_groups;
4255 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
4257 if (type != NL80211_IFTYPE_MONITOR)
4258 return -EINVAL;
4260 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
4261 return -EOPNOTSUPP;
4263 mumimo_groups =
4264 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_GROUP_DATA]);
4266 /* bits 0 and 63 are reserved and must be zero */
4267 if ((mumimo_groups[0] & BIT(0)) ||
4268 (mumimo_groups[VHT_MUMIMO_GROUPS_DATA_LEN - 1] & BIT(7)))
4269 return -EINVAL;
4271 params->vht_mumimo_groups = mumimo_groups;
4272 change = true;
4275 if (info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]) {
4276 u32 cap_flag = NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER;
4278 if (type != NL80211_IFTYPE_MONITOR)
4279 return -EINVAL;
4281 if (!wiphy_ext_feature_isset(&rdev->wiphy, cap_flag))
4282 return -EOPNOTSUPP;
4284 params->vht_mumimo_follow_addr =
4285 nla_data(info->attrs[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR]);
4286 change = true;
4289 return change ? 1 : 0;
4292 static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev,
4293 struct net_device *netdev, u8 use_4addr,
4294 enum nl80211_iftype iftype)
4296 if (!use_4addr) {
4297 if (netdev && netif_is_bridge_port(netdev))
4298 return -EBUSY;
4299 return 0;
4302 switch (iftype) {
4303 case NL80211_IFTYPE_AP_VLAN:
4304 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP)
4305 return 0;
4306 break;
4307 case NL80211_IFTYPE_STATION:
4308 if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION)
4309 return 0;
4310 break;
4311 default:
4312 break;
4315 return -EOPNOTSUPP;
4318 static int nl80211_parse_vif_radio_mask(struct genl_info *info,
4319 u32 *radio_mask)
4321 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4322 struct nlattr *attr = info->attrs[NL80211_ATTR_VIF_RADIO_MASK];
4323 u32 mask, allowed;
4325 if (!attr) {
4326 *radio_mask = 0;
4327 return 0;
4330 allowed = BIT(rdev->wiphy.n_radio) - 1;
4331 mask = nla_get_u32(attr);
4332 if (mask & ~allowed)
4333 return -EINVAL;
4334 if (!mask)
4335 mask = allowed;
4336 *radio_mask = mask;
4338 return 1;
4341 static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
4343 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4344 struct vif_params params;
4345 int err;
4346 enum nl80211_iftype otype, ntype;
4347 struct net_device *dev = info->user_ptr[1];
4348 struct wireless_dev *wdev = dev->ieee80211_ptr;
4349 u32 radio_mask = 0;
4350 bool change = false;
4352 memset(&params, 0, sizeof(params));
4354 otype = ntype = dev->ieee80211_ptr->iftype;
4356 if (info->attrs[NL80211_ATTR_IFTYPE]) {
4357 ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
4358 if (otype != ntype)
4359 change = true;
4362 if (info->attrs[NL80211_ATTR_MESH_ID]) {
4363 if (ntype != NL80211_IFTYPE_MESH_POINT)
4364 return -EINVAL;
4365 if (otype != NL80211_IFTYPE_MESH_POINT)
4366 return -EINVAL;
4367 if (netif_running(dev))
4368 return -EBUSY;
4370 wdev->u.mesh.id_up_len =
4371 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4372 memcpy(wdev->u.mesh.id,
4373 nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
4374 wdev->u.mesh.id_up_len);
4377 if (info->attrs[NL80211_ATTR_4ADDR]) {
4378 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
4379 change = true;
4380 err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype);
4381 if (err)
4382 return err;
4383 } else {
4384 params.use_4addr = -1;
4387 err = nl80211_parse_mon_options(rdev, ntype, info, &params);
4388 if (err < 0)
4389 return err;
4390 if (err > 0)
4391 change = true;
4393 err = nl80211_parse_vif_radio_mask(info, &radio_mask);
4394 if (err < 0)
4395 return err;
4396 if (err && netif_running(dev))
4397 return -EBUSY;
4399 if (change)
4400 err = cfg80211_change_iface(rdev, dev, ntype, &params);
4401 else
4402 err = 0;
4404 if (!err && params.use_4addr != -1)
4405 dev->ieee80211_ptr->use_4addr = params.use_4addr;
4407 if (radio_mask)
4408 wdev->radio_mask = radio_mask;
4410 if (change && !err)
4411 nl80211_notify_iface(rdev, wdev, NL80211_CMD_SET_INTERFACE);
4413 return err;
4416 static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
4418 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4419 struct vif_params params;
4420 struct wireless_dev *wdev;
4421 struct sk_buff *msg;
4422 u32 radio_mask;
4423 int err;
4424 enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED;
4426 memset(&params, 0, sizeof(params));
4428 if (!info->attrs[NL80211_ATTR_IFNAME])
4429 return -EINVAL;
4431 if (info->attrs[NL80211_ATTR_IFTYPE])
4432 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
4434 if (!rdev->ops->add_virtual_intf)
4435 return -EOPNOTSUPP;
4437 if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN ||
4438 rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) &&
4439 info->attrs[NL80211_ATTR_MAC]) {
4440 nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC],
4441 ETH_ALEN);
4442 if (!is_valid_ether_addr(params.macaddr))
4443 return -EADDRNOTAVAIL;
4446 if (info->attrs[NL80211_ATTR_4ADDR]) {
4447 params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]);
4448 err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type);
4449 if (err)
4450 return err;
4453 if (!cfg80211_iftype_allowed(&rdev->wiphy, type, params.use_4addr, 0))
4454 return -EOPNOTSUPP;
4456 err = nl80211_parse_mon_options(rdev, type, info, &params);
4457 if (err < 0)
4458 return err;
4460 err = nl80211_parse_vif_radio_mask(info, &radio_mask);
4461 if (err < 0)
4462 return err;
4464 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4465 if (!msg)
4466 return -ENOMEM;
4468 wdev = rdev_add_virtual_intf(rdev,
4469 nla_data(info->attrs[NL80211_ATTR_IFNAME]),
4470 NET_NAME_USER, type, &params);
4471 if (WARN_ON(!wdev)) {
4472 nlmsg_free(msg);
4473 return -EPROTO;
4474 } else if (IS_ERR(wdev)) {
4475 nlmsg_free(msg);
4476 return PTR_ERR(wdev);
4479 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
4480 wdev->owner_nlportid = info->snd_portid;
4482 switch (type) {
4483 case NL80211_IFTYPE_MESH_POINT:
4484 if (!info->attrs[NL80211_ATTR_MESH_ID])
4485 break;
4486 wdev->u.mesh.id_up_len =
4487 nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
4488 memcpy(wdev->u.mesh.id,
4489 nla_data(info->attrs[NL80211_ATTR_MESH_ID]),
4490 wdev->u.mesh.id_up_len);
4491 break;
4492 case NL80211_IFTYPE_NAN:
4493 case NL80211_IFTYPE_P2P_DEVICE:
4495 * P2P Device and NAN do not have a netdev, so don't go
4496 * through the netdev notifier and must be added here
4498 cfg80211_init_wdev(wdev);
4499 cfg80211_register_wdev(rdev, wdev);
4500 break;
4501 default:
4502 break;
4505 if (radio_mask)
4506 wdev->radio_mask = radio_mask;
4508 if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0,
4509 rdev, wdev, NL80211_CMD_NEW_INTERFACE) < 0) {
4510 nlmsg_free(msg);
4511 return -ENOBUFS;
4514 return genlmsg_reply(msg, info);
4517 static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
4519 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4520 int ret;
4522 /* to avoid failing a new interface creation due to pending removal */
4523 cfg80211_destroy_ifaces(rdev);
4525 wiphy_lock(&rdev->wiphy);
4526 ret = _nl80211_new_interface(skb, info);
4527 wiphy_unlock(&rdev->wiphy);
4529 return ret;
4532 static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
4534 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4535 struct wireless_dev *wdev = info->user_ptr[1];
4537 if (!rdev->ops->del_virtual_intf)
4538 return -EOPNOTSUPP;
4541 * We hold RTNL, so this is safe, without RTNL opencount cannot
4542 * reach 0, and thus the rdev cannot be deleted.
4544 * We need to do it for the dev_close(), since that will call
4545 * the netdev notifiers, and we need to acquire the mutex there
4546 * but don't know if we get there from here or from some other
4547 * place (e.g. "ip link set ... down").
4549 mutex_unlock(&rdev->wiphy.mtx);
4552 * If we remove a wireless device without a netdev then clear
4553 * user_ptr[1] so that nl80211_post_doit won't dereference it
4554 * to check if it needs to do dev_put(). Otherwise it crashes
4555 * since the wdev has been freed, unlike with a netdev where
4556 * we need the dev_put() for the netdev to really be freed.
4558 if (!wdev->netdev)
4559 info->user_ptr[1] = NULL;
4560 else
4561 dev_close(wdev->netdev);
4563 mutex_lock(&rdev->wiphy.mtx);
4565 return cfg80211_remove_virtual_intf(rdev, wdev);
4568 static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
4570 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4571 struct net_device *dev = info->user_ptr[1];
4572 u16 noack_map;
4574 if (!info->attrs[NL80211_ATTR_NOACK_MAP])
4575 return -EINVAL;
4577 if (!rdev->ops->set_noack_map)
4578 return -EOPNOTSUPP;
4580 noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]);
4582 return rdev_set_noack_map(rdev, dev, noack_map);
4585 static int nl80211_validate_key_link_id(struct genl_info *info,
4586 struct wireless_dev *wdev,
4587 int link_id, bool pairwise)
4589 if (pairwise) {
4590 if (link_id != -1) {
4591 GENL_SET_ERR_MSG(info,
4592 "link ID not allowed for pairwise key");
4593 return -EINVAL;
4596 return 0;
4599 if (wdev->valid_links) {
4600 if (link_id == -1) {
4601 GENL_SET_ERR_MSG(info,
4602 "link ID must for MLO group key");
4603 return -EINVAL;
4605 if (!(wdev->valid_links & BIT(link_id))) {
4606 GENL_SET_ERR_MSG(info, "invalid link ID for MLO group key");
4607 return -EINVAL;
4609 } else if (link_id != -1) {
4610 GENL_SET_ERR_MSG(info, "link ID not allowed for non-MLO group key");
4611 return -EINVAL;
4614 return 0;
4617 struct get_key_cookie {
4618 struct sk_buff *msg;
4619 int error;
4620 int idx;
4623 static void get_key_callback(void *c, struct key_params *params)
4625 struct nlattr *key;
4626 struct get_key_cookie *cookie = c;
4628 if ((params->seq &&
4629 nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ,
4630 params->seq_len, params->seq)) ||
4631 (params->cipher &&
4632 nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
4633 params->cipher)))
4634 goto nla_put_failure;
4636 key = nla_nest_start_noflag(cookie->msg, NL80211_ATTR_KEY);
4637 if (!key)
4638 goto nla_put_failure;
4640 if ((params->seq &&
4641 nla_put(cookie->msg, NL80211_KEY_SEQ,
4642 params->seq_len, params->seq)) ||
4643 (params->cipher &&
4644 nla_put_u32(cookie->msg, NL80211_KEY_CIPHER,
4645 params->cipher)))
4646 goto nla_put_failure;
4648 if (nla_put_u8(cookie->msg, NL80211_KEY_IDX, cookie->idx))
4649 goto nla_put_failure;
4651 nla_nest_end(cookie->msg, key);
4653 return;
4654 nla_put_failure:
4655 cookie->error = 1;
4658 static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
4660 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4661 int err;
4662 struct net_device *dev = info->user_ptr[1];
4663 u8 key_idx = 0;
4664 const u8 *mac_addr = NULL;
4665 bool pairwise;
4666 struct get_key_cookie cookie = {
4667 .error = 0,
4669 void *hdr;
4670 struct sk_buff *msg;
4671 bool bigtk_support = false;
4672 int link_id = nl80211_link_id_or_invalid(info->attrs);
4673 struct wireless_dev *wdev = dev->ieee80211_ptr;
4675 if (wiphy_ext_feature_isset(&rdev->wiphy,
4676 NL80211_EXT_FEATURE_BEACON_PROTECTION))
4677 bigtk_support = true;
4679 if ((wdev->iftype == NL80211_IFTYPE_STATION ||
4680 wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) &&
4681 wiphy_ext_feature_isset(&rdev->wiphy,
4682 NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT))
4683 bigtk_support = true;
4685 if (info->attrs[NL80211_ATTR_KEY_IDX]) {
4686 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
4688 if (key_idx >= 6 && key_idx <= 7 && !bigtk_support) {
4689 GENL_SET_ERR_MSG(info, "BIGTK not supported");
4690 return -EINVAL;
4694 if (info->attrs[NL80211_ATTR_MAC])
4695 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4697 pairwise = !!mac_addr;
4698 if (info->attrs[NL80211_ATTR_KEY_TYPE]) {
4699 u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]);
4701 if (kt != NL80211_KEYTYPE_GROUP &&
4702 kt != NL80211_KEYTYPE_PAIRWISE)
4703 return -EINVAL;
4704 pairwise = kt == NL80211_KEYTYPE_PAIRWISE;
4707 if (!rdev->ops->get_key)
4708 return -EOPNOTSUPP;
4710 if (!pairwise && mac_addr && !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4711 return -ENOENT;
4713 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4714 if (!msg)
4715 return -ENOMEM;
4717 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
4718 NL80211_CMD_NEW_KEY);
4719 if (!hdr)
4720 goto nla_put_failure;
4722 cookie.msg = msg;
4723 cookie.idx = key_idx;
4725 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
4726 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx))
4727 goto nla_put_failure;
4728 if (mac_addr &&
4729 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr))
4730 goto nla_put_failure;
4732 err = nl80211_validate_key_link_id(info, wdev, link_id, pairwise);
4733 if (err)
4734 goto free_msg;
4736 err = rdev_get_key(rdev, dev, link_id, key_idx, pairwise, mac_addr,
4737 &cookie, get_key_callback);
4739 if (err)
4740 goto free_msg;
4742 if (cookie.error)
4743 goto nla_put_failure;
4745 genlmsg_end(msg, hdr);
4746 return genlmsg_reply(msg, info);
4748 nla_put_failure:
4749 err = -ENOBUFS;
4750 free_msg:
4751 nlmsg_free(msg);
4752 return err;
4755 static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
4757 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4758 struct key_parse key;
4759 int err;
4760 struct net_device *dev = info->user_ptr[1];
4761 int link_id = nl80211_link_id_or_invalid(info->attrs);
4762 struct wireless_dev *wdev = dev->ieee80211_ptr;
4764 err = nl80211_parse_key(info, &key);
4765 if (err)
4766 return err;
4768 if (key.idx < 0)
4769 return -EINVAL;
4771 /* Only support setting default key and
4772 * Extended Key ID action NL80211_KEY_SET_TX.
4774 if (!key.def && !key.defmgmt && !key.defbeacon &&
4775 !(key.p.mode == NL80211_KEY_SET_TX))
4776 return -EINVAL;
4778 if (key.def) {
4779 if (!rdev->ops->set_default_key)
4780 return -EOPNOTSUPP;
4782 err = nl80211_key_allowed(wdev);
4783 if (err)
4784 return err;
4786 err = nl80211_validate_key_link_id(info, wdev, link_id, false);
4787 if (err)
4788 return err;
4790 err = rdev_set_default_key(rdev, dev, link_id, key.idx,
4791 key.def_uni, key.def_multi);
4793 if (err)
4794 return err;
4796 #ifdef CONFIG_CFG80211_WEXT
4797 wdev->wext.default_key = key.idx;
4798 #endif
4799 return 0;
4800 } else if (key.defmgmt) {
4801 if (key.def_uni || !key.def_multi)
4802 return -EINVAL;
4804 if (!rdev->ops->set_default_mgmt_key)
4805 return -EOPNOTSUPP;
4807 err = nl80211_key_allowed(wdev);
4808 if (err)
4809 return err;
4811 err = nl80211_validate_key_link_id(info, wdev, link_id, false);
4812 if (err)
4813 return err;
4815 err = rdev_set_default_mgmt_key(rdev, dev, link_id, key.idx);
4816 if (err)
4817 return err;
4819 #ifdef CONFIG_CFG80211_WEXT
4820 wdev->wext.default_mgmt_key = key.idx;
4821 #endif
4822 return 0;
4823 } else if (key.defbeacon) {
4824 if (key.def_uni || !key.def_multi)
4825 return -EINVAL;
4827 if (!rdev->ops->set_default_beacon_key)
4828 return -EOPNOTSUPP;
4830 err = nl80211_key_allowed(wdev);
4831 if (err)
4832 return err;
4834 err = nl80211_validate_key_link_id(info, wdev, link_id, false);
4835 if (err)
4836 return err;
4838 return rdev_set_default_beacon_key(rdev, dev, link_id, key.idx);
4839 } else if (key.p.mode == NL80211_KEY_SET_TX &&
4840 wiphy_ext_feature_isset(&rdev->wiphy,
4841 NL80211_EXT_FEATURE_EXT_KEY_ID)) {
4842 u8 *mac_addr = NULL;
4844 if (info->attrs[NL80211_ATTR_MAC])
4845 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4847 if (!mac_addr || key.idx < 0 || key.idx > 1)
4848 return -EINVAL;
4850 err = nl80211_validate_key_link_id(info, wdev, link_id, true);
4851 if (err)
4852 return err;
4854 return rdev_add_key(rdev, dev, link_id, key.idx,
4855 NL80211_KEYTYPE_PAIRWISE,
4856 mac_addr, &key.p);
4859 return -EINVAL;
4862 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
4864 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4865 int err;
4866 struct net_device *dev = info->user_ptr[1];
4867 struct key_parse key;
4868 const u8 *mac_addr = NULL;
4869 int link_id = nl80211_link_id_or_invalid(info->attrs);
4870 struct wireless_dev *wdev = dev->ieee80211_ptr;
4872 err = nl80211_parse_key(info, &key);
4873 if (err)
4874 return err;
4876 if (!key.p.key) {
4877 GENL_SET_ERR_MSG(info, "no key");
4878 return -EINVAL;
4881 if (info->attrs[NL80211_ATTR_MAC])
4882 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4884 if (key.type == -1) {
4885 if (mac_addr)
4886 key.type = NL80211_KEYTYPE_PAIRWISE;
4887 else
4888 key.type = NL80211_KEYTYPE_GROUP;
4891 /* for now */
4892 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
4893 key.type != NL80211_KEYTYPE_GROUP) {
4894 GENL_SET_ERR_MSG(info, "key type not pairwise or group");
4895 return -EINVAL;
4898 if (key.type == NL80211_KEYTYPE_GROUP &&
4899 info->attrs[NL80211_ATTR_VLAN_ID])
4900 key.p.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
4902 if (!rdev->ops->add_key)
4903 return -EOPNOTSUPP;
4905 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx,
4906 key.type == NL80211_KEYTYPE_PAIRWISE,
4907 mac_addr)) {
4908 GENL_SET_ERR_MSG(info, "key setting validation failed");
4909 return -EINVAL;
4912 err = nl80211_key_allowed(wdev);
4913 if (err)
4914 GENL_SET_ERR_MSG(info, "key not allowed");
4916 if (!err)
4917 err = nl80211_validate_key_link_id(info, wdev, link_id,
4918 key.type == NL80211_KEYTYPE_PAIRWISE);
4920 if (!err) {
4921 err = rdev_add_key(rdev, dev, link_id, key.idx,
4922 key.type == NL80211_KEYTYPE_PAIRWISE,
4923 mac_addr, &key.p);
4924 if (err)
4925 GENL_SET_ERR_MSG(info, "key addition failed");
4928 return err;
4931 static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
4933 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4934 int err;
4935 struct net_device *dev = info->user_ptr[1];
4936 u8 *mac_addr = NULL;
4937 struct key_parse key;
4938 int link_id = nl80211_link_id_or_invalid(info->attrs);
4939 struct wireless_dev *wdev = dev->ieee80211_ptr;
4941 err = nl80211_parse_key(info, &key);
4942 if (err)
4943 return err;
4945 if (info->attrs[NL80211_ATTR_MAC])
4946 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
4948 if (key.type == -1) {
4949 if (mac_addr)
4950 key.type = NL80211_KEYTYPE_PAIRWISE;
4951 else
4952 key.type = NL80211_KEYTYPE_GROUP;
4955 /* for now */
4956 if (key.type != NL80211_KEYTYPE_PAIRWISE &&
4957 key.type != NL80211_KEYTYPE_GROUP)
4958 return -EINVAL;
4960 if (!cfg80211_valid_key_idx(rdev, key.idx,
4961 key.type == NL80211_KEYTYPE_PAIRWISE))
4962 return -EINVAL;
4964 if (!rdev->ops->del_key)
4965 return -EOPNOTSUPP;
4967 err = nl80211_key_allowed(wdev);
4969 if (key.type == NL80211_KEYTYPE_GROUP && mac_addr &&
4970 !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN))
4971 err = -ENOENT;
4973 if (!err)
4974 err = nl80211_validate_key_link_id(info, wdev, link_id,
4975 key.type == NL80211_KEYTYPE_PAIRWISE);
4977 if (!err)
4978 err = rdev_del_key(rdev, dev, link_id, key.idx,
4979 key.type == NL80211_KEYTYPE_PAIRWISE,
4980 mac_addr);
4982 #ifdef CONFIG_CFG80211_WEXT
4983 if (!err) {
4984 if (key.idx == wdev->wext.default_key)
4985 wdev->wext.default_key = -1;
4986 else if (key.idx == wdev->wext.default_mgmt_key)
4987 wdev->wext.default_mgmt_key = -1;
4989 #endif
4991 return err;
4994 /* This function returns an error or the number of nested attributes */
4995 static int validate_acl_mac_addrs(struct nlattr *nl_attr)
4997 struct nlattr *attr;
4998 int n_entries = 0, tmp;
5000 nla_for_each_nested(attr, nl_attr, tmp) {
5001 if (nla_len(attr) != ETH_ALEN)
5002 return -EINVAL;
5004 n_entries++;
5007 return n_entries;
5011 * This function parses ACL information and allocates memory for ACL data.
5012 * On successful return, the calling function is responsible to free the
5013 * ACL buffer returned by this function.
5015 static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy,
5016 struct genl_info *info)
5018 enum nl80211_acl_policy acl_policy;
5019 struct nlattr *attr;
5020 struct cfg80211_acl_data *acl;
5021 int i = 0, n_entries, tmp;
5023 if (!wiphy->max_acl_mac_addrs)
5024 return ERR_PTR(-EOPNOTSUPP);
5026 if (!info->attrs[NL80211_ATTR_ACL_POLICY])
5027 return ERR_PTR(-EINVAL);
5029 acl_policy = nla_get_u32(info->attrs[NL80211_ATTR_ACL_POLICY]);
5030 if (acl_policy != NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED &&
5031 acl_policy != NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
5032 return ERR_PTR(-EINVAL);
5034 if (!info->attrs[NL80211_ATTR_MAC_ADDRS])
5035 return ERR_PTR(-EINVAL);
5037 n_entries = validate_acl_mac_addrs(info->attrs[NL80211_ATTR_MAC_ADDRS]);
5038 if (n_entries < 0)
5039 return ERR_PTR(n_entries);
5041 if (n_entries > wiphy->max_acl_mac_addrs)
5042 return ERR_PTR(-EOPNOTSUPP);
5044 acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL);
5045 if (!acl)
5046 return ERR_PTR(-ENOMEM);
5047 acl->n_acl_entries = n_entries;
5049 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_MAC_ADDRS], tmp) {
5050 memcpy(acl->mac_addrs[i].addr, nla_data(attr), ETH_ALEN);
5051 i++;
5053 acl->acl_policy = acl_policy;
5055 return acl;
5058 static int nl80211_set_mac_acl(struct sk_buff *skb, struct genl_info *info)
5060 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5061 struct net_device *dev = info->user_ptr[1];
5062 struct cfg80211_acl_data *acl;
5063 int err;
5065 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
5066 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
5067 return -EOPNOTSUPP;
5069 if (!dev->ieee80211_ptr->links[0].ap.beacon_interval)
5070 return -EINVAL;
5072 acl = parse_acl_data(&rdev->wiphy, info);
5073 if (IS_ERR(acl))
5074 return PTR_ERR(acl);
5076 err = rdev_set_mac_acl(rdev, dev, acl);
5078 kfree(acl);
5080 return err;
5083 static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
5084 u8 *rates, u8 rates_len)
5086 u8 i;
5087 u32 mask = 0;
5089 for (i = 0; i < rates_len; i++) {
5090 int rate = (rates[i] & 0x7f) * 5;
5091 int ridx;
5093 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
5094 struct ieee80211_rate *srate =
5095 &sband->bitrates[ridx];
5096 if (rate == srate->bitrate) {
5097 mask |= 1 << ridx;
5098 break;
5101 if (ridx == sband->n_bitrates)
5102 return 0; /* rate not found */
5105 return mask;
5108 static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband,
5109 u8 *rates, u8 rates_len,
5110 u8 mcs[IEEE80211_HT_MCS_MASK_LEN])
5112 u8 i;
5114 memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN);
5116 for (i = 0; i < rates_len; i++) {
5117 int ridx, rbit;
5119 ridx = rates[i] / 8;
5120 rbit = BIT(rates[i] % 8);
5122 /* check validity */
5123 if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN))
5124 return false;
5126 /* check availability */
5127 ridx = array_index_nospec(ridx, IEEE80211_HT_MCS_MASK_LEN);
5128 if (sband->ht_cap.mcs.rx_mask[ridx] & rbit)
5129 mcs[ridx] |= rbit;
5130 else
5131 return false;
5134 return true;
5137 static u16 vht_mcs_map_to_mcs_mask(u8 vht_mcs_map)
5139 u16 mcs_mask = 0;
5141 switch (vht_mcs_map) {
5142 case IEEE80211_VHT_MCS_NOT_SUPPORTED:
5143 break;
5144 case IEEE80211_VHT_MCS_SUPPORT_0_7:
5145 mcs_mask = 0x00FF;
5146 break;
5147 case IEEE80211_VHT_MCS_SUPPORT_0_8:
5148 mcs_mask = 0x01FF;
5149 break;
5150 case IEEE80211_VHT_MCS_SUPPORT_0_9:
5151 mcs_mask = 0x03FF;
5152 break;
5153 default:
5154 break;
5157 return mcs_mask;
5160 static void vht_build_mcs_mask(u16 vht_mcs_map,
5161 u16 vht_mcs_mask[NL80211_VHT_NSS_MAX])
5163 u8 nss;
5165 for (nss = 0; nss < NL80211_VHT_NSS_MAX; nss++) {
5166 vht_mcs_mask[nss] = vht_mcs_map_to_mcs_mask(vht_mcs_map & 0x03);
5167 vht_mcs_map >>= 2;
5171 static bool vht_set_mcs_mask(struct ieee80211_supported_band *sband,
5172 struct nl80211_txrate_vht *txrate,
5173 u16 mcs[NL80211_VHT_NSS_MAX])
5175 u16 tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
5176 u16 tx_mcs_mask[NL80211_VHT_NSS_MAX] = {};
5177 u8 i;
5179 if (!sband->vht_cap.vht_supported)
5180 return false;
5182 memset(mcs, 0, sizeof(u16) * NL80211_VHT_NSS_MAX);
5184 /* Build vht_mcs_mask from VHT capabilities */
5185 vht_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
5187 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
5188 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
5189 mcs[i] = txrate->mcs[i];
5190 else
5191 return false;
5194 return true;
5197 static u16 he_mcs_map_to_mcs_mask(u8 he_mcs_map)
5199 switch (he_mcs_map) {
5200 case IEEE80211_HE_MCS_NOT_SUPPORTED:
5201 return 0;
5202 case IEEE80211_HE_MCS_SUPPORT_0_7:
5203 return 0x00FF;
5204 case IEEE80211_HE_MCS_SUPPORT_0_9:
5205 return 0x03FF;
5206 case IEEE80211_HE_MCS_SUPPORT_0_11:
5207 return 0xFFF;
5208 default:
5209 break;
5211 return 0;
5214 static void he_build_mcs_mask(u16 he_mcs_map,
5215 u16 he_mcs_mask[NL80211_HE_NSS_MAX])
5217 u8 nss;
5219 for (nss = 0; nss < NL80211_HE_NSS_MAX; nss++) {
5220 he_mcs_mask[nss] = he_mcs_map_to_mcs_mask(he_mcs_map & 0x03);
5221 he_mcs_map >>= 2;
5225 static u16 he_get_txmcsmap(struct genl_info *info, unsigned int link_id,
5226 const struct ieee80211_sta_he_cap *he_cap)
5228 struct net_device *dev = info->user_ptr[1];
5229 struct wireless_dev *wdev = dev->ieee80211_ptr;
5230 struct cfg80211_chan_def *chandef;
5231 __le16 tx_mcs;
5233 chandef = wdev_chandef(wdev, link_id);
5234 if (!chandef) {
5236 * This is probably broken, but we never maintained
5237 * a chandef in these cases, so it always was.
5239 return le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80);
5242 switch (chandef->width) {
5243 case NL80211_CHAN_WIDTH_80P80:
5244 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80p80;
5245 break;
5246 case NL80211_CHAN_WIDTH_160:
5247 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_160;
5248 break;
5249 default:
5250 tx_mcs = he_cap->he_mcs_nss_supp.tx_mcs_80;
5251 break;
5254 return le16_to_cpu(tx_mcs);
5257 static bool he_set_mcs_mask(struct genl_info *info,
5258 struct wireless_dev *wdev,
5259 struct ieee80211_supported_band *sband,
5260 struct nl80211_txrate_he *txrate,
5261 u16 mcs[NL80211_HE_NSS_MAX],
5262 unsigned int link_id)
5264 const struct ieee80211_sta_he_cap *he_cap;
5265 u16 tx_mcs_mask[NL80211_HE_NSS_MAX] = {};
5266 u16 tx_mcs_map = 0;
5267 u8 i;
5269 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
5270 if (!he_cap)
5271 return false;
5273 memset(mcs, 0, sizeof(u16) * NL80211_HE_NSS_MAX);
5275 tx_mcs_map = he_get_txmcsmap(info, link_id, he_cap);
5277 /* Build he_mcs_mask from HE capabilities */
5278 he_build_mcs_mask(tx_mcs_map, tx_mcs_mask);
5280 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
5281 if ((tx_mcs_mask[i] & txrate->mcs[i]) == txrate->mcs[i])
5282 mcs[i] = txrate->mcs[i];
5283 else
5284 return false;
5287 return true;
5290 static int nl80211_parse_tx_bitrate_mask(struct genl_info *info,
5291 struct nlattr *attrs[],
5292 enum nl80211_attrs attr,
5293 struct cfg80211_bitrate_mask *mask,
5294 struct net_device *dev,
5295 bool default_all_enabled,
5296 unsigned int link_id)
5298 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
5299 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5300 struct wireless_dev *wdev = dev->ieee80211_ptr;
5301 int rem, i;
5302 struct nlattr *tx_rates;
5303 struct ieee80211_supported_band *sband;
5304 u16 vht_tx_mcs_map, he_tx_mcs_map;
5306 memset(mask, 0, sizeof(*mask));
5307 /* Default to all rates enabled */
5308 for (i = 0; i < NUM_NL80211_BANDS; i++) {
5309 const struct ieee80211_sta_he_cap *he_cap;
5311 if (!default_all_enabled)
5312 break;
5314 sband = rdev->wiphy.bands[i];
5316 if (!sband)
5317 continue;
5319 mask->control[i].legacy = (1 << sband->n_bitrates) - 1;
5320 memcpy(mask->control[i].ht_mcs,
5321 sband->ht_cap.mcs.rx_mask,
5322 sizeof(mask->control[i].ht_mcs));
5324 if (sband->vht_cap.vht_supported) {
5325 vht_tx_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
5326 vht_build_mcs_mask(vht_tx_mcs_map, mask->control[i].vht_mcs);
5329 he_cap = ieee80211_get_he_iftype_cap(sband, wdev->iftype);
5330 if (!he_cap)
5331 continue;
5333 he_tx_mcs_map = he_get_txmcsmap(info, link_id, he_cap);
5334 he_build_mcs_mask(he_tx_mcs_map, mask->control[i].he_mcs);
5336 mask->control[i].he_gi = 0xFF;
5337 mask->control[i].he_ltf = 0xFF;
5340 /* if no rates are given set it back to the defaults */
5341 if (!attrs[attr])
5342 goto out;
5344 /* The nested attribute uses enum nl80211_band as the index. This maps
5345 * directly to the enum nl80211_band values used in cfg80211.
5347 BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8);
5348 nla_for_each_nested(tx_rates, attrs[attr], rem) {
5349 enum nl80211_band band = nla_type(tx_rates);
5350 int err;
5352 if (band < 0 || band >= NUM_NL80211_BANDS)
5353 return -EINVAL;
5354 sband = rdev->wiphy.bands[band];
5355 if (sband == NULL)
5356 return -EINVAL;
5357 err = nla_parse_nested_deprecated(tb, NL80211_TXRATE_MAX,
5358 tx_rates,
5359 nl80211_txattr_policy,
5360 info->extack);
5361 if (err)
5362 return err;
5363 if (tb[NL80211_TXRATE_LEGACY]) {
5364 mask->control[band].legacy = rateset_to_mask(
5365 sband,
5366 nla_data(tb[NL80211_TXRATE_LEGACY]),
5367 nla_len(tb[NL80211_TXRATE_LEGACY]));
5368 if ((mask->control[band].legacy == 0) &&
5369 nla_len(tb[NL80211_TXRATE_LEGACY]))
5370 return -EINVAL;
5372 if (tb[NL80211_TXRATE_HT]) {
5373 if (!ht_rateset_to_mask(
5374 sband,
5375 nla_data(tb[NL80211_TXRATE_HT]),
5376 nla_len(tb[NL80211_TXRATE_HT]),
5377 mask->control[band].ht_mcs))
5378 return -EINVAL;
5381 if (tb[NL80211_TXRATE_VHT]) {
5382 if (!vht_set_mcs_mask(
5383 sband,
5384 nla_data(tb[NL80211_TXRATE_VHT]),
5385 mask->control[band].vht_mcs))
5386 return -EINVAL;
5389 if (tb[NL80211_TXRATE_GI]) {
5390 mask->control[band].gi =
5391 nla_get_u8(tb[NL80211_TXRATE_GI]);
5392 if (mask->control[band].gi > NL80211_TXRATE_FORCE_LGI)
5393 return -EINVAL;
5395 if (tb[NL80211_TXRATE_HE] &&
5396 !he_set_mcs_mask(info, wdev, sband,
5397 nla_data(tb[NL80211_TXRATE_HE]),
5398 mask->control[band].he_mcs,
5399 link_id))
5400 return -EINVAL;
5402 if (tb[NL80211_TXRATE_HE_GI])
5403 mask->control[band].he_gi =
5404 nla_get_u8(tb[NL80211_TXRATE_HE_GI]);
5405 if (tb[NL80211_TXRATE_HE_LTF])
5406 mask->control[band].he_ltf =
5407 nla_get_u8(tb[NL80211_TXRATE_HE_LTF]);
5409 if (mask->control[band].legacy == 0) {
5410 /* don't allow empty legacy rates if HT, VHT or HE
5411 * are not even supported.
5413 if (!(rdev->wiphy.bands[band]->ht_cap.ht_supported ||
5414 rdev->wiphy.bands[band]->vht_cap.vht_supported ||
5415 ieee80211_get_he_iftype_cap(sband, wdev->iftype)))
5416 return -EINVAL;
5418 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++)
5419 if (mask->control[band].ht_mcs[i])
5420 goto out;
5422 for (i = 0; i < NL80211_VHT_NSS_MAX; i++)
5423 if (mask->control[band].vht_mcs[i])
5424 goto out;
5426 for (i = 0; i < NL80211_HE_NSS_MAX; i++)
5427 if (mask->control[band].he_mcs[i])
5428 goto out;
5430 /* legacy and mcs rates may not be both empty */
5431 return -EINVAL;
5435 out:
5436 return 0;
5439 static int validate_beacon_tx_rate(struct cfg80211_registered_device *rdev,
5440 enum nl80211_band band,
5441 struct cfg80211_bitrate_mask *beacon_rate)
5443 u32 count_ht, count_vht, count_he, i;
5444 u32 rate = beacon_rate->control[band].legacy;
5446 /* Allow only one rate */
5447 if (hweight32(rate) > 1)
5448 return -EINVAL;
5450 count_ht = 0;
5451 for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) {
5452 if (hweight8(beacon_rate->control[band].ht_mcs[i]) > 1) {
5453 return -EINVAL;
5454 } else if (beacon_rate->control[band].ht_mcs[i]) {
5455 count_ht++;
5456 if (count_ht > 1)
5457 return -EINVAL;
5459 if (count_ht && rate)
5460 return -EINVAL;
5463 count_vht = 0;
5464 for (i = 0; i < NL80211_VHT_NSS_MAX; i++) {
5465 if (hweight16(beacon_rate->control[band].vht_mcs[i]) > 1) {
5466 return -EINVAL;
5467 } else if (beacon_rate->control[band].vht_mcs[i]) {
5468 count_vht++;
5469 if (count_vht > 1)
5470 return -EINVAL;
5472 if (count_vht && rate)
5473 return -EINVAL;
5476 count_he = 0;
5477 for (i = 0; i < NL80211_HE_NSS_MAX; i++) {
5478 if (hweight16(beacon_rate->control[band].he_mcs[i]) > 1) {
5479 return -EINVAL;
5480 } else if (beacon_rate->control[band].he_mcs[i]) {
5481 count_he++;
5482 if (count_he > 1)
5483 return -EINVAL;
5485 if (count_he && rate)
5486 return -EINVAL;
5489 if ((count_ht && count_vht && count_he) ||
5490 (!rate && !count_ht && !count_vht && !count_he))
5491 return -EINVAL;
5493 if (rate &&
5494 !wiphy_ext_feature_isset(&rdev->wiphy,
5495 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY))
5496 return -EINVAL;
5497 if (count_ht &&
5498 !wiphy_ext_feature_isset(&rdev->wiphy,
5499 NL80211_EXT_FEATURE_BEACON_RATE_HT))
5500 return -EINVAL;
5501 if (count_vht &&
5502 !wiphy_ext_feature_isset(&rdev->wiphy,
5503 NL80211_EXT_FEATURE_BEACON_RATE_VHT))
5504 return -EINVAL;
5505 if (count_he &&
5506 !wiphy_ext_feature_isset(&rdev->wiphy,
5507 NL80211_EXT_FEATURE_BEACON_RATE_HE))
5508 return -EINVAL;
5510 return 0;
5513 static int nl80211_parse_mbssid_config(struct wiphy *wiphy,
5514 struct net_device *dev,
5515 struct nlattr *attrs,
5516 struct cfg80211_mbssid_config *config,
5517 u8 num_elems)
5519 struct nlattr *tb[NL80211_MBSSID_CONFIG_ATTR_MAX + 1];
5521 if (!wiphy->mbssid_max_interfaces)
5522 return -EOPNOTSUPP;
5524 if (nla_parse_nested(tb, NL80211_MBSSID_CONFIG_ATTR_MAX, attrs, NULL,
5525 NULL) ||
5526 !tb[NL80211_MBSSID_CONFIG_ATTR_INDEX])
5527 return -EINVAL;
5529 config->ema = nla_get_flag(tb[NL80211_MBSSID_CONFIG_ATTR_EMA]);
5530 if (config->ema) {
5531 if (!wiphy->ema_max_profile_periodicity)
5532 return -EOPNOTSUPP;
5534 if (num_elems > wiphy->ema_max_profile_periodicity)
5535 return -EINVAL;
5538 config->index = nla_get_u8(tb[NL80211_MBSSID_CONFIG_ATTR_INDEX]);
5539 if (config->index >= wiphy->mbssid_max_interfaces ||
5540 (!config->index && !num_elems))
5541 return -EINVAL;
5543 if (tb[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX]) {
5544 u32 tx_ifindex =
5545 nla_get_u32(tb[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX]);
5547 if ((!config->index && tx_ifindex != dev->ifindex) ||
5548 (config->index && tx_ifindex == dev->ifindex))
5549 return -EINVAL;
5551 if (tx_ifindex != dev->ifindex) {
5552 struct net_device *tx_netdev =
5553 dev_get_by_index(wiphy_net(wiphy), tx_ifindex);
5555 if (!tx_netdev || !tx_netdev->ieee80211_ptr ||
5556 tx_netdev->ieee80211_ptr->wiphy != wiphy ||
5557 tx_netdev->ieee80211_ptr->iftype !=
5558 NL80211_IFTYPE_AP) {
5559 dev_put(tx_netdev);
5560 return -EINVAL;
5563 config->tx_wdev = tx_netdev->ieee80211_ptr;
5564 } else {
5565 config->tx_wdev = dev->ieee80211_ptr;
5567 } else if (!config->index) {
5568 config->tx_wdev = dev->ieee80211_ptr;
5569 } else {
5570 return -EINVAL;
5573 return 0;
5576 static struct cfg80211_mbssid_elems *
5577 nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs)
5579 struct nlattr *nl_elems;
5580 struct cfg80211_mbssid_elems *elems;
5581 int rem_elems;
5582 u8 i = 0, num_elems = 0;
5584 if (!wiphy->mbssid_max_interfaces)
5585 return ERR_PTR(-EINVAL);
5587 nla_for_each_nested(nl_elems, attrs, rem_elems) {
5588 if (num_elems >= 255)
5589 return ERR_PTR(-EINVAL);
5590 num_elems++;
5593 elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL);
5594 if (!elems)
5595 return ERR_PTR(-ENOMEM);
5596 elems->cnt = num_elems;
5598 nla_for_each_nested(nl_elems, attrs, rem_elems) {
5599 elems->elem[i].data = nla_data(nl_elems);
5600 elems->elem[i].len = nla_len(nl_elems);
5601 i++;
5603 return elems;
5606 static struct cfg80211_rnr_elems *
5607 nl80211_parse_rnr_elems(struct wiphy *wiphy, struct nlattr *attrs,
5608 struct netlink_ext_ack *extack)
5610 struct nlattr *nl_elems;
5611 struct cfg80211_rnr_elems *elems;
5612 int rem_elems;
5613 u8 i = 0, num_elems = 0;
5615 nla_for_each_nested(nl_elems, attrs, rem_elems) {
5616 int ret;
5618 ret = validate_ie_attr(nl_elems, extack);
5619 if (ret)
5620 return ERR_PTR(ret);
5622 num_elems++;
5625 elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL);
5626 if (!elems)
5627 return ERR_PTR(-ENOMEM);
5628 elems->cnt = num_elems;
5630 nla_for_each_nested(nl_elems, attrs, rem_elems) {
5631 elems->elem[i].data = nla_data(nl_elems);
5632 elems->elem[i].len = nla_len(nl_elems);
5633 i++;
5635 return elems;
5638 static int nl80211_parse_he_bss_color(struct nlattr *attrs,
5639 struct cfg80211_he_bss_color *he_bss_color)
5641 struct nlattr *tb[NL80211_HE_BSS_COLOR_ATTR_MAX + 1];
5642 int err;
5644 err = nla_parse_nested(tb, NL80211_HE_BSS_COLOR_ATTR_MAX, attrs,
5645 he_bss_color_policy, NULL);
5646 if (err)
5647 return err;
5649 if (!tb[NL80211_HE_BSS_COLOR_ATTR_COLOR])
5650 return -EINVAL;
5652 he_bss_color->color =
5653 nla_get_u8(tb[NL80211_HE_BSS_COLOR_ATTR_COLOR]);
5654 he_bss_color->enabled =
5655 !nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_DISABLED]);
5656 he_bss_color->partial =
5657 nla_get_flag(tb[NL80211_HE_BSS_COLOR_ATTR_PARTIAL]);
5659 return 0;
5662 static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev,
5663 struct nlattr *attrs[],
5664 struct cfg80211_beacon_data *bcn,
5665 struct netlink_ext_ack *extack)
5667 bool haveinfo = false;
5668 int err;
5670 memset(bcn, 0, sizeof(*bcn));
5672 bcn->link_id = nl80211_link_id(attrs);
5674 if (attrs[NL80211_ATTR_BEACON_HEAD]) {
5675 bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
5676 bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
5677 if (!bcn->head_len)
5678 return -EINVAL;
5679 haveinfo = true;
5682 if (attrs[NL80211_ATTR_BEACON_TAIL]) {
5683 bcn->tail = nla_data(attrs[NL80211_ATTR_BEACON_TAIL]);
5684 bcn->tail_len = nla_len(attrs[NL80211_ATTR_BEACON_TAIL]);
5685 haveinfo = true;
5688 if (!haveinfo)
5689 return -EINVAL;
5691 if (attrs[NL80211_ATTR_IE]) {
5692 bcn->beacon_ies = nla_data(attrs[NL80211_ATTR_IE]);
5693 bcn->beacon_ies_len = nla_len(attrs[NL80211_ATTR_IE]);
5696 if (attrs[NL80211_ATTR_IE_PROBE_RESP]) {
5697 bcn->proberesp_ies =
5698 nla_data(attrs[NL80211_ATTR_IE_PROBE_RESP]);
5699 bcn->proberesp_ies_len =
5700 nla_len(attrs[NL80211_ATTR_IE_PROBE_RESP]);
5703 if (attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
5704 bcn->assocresp_ies =
5705 nla_data(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
5706 bcn->assocresp_ies_len =
5707 nla_len(attrs[NL80211_ATTR_IE_ASSOC_RESP]);
5710 if (attrs[NL80211_ATTR_PROBE_RESP]) {
5711 bcn->probe_resp = nla_data(attrs[NL80211_ATTR_PROBE_RESP]);
5712 bcn->probe_resp_len = nla_len(attrs[NL80211_ATTR_PROBE_RESP]);
5715 if (attrs[NL80211_ATTR_FTM_RESPONDER]) {
5716 struct nlattr *tb[NL80211_FTM_RESP_ATTR_MAX + 1];
5718 err = nla_parse_nested_deprecated(tb,
5719 NL80211_FTM_RESP_ATTR_MAX,
5720 attrs[NL80211_ATTR_FTM_RESPONDER],
5721 NULL, NULL);
5722 if (err)
5723 return err;
5725 if (tb[NL80211_FTM_RESP_ATTR_ENABLED] &&
5726 wiphy_ext_feature_isset(&rdev->wiphy,
5727 NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER))
5728 bcn->ftm_responder = 1;
5729 else
5730 return -EOPNOTSUPP;
5732 if (tb[NL80211_FTM_RESP_ATTR_LCI]) {
5733 bcn->lci = nla_data(tb[NL80211_FTM_RESP_ATTR_LCI]);
5734 bcn->lci_len = nla_len(tb[NL80211_FTM_RESP_ATTR_LCI]);
5737 if (tb[NL80211_FTM_RESP_ATTR_CIVICLOC]) {
5738 bcn->civicloc = nla_data(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5739 bcn->civicloc_len = nla_len(tb[NL80211_FTM_RESP_ATTR_CIVICLOC]);
5741 } else {
5742 bcn->ftm_responder = -1;
5745 if (attrs[NL80211_ATTR_HE_BSS_COLOR]) {
5746 err = nl80211_parse_he_bss_color(attrs[NL80211_ATTR_HE_BSS_COLOR],
5747 &bcn->he_bss_color);
5748 if (err)
5749 return err;
5750 bcn->he_bss_color_valid = true;
5753 if (attrs[NL80211_ATTR_MBSSID_ELEMS]) {
5754 struct cfg80211_mbssid_elems *mbssid =
5755 nl80211_parse_mbssid_elems(&rdev->wiphy,
5756 attrs[NL80211_ATTR_MBSSID_ELEMS]);
5758 if (IS_ERR(mbssid))
5759 return PTR_ERR(mbssid);
5761 bcn->mbssid_ies = mbssid;
5763 if (bcn->mbssid_ies && attrs[NL80211_ATTR_EMA_RNR_ELEMS]) {
5764 struct cfg80211_rnr_elems *rnr =
5765 nl80211_parse_rnr_elems(&rdev->wiphy,
5766 attrs[NL80211_ATTR_EMA_RNR_ELEMS],
5767 extack);
5769 if (IS_ERR(rnr))
5770 return PTR_ERR(rnr);
5772 if (rnr && rnr->cnt < bcn->mbssid_ies->cnt)
5773 return -EINVAL;
5775 bcn->rnr_ies = rnr;
5779 return 0;
5782 static int nl80211_parse_he_obss_pd(struct nlattr *attrs,
5783 struct ieee80211_he_obss_pd *he_obss_pd)
5785 struct nlattr *tb[NL80211_HE_OBSS_PD_ATTR_MAX + 1];
5786 int err;
5788 err = nla_parse_nested(tb, NL80211_HE_OBSS_PD_ATTR_MAX, attrs,
5789 he_obss_pd_policy, NULL);
5790 if (err)
5791 return err;
5793 if (!tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL])
5794 return -EINVAL;
5796 he_obss_pd->sr_ctrl = nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_SR_CTRL]);
5798 if (tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET])
5799 he_obss_pd->min_offset =
5800 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MIN_OFFSET]);
5801 if (tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET])
5802 he_obss_pd->max_offset =
5803 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_MAX_OFFSET]);
5804 if (tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET])
5805 he_obss_pd->non_srg_max_offset =
5806 nla_get_u8(tb[NL80211_HE_OBSS_PD_ATTR_NON_SRG_MAX_OFFSET]);
5808 if (he_obss_pd->min_offset > he_obss_pd->max_offset)
5809 return -EINVAL;
5811 if (tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP])
5812 memcpy(he_obss_pd->bss_color_bitmap,
5813 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_BSS_COLOR_BITMAP]),
5814 sizeof(he_obss_pd->bss_color_bitmap));
5816 if (tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP])
5817 memcpy(he_obss_pd->partial_bssid_bitmap,
5818 nla_data(tb[NL80211_HE_OBSS_PD_ATTR_PARTIAL_BSSID_BITMAP]),
5819 sizeof(he_obss_pd->partial_bssid_bitmap));
5821 he_obss_pd->enable = true;
5823 return 0;
5826 static int nl80211_parse_fils_discovery(struct cfg80211_registered_device *rdev,
5827 struct nlattr *attrs,
5828 struct cfg80211_fils_discovery *fd)
5830 struct nlattr *tb[NL80211_FILS_DISCOVERY_ATTR_MAX + 1];
5831 int ret;
5833 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5834 NL80211_EXT_FEATURE_FILS_DISCOVERY))
5835 return -EINVAL;
5837 ret = nla_parse_nested(tb, NL80211_FILS_DISCOVERY_ATTR_MAX, attrs,
5838 NULL, NULL);
5839 if (ret)
5840 return ret;
5842 if (!tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN] &&
5843 !tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX] &&
5844 !tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]) {
5845 fd->update = true;
5846 return 0;
5849 if (!tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN] ||
5850 !tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX] ||
5851 !tb[NL80211_FILS_DISCOVERY_ATTR_TMPL])
5852 return -EINVAL;
5854 fd->tmpl_len = nla_len(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5855 fd->tmpl = nla_data(tb[NL80211_FILS_DISCOVERY_ATTR_TMPL]);
5856 fd->min_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MIN]);
5857 fd->max_interval = nla_get_u32(tb[NL80211_FILS_DISCOVERY_ATTR_INT_MAX]);
5858 fd->update = true;
5859 return 0;
5862 static int
5863 nl80211_parse_unsol_bcast_probe_resp(struct cfg80211_registered_device *rdev,
5864 struct nlattr *attrs,
5865 struct cfg80211_unsol_bcast_probe_resp *presp)
5867 struct nlattr *tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX + 1];
5868 int ret;
5870 if (!wiphy_ext_feature_isset(&rdev->wiphy,
5871 NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP))
5872 return -EINVAL;
5874 ret = nla_parse_nested(tb, NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_MAX,
5875 attrs, NULL, NULL);
5876 if (ret)
5877 return ret;
5879 if (!tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] &&
5880 !tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]) {
5881 presp->update = true;
5882 return 0;
5885 if (!tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT] ||
5886 !tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL])
5887 return -EINVAL;
5889 presp->tmpl = nla_data(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5890 presp->tmpl_len = nla_len(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_TMPL]);
5891 presp->interval = nla_get_u32(tb[NL80211_UNSOL_BCAST_PROBE_RESP_ATTR_INT]);
5892 presp->update = true;
5893 return 0;
5896 static void nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
5897 const struct element *rates)
5899 int i;
5901 if (!rates)
5902 return;
5904 for (i = 0; i < rates->datalen; i++) {
5905 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
5906 params->ht_required = true;
5907 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
5908 params->vht_required = true;
5909 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_HE_PHY)
5910 params->he_required = true;
5911 if (rates->data[i] == BSS_MEMBERSHIP_SELECTOR_SAE_H2E)
5912 params->sae_h2e_required = true;
5917 * Since the nl80211 API didn't include, from the beginning, attributes about
5918 * HT/VHT requirements/capabilities, we parse them out of the IEs for the
5919 * benefit of drivers that rebuild IEs in the firmware.
5921 static int nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
5923 const struct cfg80211_beacon_data *bcn = &params->beacon;
5924 size_t ies_len = bcn->tail_len;
5925 const u8 *ies = bcn->tail;
5926 const struct element *rates;
5927 const struct element *cap;
5929 rates = cfg80211_find_elem(WLAN_EID_SUPP_RATES, ies, ies_len);
5930 nl80211_check_ap_rate_selectors(params, rates);
5932 rates = cfg80211_find_elem(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
5933 nl80211_check_ap_rate_selectors(params, rates);
5935 cap = cfg80211_find_elem(WLAN_EID_HT_CAPABILITY, ies, ies_len);
5936 if (cap && cap->datalen >= sizeof(*params->ht_cap))
5937 params->ht_cap = (void *)cap->data;
5938 cap = cfg80211_find_elem(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
5939 if (cap && cap->datalen >= sizeof(*params->vht_cap))
5940 params->vht_cap = (void *)cap->data;
5941 cap = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
5942 if (cap && cap->datalen >= sizeof(*params->he_cap) + 1)
5943 params->he_cap = (void *)(cap->data + 1);
5944 cap = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
5945 if (cap && cap->datalen >= sizeof(*params->he_oper) + 1)
5946 params->he_oper = (void *)(cap->data + 1);
5947 cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_CAPABILITY, ies, ies_len);
5948 if (cap) {
5949 if (!cap->datalen)
5950 return -EINVAL;
5951 params->eht_cap = (void *)(cap->data + 1);
5952 if (!ieee80211_eht_capa_size_ok((const u8 *)params->he_cap,
5953 (const u8 *)params->eht_cap,
5954 cap->datalen - 1, true))
5955 return -EINVAL;
5957 cap = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_OPERATION, ies, ies_len);
5958 if (cap) {
5959 if (!cap->datalen)
5960 return -EINVAL;
5961 params->eht_oper = (void *)(cap->data + 1);
5962 if (!ieee80211_eht_oper_size_ok((const u8 *)params->eht_oper,
5963 cap->datalen - 1))
5964 return -EINVAL;
5966 return 0;
5969 static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
5970 struct cfg80211_ap_settings *params)
5972 struct wireless_dev *wdev;
5974 list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
5975 if (wdev->iftype != NL80211_IFTYPE_AP &&
5976 wdev->iftype != NL80211_IFTYPE_P2P_GO)
5977 continue;
5979 if (!wdev->u.ap.preset_chandef.chan)
5980 continue;
5982 params->chandef = wdev->u.ap.preset_chandef;
5983 return true;
5986 return false;
5989 static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
5990 enum nl80211_auth_type auth_type,
5991 enum nl80211_commands cmd)
5993 if (auth_type > NL80211_AUTHTYPE_MAX)
5994 return false;
5996 switch (cmd) {
5997 case NL80211_CMD_AUTHENTICATE:
5998 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
5999 auth_type == NL80211_AUTHTYPE_SAE)
6000 return false;
6001 if (!wiphy_ext_feature_isset(&rdev->wiphy,
6002 NL80211_EXT_FEATURE_FILS_STA) &&
6003 (auth_type == NL80211_AUTHTYPE_FILS_SK ||
6004 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
6005 auth_type == NL80211_AUTHTYPE_FILS_PK))
6006 return false;
6007 return true;
6008 case NL80211_CMD_CONNECT:
6009 if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
6010 !wiphy_ext_feature_isset(&rdev->wiphy,
6011 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
6012 auth_type == NL80211_AUTHTYPE_SAE)
6013 return false;
6015 /* FILS with SK PFS or PK not supported yet */
6016 if (auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
6017 auth_type == NL80211_AUTHTYPE_FILS_PK)
6018 return false;
6019 if (!wiphy_ext_feature_isset(
6020 &rdev->wiphy,
6021 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
6022 auth_type == NL80211_AUTHTYPE_FILS_SK)
6023 return false;
6024 return true;
6025 case NL80211_CMD_START_AP:
6026 if (!wiphy_ext_feature_isset(&rdev->wiphy,
6027 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP) &&
6028 auth_type == NL80211_AUTHTYPE_SAE)
6029 return false;
6030 /* FILS not supported yet */
6031 if (auth_type == NL80211_AUTHTYPE_FILS_SK ||
6032 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
6033 auth_type == NL80211_AUTHTYPE_FILS_PK)
6034 return false;
6035 return true;
6036 default:
6037 return false;
6041 static void nl80211_send_ap_started(struct wireless_dev *wdev,
6042 unsigned int link_id)
6044 struct wiphy *wiphy = wdev->wiphy;
6045 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
6046 struct sk_buff *msg;
6047 void *hdr;
6049 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6050 if (!msg)
6051 return;
6053 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_START_AP);
6054 if (!hdr)
6055 goto out;
6057 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
6058 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
6059 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
6060 NL80211_ATTR_PAD) ||
6061 (wdev->u.ap.ssid_len &&
6062 nla_put(msg, NL80211_ATTR_SSID, wdev->u.ap.ssid_len,
6063 wdev->u.ap.ssid)) ||
6064 (wdev->valid_links &&
6065 nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)))
6066 goto out;
6068 genlmsg_end(msg, hdr);
6070 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
6071 NL80211_MCGRP_MLME, GFP_KERNEL);
6072 return;
6073 out:
6074 nlmsg_free(msg);
6077 static int nl80211_validate_ap_phy_operation(struct cfg80211_ap_settings *params)
6079 struct ieee80211_channel *channel = params->chandef.chan;
6081 if ((params->he_cap || params->he_oper) &&
6082 (channel->flags & IEEE80211_CHAN_NO_HE))
6083 return -EOPNOTSUPP;
6085 if ((params->eht_cap || params->eht_oper) &&
6086 (channel->flags & IEEE80211_CHAN_NO_EHT))
6087 return -EOPNOTSUPP;
6089 return 0;
6092 static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
6094 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6095 struct cfg80211_beaconing_check_config beacon_check = {};
6096 unsigned int link_id = nl80211_link_id(info->attrs);
6097 struct net_device *dev = info->user_ptr[1];
6098 struct wireless_dev *wdev = dev->ieee80211_ptr;
6099 struct cfg80211_ap_settings *params;
6100 int err;
6102 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
6103 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6104 return -EOPNOTSUPP;
6106 if (!rdev->ops->start_ap)
6107 return -EOPNOTSUPP;
6109 if (wdev->links[link_id].cac_started)
6110 return -EBUSY;
6112 if (wdev->links[link_id].ap.beacon_interval)
6113 return -EALREADY;
6115 /* these are required for START_AP */
6116 if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] ||
6117 !info->attrs[NL80211_ATTR_DTIM_PERIOD] ||
6118 !info->attrs[NL80211_ATTR_BEACON_HEAD])
6119 return -EINVAL;
6121 if (info->attrs[NL80211_ATTR_SMPS_MODE] &&
6122 nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]) != NL80211_SMPS_OFF)
6123 return -EOPNOTSUPP;
6125 params = kzalloc(sizeof(*params), GFP_KERNEL);
6126 if (!params)
6127 return -ENOMEM;
6129 err = nl80211_parse_beacon(rdev, info->attrs, &params->beacon,
6130 info->extack);
6131 if (err)
6132 goto out;
6134 params->beacon_interval =
6135 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
6136 params->dtim_period =
6137 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
6139 err = cfg80211_validate_beacon_int(rdev, dev->ieee80211_ptr->iftype,
6140 params->beacon_interval);
6141 if (err)
6142 goto out;
6145 * In theory, some of these attributes should be required here
6146 * but since they were not used when the command was originally
6147 * added, keep them optional for old user space programs to let
6148 * them continue to work with drivers that do not need the
6149 * additional information -- drivers must check!
6151 if (info->attrs[NL80211_ATTR_SSID]) {
6152 params->ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
6153 params->ssid_len =
6154 nla_len(info->attrs[NL80211_ATTR_SSID]);
6155 if (params->ssid_len == 0) {
6156 err = -EINVAL;
6157 goto out;
6160 if (wdev->u.ap.ssid_len &&
6161 (wdev->u.ap.ssid_len != params->ssid_len ||
6162 memcmp(wdev->u.ap.ssid, params->ssid, params->ssid_len))) {
6163 /* require identical SSID for MLO */
6164 err = -EINVAL;
6165 goto out;
6167 } else if (wdev->valid_links) {
6168 /* require SSID for MLO */
6169 err = -EINVAL;
6170 goto out;
6173 if (info->attrs[NL80211_ATTR_HIDDEN_SSID])
6174 params->hidden_ssid = nla_get_u32(
6175 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
6177 params->privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
6179 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
6180 params->auth_type = nla_get_u32(
6181 info->attrs[NL80211_ATTR_AUTH_TYPE]);
6182 if (!nl80211_valid_auth_type(rdev, params->auth_type,
6183 NL80211_CMD_START_AP)) {
6184 err = -EINVAL;
6185 goto out;
6187 } else
6188 params->auth_type = NL80211_AUTHTYPE_AUTOMATIC;
6190 err = nl80211_crypto_settings(rdev, info, &params->crypto,
6191 NL80211_MAX_NR_CIPHER_SUITES);
6192 if (err)
6193 goto out;
6195 if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) {
6196 if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER)) {
6197 err = -EOPNOTSUPP;
6198 goto out;
6200 params->inactivity_timeout = nla_get_u16(
6201 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
6204 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
6205 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
6206 err = -EINVAL;
6207 goto out;
6209 params->p2p_ctwindow =
6210 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
6211 if (params->p2p_ctwindow != 0 &&
6212 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) {
6213 err = -EINVAL;
6214 goto out;
6218 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
6219 u8 tmp;
6221 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
6222 err = -EINVAL;
6223 goto out;
6225 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
6226 params->p2p_opp_ps = tmp;
6227 if (params->p2p_opp_ps != 0 &&
6228 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) {
6229 err = -EINVAL;
6230 goto out;
6234 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
6235 err = nl80211_parse_chandef(rdev, info, &params->chandef);
6236 if (err)
6237 goto out;
6238 } else if (wdev->valid_links) {
6239 /* with MLD need to specify the channel configuration */
6240 err = -EINVAL;
6241 goto out;
6242 } else if (wdev->u.ap.preset_chandef.chan) {
6243 params->chandef = wdev->u.ap.preset_chandef;
6244 } else if (!nl80211_get_ap_channel(rdev, params)) {
6245 err = -EINVAL;
6246 goto out;
6249 beacon_check.iftype = wdev->iftype;
6250 beacon_check.relax = true;
6251 beacon_check.reg_power =
6252 cfg80211_get_6ghz_power_type(params->beacon.tail,
6253 params->beacon.tail_len);
6254 if (!cfg80211_reg_check_beaconing(&rdev->wiphy, &params->chandef,
6255 &beacon_check)) {
6256 err = -EINVAL;
6257 goto out;
6260 if (info->attrs[NL80211_ATTR_TX_RATES]) {
6261 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
6262 NL80211_ATTR_TX_RATES,
6263 &params->beacon_rate,
6264 dev, false, link_id);
6265 if (err)
6266 goto out;
6268 err = validate_beacon_tx_rate(rdev, params->chandef.chan->band,
6269 &params->beacon_rate);
6270 if (err)
6271 goto out;
6274 params->pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
6275 if (params->pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
6276 err = -EOPNOTSUPP;
6277 goto out;
6280 if (info->attrs[NL80211_ATTR_ACL_POLICY]) {
6281 params->acl = parse_acl_data(&rdev->wiphy, info);
6282 if (IS_ERR(params->acl)) {
6283 err = PTR_ERR(params->acl);
6284 params->acl = NULL;
6285 goto out;
6289 params->twt_responder =
6290 nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
6292 if (info->attrs[NL80211_ATTR_HE_OBSS_PD]) {
6293 err = nl80211_parse_he_obss_pd(
6294 info->attrs[NL80211_ATTR_HE_OBSS_PD],
6295 &params->he_obss_pd);
6296 if (err)
6297 goto out;
6300 if (info->attrs[NL80211_ATTR_FILS_DISCOVERY]) {
6301 err = nl80211_parse_fils_discovery(rdev,
6302 info->attrs[NL80211_ATTR_FILS_DISCOVERY],
6303 &params->fils_discovery);
6304 if (err)
6305 goto out;
6308 if (info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP]) {
6309 err = nl80211_parse_unsol_bcast_probe_resp(
6310 rdev, info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP],
6311 &params->unsol_bcast_probe_resp);
6312 if (err)
6313 goto out;
6316 if (info->attrs[NL80211_ATTR_MBSSID_CONFIG]) {
6317 err = nl80211_parse_mbssid_config(&rdev->wiphy, dev,
6318 info->attrs[NL80211_ATTR_MBSSID_CONFIG],
6319 &params->mbssid_config,
6320 params->beacon.mbssid_ies ?
6321 params->beacon.mbssid_ies->cnt :
6323 if (err)
6324 goto out;
6327 if (!params->mbssid_config.ema && params->beacon.rnr_ies) {
6328 err = -EINVAL;
6329 goto out;
6332 err = nl80211_calculate_ap_params(params);
6333 if (err)
6334 goto out;
6336 err = nl80211_validate_ap_phy_operation(params);
6337 if (err)
6338 goto out;
6340 if (info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS])
6341 params->flags = nla_get_u32(
6342 info->attrs[NL80211_ATTR_AP_SETTINGS_FLAGS]);
6343 else if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
6344 params->flags |= NL80211_AP_SETTINGS_EXTERNAL_AUTH_SUPPORT;
6346 if (wdev->conn_owner_nlportid &&
6347 info->attrs[NL80211_ATTR_SOCKET_OWNER] &&
6348 wdev->conn_owner_nlportid != info->snd_portid) {
6349 err = -EINVAL;
6350 goto out;
6353 /* FIXME: validate MLO/link-id against driver capabilities */
6355 err = rdev_start_ap(rdev, dev, params);
6356 if (!err) {
6357 wdev->links[link_id].ap.beacon_interval = params->beacon_interval;
6358 wdev->links[link_id].ap.chandef = params->chandef;
6359 wdev->u.ap.ssid_len = params->ssid_len;
6360 memcpy(wdev->u.ap.ssid, params->ssid,
6361 params->ssid_len);
6363 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
6364 wdev->conn_owner_nlportid = info->snd_portid;
6366 nl80211_send_ap_started(wdev, link_id);
6368 out:
6369 kfree(params->acl);
6370 kfree(params->beacon.mbssid_ies);
6371 if (params->mbssid_config.tx_wdev &&
6372 params->mbssid_config.tx_wdev->netdev &&
6373 params->mbssid_config.tx_wdev->netdev != dev)
6374 dev_put(params->mbssid_config.tx_wdev->netdev);
6375 kfree(params->beacon.rnr_ies);
6376 kfree(params);
6378 return err;
6381 static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info)
6383 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6384 struct cfg80211_beaconing_check_config beacon_check = {};
6385 unsigned int link_id = nl80211_link_id(info->attrs);
6386 struct net_device *dev = info->user_ptr[1];
6387 struct wireless_dev *wdev = dev->ieee80211_ptr;
6388 struct cfg80211_ap_update *params;
6389 struct nlattr *attr;
6390 int err;
6392 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
6393 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
6394 return -EOPNOTSUPP;
6396 if (!rdev->ops->change_beacon)
6397 return -EOPNOTSUPP;
6399 if (!wdev->links[link_id].ap.beacon_interval)
6400 return -EINVAL;
6402 params = kzalloc(sizeof(*params), GFP_KERNEL);
6403 if (!params)
6404 return -ENOMEM;
6406 err = nl80211_parse_beacon(rdev, info->attrs, &params->beacon,
6407 info->extack);
6408 if (err)
6409 goto out;
6411 /* recheck beaconing is permitted with possibly changed power type */
6412 beacon_check.iftype = wdev->iftype;
6413 beacon_check.relax = true;
6414 beacon_check.reg_power =
6415 cfg80211_get_6ghz_power_type(params->beacon.tail,
6416 params->beacon.tail_len);
6417 if (!cfg80211_reg_check_beaconing(&rdev->wiphy,
6418 &wdev->links[link_id].ap.chandef,
6419 &beacon_check)) {
6420 err = -EINVAL;
6421 goto out;
6424 attr = info->attrs[NL80211_ATTR_FILS_DISCOVERY];
6425 if (attr) {
6426 err = nl80211_parse_fils_discovery(rdev, attr,
6427 &params->fils_discovery);
6428 if (err)
6429 goto out;
6432 attr = info->attrs[NL80211_ATTR_UNSOL_BCAST_PROBE_RESP];
6433 if (attr) {
6434 err = nl80211_parse_unsol_bcast_probe_resp(rdev, attr,
6435 &params->unsol_bcast_probe_resp);
6436 if (err)
6437 goto out;
6440 err = rdev_change_beacon(rdev, dev, params);
6442 out:
6443 kfree(params->beacon.mbssid_ies);
6444 kfree(params->beacon.rnr_ies);
6445 kfree(params);
6446 return err;
6449 static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info)
6451 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6452 unsigned int link_id = nl80211_link_id(info->attrs);
6453 struct net_device *dev = info->user_ptr[1];
6455 return cfg80211_stop_ap(rdev, dev, link_id, false);
6458 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
6459 [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
6460 [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
6461 [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
6462 [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
6463 [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG },
6464 [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG },
6467 static int parse_station_flags(struct genl_info *info,
6468 enum nl80211_iftype iftype,
6469 struct station_parameters *params)
6471 struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
6472 struct nlattr *nla;
6473 int flag;
6476 * Try parsing the new attribute first so userspace
6477 * can specify both for older kernels.
6479 nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
6480 if (nla) {
6481 struct nl80211_sta_flag_update *sta_flags;
6483 sta_flags = nla_data(nla);
6484 params->sta_flags_mask = sta_flags->mask;
6485 params->sta_flags_set = sta_flags->set;
6486 params->sta_flags_set &= params->sta_flags_mask;
6487 if ((params->sta_flags_mask |
6488 params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
6489 return -EINVAL;
6490 return 0;
6493 /* if present, parse the old attribute */
6495 nla = info->attrs[NL80211_ATTR_STA_FLAGS];
6496 if (!nla)
6497 return 0;
6499 if (nla_parse_nested_deprecated(flags, NL80211_STA_FLAG_MAX, nla, sta_flags_policy, info->extack))
6500 return -EINVAL;
6503 * Only allow certain flags for interface types so that
6504 * other attributes are silently ignored. Remember that
6505 * this is backward compatibility code with old userspace
6506 * and shouldn't be hit in other cases anyway.
6508 switch (iftype) {
6509 case NL80211_IFTYPE_AP:
6510 case NL80211_IFTYPE_AP_VLAN:
6511 case NL80211_IFTYPE_P2P_GO:
6512 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
6513 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
6514 BIT(NL80211_STA_FLAG_WME) |
6515 BIT(NL80211_STA_FLAG_MFP);
6516 break;
6517 case NL80211_IFTYPE_P2P_CLIENT:
6518 case NL80211_IFTYPE_STATION:
6519 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) |
6520 BIT(NL80211_STA_FLAG_TDLS_PEER);
6521 break;
6522 case NL80211_IFTYPE_MESH_POINT:
6523 params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
6524 BIT(NL80211_STA_FLAG_MFP) |
6525 BIT(NL80211_STA_FLAG_AUTHORIZED);
6526 break;
6527 default:
6528 return -EINVAL;
6531 for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) {
6532 if (flags[flag]) {
6533 params->sta_flags_set |= (1<<flag);
6535 /* no longer support new API additions in old API */
6536 if (flag > NL80211_STA_FLAG_MAX_OLD_API)
6537 return -EINVAL;
6541 return 0;
6544 bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr)
6546 struct nlattr *rate;
6547 u32 bitrate;
6548 u16 bitrate_compat;
6549 enum nl80211_rate_info rate_flg;
6551 rate = nla_nest_start_noflag(msg, attr);
6552 if (!rate)
6553 return false;
6555 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
6556 bitrate = cfg80211_calculate_bitrate(info);
6557 /* report 16-bit bitrate only if we can */
6558 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
6559 if (bitrate > 0 &&
6560 nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate))
6561 return false;
6562 if (bitrate_compat > 0 &&
6563 nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat))
6564 return false;
6566 switch (info->bw) {
6567 case RATE_INFO_BW_1:
6568 rate_flg = NL80211_RATE_INFO_1_MHZ_WIDTH;
6569 break;
6570 case RATE_INFO_BW_2:
6571 rate_flg = NL80211_RATE_INFO_2_MHZ_WIDTH;
6572 break;
6573 case RATE_INFO_BW_4:
6574 rate_flg = NL80211_RATE_INFO_4_MHZ_WIDTH;
6575 break;
6576 case RATE_INFO_BW_5:
6577 rate_flg = NL80211_RATE_INFO_5_MHZ_WIDTH;
6578 break;
6579 case RATE_INFO_BW_8:
6580 rate_flg = NL80211_RATE_INFO_8_MHZ_WIDTH;
6581 break;
6582 case RATE_INFO_BW_10:
6583 rate_flg = NL80211_RATE_INFO_10_MHZ_WIDTH;
6584 break;
6585 case RATE_INFO_BW_16:
6586 rate_flg = NL80211_RATE_INFO_16_MHZ_WIDTH;
6587 break;
6588 default:
6589 WARN_ON(1);
6590 fallthrough;
6591 case RATE_INFO_BW_20:
6592 rate_flg = 0;
6593 break;
6594 case RATE_INFO_BW_40:
6595 rate_flg = NL80211_RATE_INFO_40_MHZ_WIDTH;
6596 break;
6597 case RATE_INFO_BW_80:
6598 rate_flg = NL80211_RATE_INFO_80_MHZ_WIDTH;
6599 break;
6600 case RATE_INFO_BW_160:
6601 rate_flg = NL80211_RATE_INFO_160_MHZ_WIDTH;
6602 break;
6603 case RATE_INFO_BW_HE_RU:
6604 rate_flg = 0;
6605 WARN_ON(!(info->flags & RATE_INFO_FLAGS_HE_MCS));
6606 break;
6607 case RATE_INFO_BW_320:
6608 rate_flg = NL80211_RATE_INFO_320_MHZ_WIDTH;
6609 break;
6610 case RATE_INFO_BW_EHT_RU:
6611 rate_flg = 0;
6612 WARN_ON(!(info->flags & RATE_INFO_FLAGS_EHT_MCS));
6613 break;
6616 if (rate_flg && nla_put_flag(msg, rate_flg))
6617 return false;
6619 if (info->flags & RATE_INFO_FLAGS_MCS) {
6620 if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs))
6621 return false;
6622 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
6623 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
6624 return false;
6625 } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) {
6626 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs))
6627 return false;
6628 if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss))
6629 return false;
6630 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
6631 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
6632 return false;
6633 } else if (info->flags & RATE_INFO_FLAGS_HE_MCS) {
6634 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_MCS, info->mcs))
6635 return false;
6636 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_NSS, info->nss))
6637 return false;
6638 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_GI, info->he_gi))
6639 return false;
6640 if (nla_put_u8(msg, NL80211_RATE_INFO_HE_DCM, info->he_dcm))
6641 return false;
6642 if (info->bw == RATE_INFO_BW_HE_RU &&
6643 nla_put_u8(msg, NL80211_RATE_INFO_HE_RU_ALLOC,
6644 info->he_ru_alloc))
6645 return false;
6646 } else if (info->flags & RATE_INFO_FLAGS_S1G_MCS) {
6647 if (nla_put_u8(msg, NL80211_RATE_INFO_S1G_MCS, info->mcs))
6648 return false;
6649 if (nla_put_u8(msg, NL80211_RATE_INFO_S1G_NSS, info->nss))
6650 return false;
6651 if (info->flags & RATE_INFO_FLAGS_SHORT_GI &&
6652 nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI))
6653 return false;
6654 } else if (info->flags & RATE_INFO_FLAGS_EHT_MCS) {
6655 if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_MCS, info->mcs))
6656 return false;
6657 if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_NSS, info->nss))
6658 return false;
6659 if (nla_put_u8(msg, NL80211_RATE_INFO_EHT_GI, info->eht_gi))
6660 return false;
6661 if (info->bw == RATE_INFO_BW_EHT_RU &&
6662 nla_put_u8(msg, NL80211_RATE_INFO_EHT_RU_ALLOC,
6663 info->eht_ru_alloc))
6664 return false;
6667 nla_nest_end(msg, rate);
6668 return true;
6671 static bool nl80211_put_signal(struct sk_buff *msg, u8 mask, s8 *signal,
6672 int id)
6674 void *attr;
6675 int i = 0;
6677 if (!mask)
6678 return true;
6680 attr = nla_nest_start_noflag(msg, id);
6681 if (!attr)
6682 return false;
6684 for (i = 0; i < IEEE80211_MAX_CHAINS; i++) {
6685 if (!(mask & BIT(i)))
6686 continue;
6688 if (nla_put_u8(msg, i, signal[i]))
6689 return false;
6692 nla_nest_end(msg, attr);
6694 return true;
6697 static int nl80211_send_station(struct sk_buff *msg, u32 cmd, u32 portid,
6698 u32 seq, int flags,
6699 struct cfg80211_registered_device *rdev,
6700 struct net_device *dev,
6701 const u8 *mac_addr, struct station_info *sinfo)
6703 void *hdr;
6704 struct nlattr *sinfoattr, *bss_param;
6706 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
6707 if (!hdr) {
6708 cfg80211_sinfo_release_content(sinfo);
6709 return -1;
6712 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
6713 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
6714 nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation))
6715 goto nla_put_failure;
6717 sinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_STA_INFO);
6718 if (!sinfoattr)
6719 goto nla_put_failure;
6721 #define PUT_SINFO(attr, memb, type) do { \
6722 BUILD_BUG_ON(sizeof(type) == sizeof(u64)); \
6723 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
6724 nla_put_ ## type(msg, NL80211_STA_INFO_ ## attr, \
6725 sinfo->memb)) \
6726 goto nla_put_failure; \
6727 } while (0)
6728 #define PUT_SINFO_U64(attr, memb) do { \
6729 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_ ## attr) && \
6730 nla_put_u64_64bit(msg, NL80211_STA_INFO_ ## attr, \
6731 sinfo->memb, NL80211_STA_INFO_PAD)) \
6732 goto nla_put_failure; \
6733 } while (0)
6735 PUT_SINFO(CONNECTED_TIME, connected_time, u32);
6736 PUT_SINFO(INACTIVE_TIME, inactive_time, u32);
6737 PUT_SINFO_U64(ASSOC_AT_BOOTTIME, assoc_at);
6739 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_RX_BYTES) |
6740 BIT_ULL(NL80211_STA_INFO_RX_BYTES64)) &&
6741 nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES,
6742 (u32)sinfo->rx_bytes))
6743 goto nla_put_failure;
6745 if (sinfo->filled & (BIT_ULL(NL80211_STA_INFO_TX_BYTES) |
6746 BIT_ULL(NL80211_STA_INFO_TX_BYTES64)) &&
6747 nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES,
6748 (u32)sinfo->tx_bytes))
6749 goto nla_put_failure;
6751 PUT_SINFO_U64(RX_BYTES64, rx_bytes);
6752 PUT_SINFO_U64(TX_BYTES64, tx_bytes);
6753 PUT_SINFO(LLID, llid, u16);
6754 PUT_SINFO(PLID, plid, u16);
6755 PUT_SINFO(PLINK_STATE, plink_state, u8);
6756 PUT_SINFO_U64(RX_DURATION, rx_duration);
6757 PUT_SINFO_U64(TX_DURATION, tx_duration);
6759 if (wiphy_ext_feature_isset(&rdev->wiphy,
6760 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
6761 PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16);
6763 switch (rdev->wiphy.signal_type) {
6764 case CFG80211_SIGNAL_TYPE_MBM:
6765 PUT_SINFO(SIGNAL, signal, u8);
6766 PUT_SINFO(SIGNAL_AVG, signal_avg, u8);
6767 break;
6768 default:
6769 break;
6771 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL)) {
6772 if (!nl80211_put_signal(msg, sinfo->chains,
6773 sinfo->chain_signal,
6774 NL80211_STA_INFO_CHAIN_SIGNAL))
6775 goto nla_put_failure;
6777 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG)) {
6778 if (!nl80211_put_signal(msg, sinfo->chains,
6779 sinfo->chain_signal_avg,
6780 NL80211_STA_INFO_CHAIN_SIGNAL_AVG))
6781 goto nla_put_failure;
6783 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_BITRATE)) {
6784 if (!nl80211_put_sta_rate(msg, &sinfo->txrate,
6785 NL80211_STA_INFO_TX_BITRATE))
6786 goto nla_put_failure;
6788 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) {
6789 if (!nl80211_put_sta_rate(msg, &sinfo->rxrate,
6790 NL80211_STA_INFO_RX_BITRATE))
6791 goto nla_put_failure;
6794 PUT_SINFO(RX_PACKETS, rx_packets, u32);
6795 PUT_SINFO(TX_PACKETS, tx_packets, u32);
6796 PUT_SINFO(TX_RETRIES, tx_retries, u32);
6797 PUT_SINFO(TX_FAILED, tx_failed, u32);
6798 PUT_SINFO(EXPECTED_THROUGHPUT, expected_throughput, u32);
6799 PUT_SINFO(AIRTIME_LINK_METRIC, airtime_link_metric, u32);
6800 PUT_SINFO(BEACON_LOSS, beacon_loss_count, u32);
6801 PUT_SINFO(LOCAL_PM, local_pm, u32);
6802 PUT_SINFO(PEER_PM, peer_pm, u32);
6803 PUT_SINFO(NONPEER_PM, nonpeer_pm, u32);
6804 PUT_SINFO(CONNECTED_TO_GATE, connected_to_gate, u8);
6805 PUT_SINFO(CONNECTED_TO_AS, connected_to_as, u8);
6807 if (sinfo->filled & BIT_ULL(NL80211_STA_INFO_BSS_PARAM)) {
6808 bss_param = nla_nest_start_noflag(msg,
6809 NL80211_STA_INFO_BSS_PARAM);
6810 if (!bss_param)
6811 goto nla_put_failure;
6813 if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) &&
6814 nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) ||
6815 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) &&
6816 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) ||
6817 ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) &&
6818 nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) ||
6819 nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD,
6820 sinfo->bss_param.dtim_period) ||
6821 nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL,
6822 sinfo->bss_param.beacon_interval))
6823 goto nla_put_failure;
6825 nla_nest_end(msg, bss_param);
6827 if ((sinfo->filled & BIT_ULL(NL80211_STA_INFO_STA_FLAGS)) &&
6828 nla_put(msg, NL80211_STA_INFO_STA_FLAGS,
6829 sizeof(struct nl80211_sta_flag_update),
6830 &sinfo->sta_flags))
6831 goto nla_put_failure;
6833 PUT_SINFO_U64(T_OFFSET, t_offset);
6834 PUT_SINFO_U64(RX_DROP_MISC, rx_dropped_misc);
6835 PUT_SINFO_U64(BEACON_RX, rx_beacon);
6836 PUT_SINFO(BEACON_SIGNAL_AVG, rx_beacon_signal_avg, u8);
6837 PUT_SINFO(RX_MPDUS, rx_mpdu_count, u32);
6838 PUT_SINFO(FCS_ERROR_COUNT, fcs_err_count, u32);
6839 if (wiphy_ext_feature_isset(&rdev->wiphy,
6840 NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT)) {
6841 PUT_SINFO(ACK_SIGNAL, ack_signal, u8);
6842 PUT_SINFO(ACK_SIGNAL_AVG, avg_ack_signal, s8);
6845 #undef PUT_SINFO
6846 #undef PUT_SINFO_U64
6848 if (sinfo->pertid) {
6849 struct nlattr *tidsattr;
6850 int tid;
6852 tidsattr = nla_nest_start_noflag(msg,
6853 NL80211_STA_INFO_TID_STATS);
6854 if (!tidsattr)
6855 goto nla_put_failure;
6857 for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) {
6858 struct cfg80211_tid_stats *tidstats;
6859 struct nlattr *tidattr;
6861 tidstats = &sinfo->pertid[tid];
6863 if (!tidstats->filled)
6864 continue;
6866 tidattr = nla_nest_start_noflag(msg, tid + 1);
6867 if (!tidattr)
6868 goto nla_put_failure;
6870 #define PUT_TIDVAL_U64(attr, memb) do { \
6871 if (tidstats->filled & BIT(NL80211_TID_STATS_ ## attr) && \
6872 nla_put_u64_64bit(msg, NL80211_TID_STATS_ ## attr, \
6873 tidstats->memb, NL80211_TID_STATS_PAD)) \
6874 goto nla_put_failure; \
6875 } while (0)
6877 PUT_TIDVAL_U64(RX_MSDU, rx_msdu);
6878 PUT_TIDVAL_U64(TX_MSDU, tx_msdu);
6879 PUT_TIDVAL_U64(TX_MSDU_RETRIES, tx_msdu_retries);
6880 PUT_TIDVAL_U64(TX_MSDU_FAILED, tx_msdu_failed);
6882 #undef PUT_TIDVAL_U64
6883 if ((tidstats->filled &
6884 BIT(NL80211_TID_STATS_TXQ_STATS)) &&
6885 !nl80211_put_txq_stats(msg, &tidstats->txq_stats,
6886 NL80211_TID_STATS_TXQ_STATS))
6887 goto nla_put_failure;
6889 nla_nest_end(msg, tidattr);
6892 nla_nest_end(msg, tidsattr);
6895 nla_nest_end(msg, sinfoattr);
6897 if (sinfo->assoc_req_ies_len &&
6898 nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
6899 sinfo->assoc_req_ies))
6900 goto nla_put_failure;
6902 if (sinfo->assoc_resp_ies_len &&
6903 nla_put(msg, NL80211_ATTR_RESP_IE, sinfo->assoc_resp_ies_len,
6904 sinfo->assoc_resp_ies))
6905 goto nla_put_failure;
6907 if (sinfo->mlo_params_valid) {
6908 if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID,
6909 sinfo->assoc_link_id))
6910 goto nla_put_failure;
6912 if (!is_zero_ether_addr(sinfo->mld_addr) &&
6913 nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN,
6914 sinfo->mld_addr))
6915 goto nla_put_failure;
6918 cfg80211_sinfo_release_content(sinfo);
6919 genlmsg_end(msg, hdr);
6920 return 0;
6922 nla_put_failure:
6923 cfg80211_sinfo_release_content(sinfo);
6924 genlmsg_cancel(msg, hdr);
6925 return -EMSGSIZE;
6928 static int nl80211_dump_station(struct sk_buff *skb,
6929 struct netlink_callback *cb)
6931 struct station_info sinfo;
6932 struct cfg80211_registered_device *rdev;
6933 struct wireless_dev *wdev;
6934 u8 mac_addr[ETH_ALEN];
6935 int sta_idx = cb->args[2];
6936 int err;
6938 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
6939 if (err)
6940 return err;
6941 /* nl80211_prepare_wdev_dump acquired it in the successful case */
6942 __acquire(&rdev->wiphy.mtx);
6944 if (!wdev->netdev) {
6945 err = -EINVAL;
6946 goto out_err;
6949 if (!rdev->ops->dump_station) {
6950 err = -EOPNOTSUPP;
6951 goto out_err;
6954 while (1) {
6955 memset(&sinfo, 0, sizeof(sinfo));
6956 err = rdev_dump_station(rdev, wdev->netdev, sta_idx,
6957 mac_addr, &sinfo);
6958 if (err == -ENOENT)
6959 break;
6960 if (err)
6961 goto out_err;
6963 if (nl80211_send_station(skb, NL80211_CMD_NEW_STATION,
6964 NETLINK_CB(cb->skb).portid,
6965 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6966 rdev, wdev->netdev, mac_addr,
6967 &sinfo) < 0)
6968 goto out;
6970 sta_idx++;
6973 out:
6974 cb->args[2] = sta_idx;
6975 err = skb->len;
6976 out_err:
6977 wiphy_unlock(&rdev->wiphy);
6979 return err;
6982 static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
6984 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6985 struct net_device *dev = info->user_ptr[1];
6986 struct station_info sinfo;
6987 struct sk_buff *msg;
6988 u8 *mac_addr = NULL;
6989 int err;
6991 memset(&sinfo, 0, sizeof(sinfo));
6993 if (!info->attrs[NL80211_ATTR_MAC])
6994 return -EINVAL;
6996 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
6998 if (!rdev->ops->get_station)
6999 return -EOPNOTSUPP;
7001 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
7002 if (err)
7003 return err;
7005 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7006 if (!msg) {
7007 cfg80211_sinfo_release_content(&sinfo);
7008 return -ENOMEM;
7011 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION,
7012 info->snd_portid, info->snd_seq, 0,
7013 rdev, dev, mac_addr, &sinfo) < 0) {
7014 nlmsg_free(msg);
7015 return -ENOBUFS;
7018 return genlmsg_reply(msg, info);
7021 int cfg80211_check_station_change(struct wiphy *wiphy,
7022 struct station_parameters *params,
7023 enum cfg80211_station_type statype)
7025 if (params->listen_interval != -1 &&
7026 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
7027 return -EINVAL;
7029 if (params->support_p2p_ps != -1 &&
7030 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
7031 return -EINVAL;
7033 if (params->aid &&
7034 !(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
7035 statype != CFG80211_STA_AP_CLIENT_UNASSOC)
7036 return -EINVAL;
7038 /* When you run into this, adjust the code below for the new flag */
7039 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 8);
7041 switch (statype) {
7042 case CFG80211_STA_MESH_PEER_KERNEL:
7043 case CFG80211_STA_MESH_PEER_USER:
7045 * No ignoring the TDLS flag here -- the userspace mesh
7046 * code doesn't have the bug of including TDLS in the
7047 * mask everywhere.
7049 if (params->sta_flags_mask &
7050 ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) |
7051 BIT(NL80211_STA_FLAG_MFP) |
7052 BIT(NL80211_STA_FLAG_AUTHORIZED)))
7053 return -EINVAL;
7054 break;
7055 case CFG80211_STA_TDLS_PEER_SETUP:
7056 case CFG80211_STA_TDLS_PEER_ACTIVE:
7057 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
7058 return -EINVAL;
7059 /* ignore since it can't change */
7060 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
7061 break;
7062 default:
7063 /* disallow mesh-specific things */
7064 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
7065 return -EINVAL;
7066 if (params->local_pm)
7067 return -EINVAL;
7068 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
7069 return -EINVAL;
7072 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
7073 statype != CFG80211_STA_TDLS_PEER_ACTIVE) {
7074 /* TDLS can't be set, ... */
7075 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
7076 return -EINVAL;
7078 * ... but don't bother the driver with it. This works around
7079 * a hostapd/wpa_supplicant issue -- it always includes the
7080 * TLDS_PEER flag in the mask even for AP mode.
7082 params->sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
7085 if (statype != CFG80211_STA_TDLS_PEER_SETUP &&
7086 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
7087 /* reject other things that can't change */
7088 if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
7089 return -EINVAL;
7090 if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
7091 return -EINVAL;
7092 if (params->link_sta_params.supported_rates)
7093 return -EINVAL;
7094 if (params->ext_capab || params->link_sta_params.ht_capa ||
7095 params->link_sta_params.vht_capa ||
7096 params->link_sta_params.he_capa ||
7097 params->link_sta_params.eht_capa)
7098 return -EINVAL;
7099 if (params->sta_flags_mask & BIT(NL80211_STA_FLAG_SPP_AMSDU))
7100 return -EINVAL;
7103 if (statype != CFG80211_STA_AP_CLIENT &&
7104 statype != CFG80211_STA_AP_CLIENT_UNASSOC) {
7105 if (params->vlan)
7106 return -EINVAL;
7109 switch (statype) {
7110 case CFG80211_STA_AP_MLME_CLIENT:
7111 /* Use this only for authorizing/unauthorizing a station */
7112 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
7113 return -EOPNOTSUPP;
7114 break;
7115 case CFG80211_STA_AP_CLIENT:
7116 case CFG80211_STA_AP_CLIENT_UNASSOC:
7117 /* accept only the listed bits */
7118 if (params->sta_flags_mask &
7119 ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
7120 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
7121 BIT(NL80211_STA_FLAG_ASSOCIATED) |
7122 BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) |
7123 BIT(NL80211_STA_FLAG_WME) |
7124 BIT(NL80211_STA_FLAG_MFP) |
7125 BIT(NL80211_STA_FLAG_SPP_AMSDU)))
7126 return -EINVAL;
7128 /* but authenticated/associated only if driver handles it */
7129 if (!(wiphy->features & NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
7130 params->sta_flags_mask &
7131 (BIT(NL80211_STA_FLAG_AUTHENTICATED) |
7132 BIT(NL80211_STA_FLAG_ASSOCIATED)))
7133 return -EINVAL;
7134 break;
7135 case CFG80211_STA_IBSS:
7136 case CFG80211_STA_AP_STA:
7137 /* reject any changes other than AUTHORIZED */
7138 if (params->sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED))
7139 return -EINVAL;
7140 break;
7141 case CFG80211_STA_TDLS_PEER_SETUP:
7142 /* reject any changes other than AUTHORIZED or WME */
7143 if (params->sta_flags_mask & ~(BIT(NL80211_STA_FLAG_AUTHORIZED) |
7144 BIT(NL80211_STA_FLAG_WME)))
7145 return -EINVAL;
7146 /* force (at least) rates when authorizing */
7147 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) &&
7148 !params->link_sta_params.supported_rates)
7149 return -EINVAL;
7150 break;
7151 case CFG80211_STA_TDLS_PEER_ACTIVE:
7152 /* reject any changes */
7153 return -EINVAL;
7154 case CFG80211_STA_MESH_PEER_KERNEL:
7155 if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
7156 return -EINVAL;
7157 break;
7158 case CFG80211_STA_MESH_PEER_USER:
7159 if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION &&
7160 params->plink_action != NL80211_PLINK_ACTION_BLOCK)
7161 return -EINVAL;
7162 break;
7166 * Older kernel versions ignored this attribute entirely, so don't
7167 * reject attempts to update it but mark it as unused instead so the
7168 * driver won't look at the data.
7170 if (statype != CFG80211_STA_AP_CLIENT_UNASSOC &&
7171 statype != CFG80211_STA_TDLS_PEER_SETUP)
7172 params->link_sta_params.opmode_notif_used = false;
7174 return 0;
7176 EXPORT_SYMBOL(cfg80211_check_station_change);
7179 * Get vlan interface making sure it is running and on the right wiphy.
7181 static struct net_device *get_vlan(struct genl_info *info,
7182 struct cfg80211_registered_device *rdev)
7184 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
7185 struct net_device *v;
7186 int ret;
7188 if (!vlanattr)
7189 return NULL;
7191 v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr));
7192 if (!v)
7193 return ERR_PTR(-ENODEV);
7195 if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) {
7196 ret = -EINVAL;
7197 goto error;
7200 if (v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN &&
7201 v->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
7202 v->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) {
7203 ret = -EINVAL;
7204 goto error;
7207 if (!netif_running(v)) {
7208 ret = -ENETDOWN;
7209 goto error;
7212 return v;
7213 error:
7214 dev_put(v);
7215 return ERR_PTR(ret);
7218 static int nl80211_parse_sta_wme(struct genl_info *info,
7219 struct station_parameters *params)
7221 struct nlattr *tb[NL80211_STA_WME_MAX + 1];
7222 struct nlattr *nla;
7223 int err;
7225 /* parse WME attributes if present */
7226 if (!info->attrs[NL80211_ATTR_STA_WME])
7227 return 0;
7229 nla = info->attrs[NL80211_ATTR_STA_WME];
7230 err = nla_parse_nested_deprecated(tb, NL80211_STA_WME_MAX, nla,
7231 nl80211_sta_wme_policy,
7232 info->extack);
7233 if (err)
7234 return err;
7236 if (tb[NL80211_STA_WME_UAPSD_QUEUES])
7237 params->uapsd_queues = nla_get_u8(
7238 tb[NL80211_STA_WME_UAPSD_QUEUES]);
7239 if (params->uapsd_queues & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
7240 return -EINVAL;
7242 if (tb[NL80211_STA_WME_MAX_SP])
7243 params->max_sp = nla_get_u8(tb[NL80211_STA_WME_MAX_SP]);
7245 if (params->max_sp & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
7246 return -EINVAL;
7248 params->sta_modify_mask |= STATION_PARAM_APPLY_UAPSD;
7250 return 0;
7253 static int nl80211_parse_sta_channel_info(struct genl_info *info,
7254 struct station_parameters *params)
7256 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]) {
7257 params->supported_channels =
7258 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
7259 params->supported_channels_len =
7260 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_CHANNELS]);
7262 * Need to include at least one (first channel, number of
7263 * channels) tuple for each subband (checked in policy),
7264 * and must have proper tuples for the rest of the data as well.
7266 if (params->supported_channels_len % 2)
7267 return -EINVAL;
7270 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]) {
7271 params->supported_oper_classes =
7272 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
7273 params->supported_oper_classes_len =
7274 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES]);
7276 return 0;
7279 static int nl80211_set_station_tdls(struct genl_info *info,
7280 struct station_parameters *params)
7282 int err;
7283 /* Dummy STA entry gets updated once the peer capabilities are known */
7284 if (info->attrs[NL80211_ATTR_PEER_AID])
7285 params->aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
7286 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
7287 params->link_sta_params.ht_capa =
7288 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
7289 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
7290 params->link_sta_params.vht_capa =
7291 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
7292 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
7293 params->link_sta_params.he_capa =
7294 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
7295 params->link_sta_params.he_capa_len =
7296 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
7298 if (info->attrs[NL80211_ATTR_EHT_CAPABILITY]) {
7299 params->link_sta_params.eht_capa =
7300 nla_data(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
7301 params->link_sta_params.eht_capa_len =
7302 nla_len(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
7304 if (!ieee80211_eht_capa_size_ok((const u8 *)params->link_sta_params.he_capa,
7305 (const u8 *)params->link_sta_params.eht_capa,
7306 params->link_sta_params.eht_capa_len,
7307 false))
7308 return -EINVAL;
7312 err = nl80211_parse_sta_channel_info(info, params);
7313 if (err)
7314 return err;
7316 return nl80211_parse_sta_wme(info, params);
7319 static int nl80211_parse_sta_txpower_setting(struct genl_info *info,
7320 struct sta_txpwr *txpwr,
7321 bool *txpwr_set)
7323 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7324 int idx;
7326 if (info->attrs[NL80211_ATTR_STA_TX_POWER_SETTING]) {
7327 if (!rdev->ops->set_tx_power ||
7328 !wiphy_ext_feature_isset(&rdev->wiphy,
7329 NL80211_EXT_FEATURE_STA_TX_PWR))
7330 return -EOPNOTSUPP;
7332 idx = NL80211_ATTR_STA_TX_POWER_SETTING;
7333 txpwr->type = nla_get_u8(info->attrs[idx]);
7335 if (txpwr->type == NL80211_TX_POWER_LIMITED) {
7336 idx = NL80211_ATTR_STA_TX_POWER;
7338 if (info->attrs[idx])
7339 txpwr->power = nla_get_s16(info->attrs[idx]);
7340 else
7341 return -EINVAL;
7344 *txpwr_set = true;
7345 } else {
7346 *txpwr_set = false;
7349 return 0;
7352 static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
7354 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7355 struct net_device *dev = info->user_ptr[1];
7356 struct station_parameters params;
7357 u8 *mac_addr;
7358 int err;
7360 memset(&params, 0, sizeof(params));
7362 if (!rdev->ops->change_station)
7363 return -EOPNOTSUPP;
7366 * AID and listen_interval properties can be set only for unassociated
7367 * station. Include these parameters here and will check them in
7368 * cfg80211_check_station_change().
7370 if (info->attrs[NL80211_ATTR_STA_AID])
7371 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
7373 if (info->attrs[NL80211_ATTR_VLAN_ID])
7374 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
7376 if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
7377 params.listen_interval =
7378 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
7379 else
7380 params.listen_interval = -1;
7382 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS])
7383 params.support_p2p_ps =
7384 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
7385 else
7386 params.support_p2p_ps = -1;
7388 if (!info->attrs[NL80211_ATTR_MAC])
7389 return -EINVAL;
7391 params.link_sta_params.link_id =
7392 nl80211_link_id_or_invalid(info->attrs);
7394 if (info->attrs[NL80211_ATTR_MLD_ADDR]) {
7395 /* If MLD_ADDR attribute is set then this is an MLD station
7396 * and the MLD_ADDR attribute holds the MLD address and the
7397 * MAC attribute holds for the LINK address.
7398 * In that case, the link_id is also expected to be valid.
7400 if (params.link_sta_params.link_id < 0)
7401 return -EINVAL;
7403 mac_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
7404 params.link_sta_params.mld_mac = mac_addr;
7405 params.link_sta_params.link_mac =
7406 nla_data(info->attrs[NL80211_ATTR_MAC]);
7407 if (!is_valid_ether_addr(params.link_sta_params.link_mac))
7408 return -EINVAL;
7409 } else {
7410 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
7414 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
7415 params.link_sta_params.supported_rates =
7416 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
7417 params.link_sta_params.supported_rates_len =
7418 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
7421 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
7422 params.capability =
7423 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
7424 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
7427 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
7428 params.ext_capab =
7429 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
7430 params.ext_capab_len =
7431 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
7434 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
7435 return -EINVAL;
7437 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
7438 params.plink_action =
7439 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
7441 if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) {
7442 params.plink_state =
7443 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]);
7444 if (info->attrs[NL80211_ATTR_MESH_PEER_AID])
7445 params.peer_aid = nla_get_u16(
7446 info->attrs[NL80211_ATTR_MESH_PEER_AID]);
7447 params.sta_modify_mask |= STATION_PARAM_APPLY_PLINK_STATE;
7450 if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE])
7451 params.local_pm = nla_get_u32(
7452 info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]);
7454 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
7455 params.link_sta_params.opmode_notif_used = true;
7456 params.link_sta_params.opmode_notif =
7457 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
7460 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
7461 params.link_sta_params.he_6ghz_capa =
7462 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
7464 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
7465 params.airtime_weight =
7466 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
7468 if (params.airtime_weight &&
7469 !wiphy_ext_feature_isset(&rdev->wiphy,
7470 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
7471 return -EOPNOTSUPP;
7473 err = nl80211_parse_sta_txpower_setting(info,
7474 &params.link_sta_params.txpwr,
7475 &params.link_sta_params.txpwr_set);
7476 if (err)
7477 return err;
7479 /* Include parameters for TDLS peer (will check later) */
7480 err = nl80211_set_station_tdls(info, &params);
7481 if (err)
7482 return err;
7484 params.vlan = get_vlan(info, rdev);
7485 if (IS_ERR(params.vlan))
7486 return PTR_ERR(params.vlan);
7488 switch (dev->ieee80211_ptr->iftype) {
7489 case NL80211_IFTYPE_AP:
7490 case NL80211_IFTYPE_AP_VLAN:
7491 case NL80211_IFTYPE_P2P_GO:
7492 case NL80211_IFTYPE_P2P_CLIENT:
7493 case NL80211_IFTYPE_STATION:
7494 case NL80211_IFTYPE_ADHOC:
7495 case NL80211_IFTYPE_MESH_POINT:
7496 break;
7497 default:
7498 err = -EOPNOTSUPP;
7499 goto out_put_vlan;
7502 /* driver will call cfg80211_check_station_change() */
7503 err = rdev_change_station(rdev, dev, mac_addr, &params);
7505 out_put_vlan:
7506 dev_put(params.vlan);
7508 return err;
7511 static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
7513 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7514 int err;
7515 struct net_device *dev = info->user_ptr[1];
7516 struct wireless_dev *wdev = dev->ieee80211_ptr;
7517 struct station_parameters params;
7518 u8 *mac_addr = NULL;
7519 u32 auth_assoc = BIT(NL80211_STA_FLAG_AUTHENTICATED) |
7520 BIT(NL80211_STA_FLAG_ASSOCIATED);
7522 memset(&params, 0, sizeof(params));
7524 if (!rdev->ops->add_station)
7525 return -EOPNOTSUPP;
7527 if (!info->attrs[NL80211_ATTR_MAC])
7528 return -EINVAL;
7530 if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL])
7531 return -EINVAL;
7533 if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
7534 return -EINVAL;
7536 if (!info->attrs[NL80211_ATTR_STA_AID] &&
7537 !info->attrs[NL80211_ATTR_PEER_AID])
7538 return -EINVAL;
7540 params.link_sta_params.link_id =
7541 nl80211_link_id_or_invalid(info->attrs);
7543 if (info->attrs[NL80211_ATTR_MLD_ADDR]) {
7544 mac_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
7545 params.link_sta_params.mld_mac = mac_addr;
7546 params.link_sta_params.link_mac =
7547 nla_data(info->attrs[NL80211_ATTR_MAC]);
7548 if (!is_valid_ether_addr(params.link_sta_params.link_mac))
7549 return -EINVAL;
7550 } else {
7551 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
7554 params.link_sta_params.supported_rates =
7555 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
7556 params.link_sta_params.supported_rates_len =
7557 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
7558 params.listen_interval =
7559 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
7561 if (info->attrs[NL80211_ATTR_VLAN_ID])
7562 params.vlan_id = nla_get_u16(info->attrs[NL80211_ATTR_VLAN_ID]);
7564 if (info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]) {
7565 params.support_p2p_ps =
7566 nla_get_u8(info->attrs[NL80211_ATTR_STA_SUPPORT_P2P_PS]);
7567 } else {
7569 * if not specified, assume it's supported for P2P GO interface,
7570 * and is NOT supported for AP interface
7572 params.support_p2p_ps =
7573 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO;
7576 if (info->attrs[NL80211_ATTR_PEER_AID])
7577 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
7578 else
7579 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
7581 if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) {
7582 params.capability =
7583 nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]);
7584 params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY;
7587 if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) {
7588 params.ext_capab =
7589 nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
7590 params.ext_capab_len =
7591 nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]);
7594 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
7595 params.link_sta_params.ht_capa =
7596 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
7598 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
7599 params.link_sta_params.vht_capa =
7600 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
7602 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
7603 params.link_sta_params.he_capa =
7604 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
7605 params.link_sta_params.he_capa_len =
7606 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
7608 if (info->attrs[NL80211_ATTR_EHT_CAPABILITY]) {
7609 params.link_sta_params.eht_capa =
7610 nla_data(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
7611 params.link_sta_params.eht_capa_len =
7612 nla_len(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
7614 if (!ieee80211_eht_capa_size_ok((const u8 *)params.link_sta_params.he_capa,
7615 (const u8 *)params.link_sta_params.eht_capa,
7616 params.link_sta_params.eht_capa_len,
7617 false))
7618 return -EINVAL;
7622 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
7623 params.link_sta_params.he_6ghz_capa =
7624 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
7626 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
7627 params.link_sta_params.opmode_notif_used = true;
7628 params.link_sta_params.opmode_notif =
7629 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
7632 if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
7633 params.plink_action =
7634 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);
7636 if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT])
7637 params.airtime_weight =
7638 nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]);
7640 if (params.airtime_weight &&
7641 !wiphy_ext_feature_isset(&rdev->wiphy,
7642 NL80211_EXT_FEATURE_AIRTIME_FAIRNESS))
7643 return -EOPNOTSUPP;
7645 err = nl80211_parse_sta_txpower_setting(info,
7646 &params.link_sta_params.txpwr,
7647 &params.link_sta_params.txpwr_set);
7648 if (err)
7649 return err;
7651 err = nl80211_parse_sta_channel_info(info, &params);
7652 if (err)
7653 return err;
7655 err = nl80211_parse_sta_wme(info, &params);
7656 if (err)
7657 return err;
7659 if (parse_station_flags(info, dev->ieee80211_ptr->iftype, &params))
7660 return -EINVAL;
7662 /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT
7663 * as userspace might just pass through the capabilities from the IEs
7664 * directly, rather than enforcing this restriction and returning an
7665 * error in this case.
7667 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) {
7668 params.link_sta_params.ht_capa = NULL;
7669 params.link_sta_params.vht_capa = NULL;
7671 /* HE and EHT require WME */
7672 if (params.link_sta_params.he_capa_len ||
7673 params.link_sta_params.he_6ghz_capa ||
7674 params.link_sta_params.eht_capa_len)
7675 return -EINVAL;
7678 /* Ensure that HT/VHT capabilities are not set for 6 GHz HE STA */
7679 if (params.link_sta_params.he_6ghz_capa &&
7680 (params.link_sta_params.ht_capa || params.link_sta_params.vht_capa))
7681 return -EINVAL;
7683 /* When you run into this, adjust the code below for the new flag */
7684 BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 8);
7686 switch (dev->ieee80211_ptr->iftype) {
7687 case NL80211_IFTYPE_AP:
7688 case NL80211_IFTYPE_AP_VLAN:
7689 case NL80211_IFTYPE_P2P_GO:
7690 /* ignore WME attributes if iface/sta is not capable */
7691 if (!(rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) ||
7692 !(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)))
7693 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
7695 /* TDLS peers cannot be added */
7696 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
7697 info->attrs[NL80211_ATTR_PEER_AID])
7698 return -EINVAL;
7699 /* but don't bother the driver with it */
7700 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
7702 /* allow authenticated/associated only if driver handles it */
7703 if (!(rdev->wiphy.features &
7704 NL80211_FEATURE_FULL_AP_CLIENT_STATE) &&
7705 params.sta_flags_mask & auth_assoc)
7706 return -EINVAL;
7708 if (!wiphy_ext_feature_isset(&rdev->wiphy,
7709 NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT) &&
7710 params.sta_flags_mask & BIT(NL80211_STA_FLAG_SPP_AMSDU))
7711 return -EINVAL;
7713 /* Older userspace, or userspace wanting to be compatible with
7714 * !NL80211_FEATURE_FULL_AP_CLIENT_STATE, will not set the auth
7715 * and assoc flags in the mask, but assumes the station will be
7716 * added as associated anyway since this was the required driver
7717 * behaviour before NL80211_FEATURE_FULL_AP_CLIENT_STATE was
7718 * introduced.
7719 * In order to not bother drivers with this quirk in the API
7720 * set the flags in both the mask and set for new stations in
7721 * this case.
7723 if (!(params.sta_flags_mask & auth_assoc)) {
7724 params.sta_flags_mask |= auth_assoc;
7725 params.sta_flags_set |= auth_assoc;
7728 /* must be last in here for error handling */
7729 params.vlan = get_vlan(info, rdev);
7730 if (IS_ERR(params.vlan))
7731 return PTR_ERR(params.vlan);
7732 break;
7733 case NL80211_IFTYPE_MESH_POINT:
7734 /* ignore uAPSD data */
7735 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
7737 /* associated is disallowed */
7738 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
7739 return -EINVAL;
7740 /* TDLS peers cannot be added */
7741 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
7742 info->attrs[NL80211_ATTR_PEER_AID])
7743 return -EINVAL;
7744 break;
7745 case NL80211_IFTYPE_STATION:
7746 case NL80211_IFTYPE_P2P_CLIENT:
7747 /* ignore uAPSD data */
7748 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
7750 /* these are disallowed */
7751 if (params.sta_flags_mask &
7752 (BIT(NL80211_STA_FLAG_ASSOCIATED) |
7753 BIT(NL80211_STA_FLAG_AUTHENTICATED)))
7754 return -EINVAL;
7755 /* Only TDLS peers can be added */
7756 if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
7757 return -EINVAL;
7758 /* Can only add if TDLS ... */
7759 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS))
7760 return -EOPNOTSUPP;
7761 /* ... with external setup is supported */
7762 if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP))
7763 return -EOPNOTSUPP;
7765 * Older wpa_supplicant versions always mark the TDLS peer
7766 * as authorized, but it shouldn't yet be.
7768 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_AUTHORIZED);
7769 break;
7770 default:
7771 return -EOPNOTSUPP;
7774 /* be aware of params.vlan when changing code here */
7776 if (wdev->valid_links) {
7777 if (params.link_sta_params.link_id < 0) {
7778 err = -EINVAL;
7779 goto out;
7781 if (!(wdev->valid_links & BIT(params.link_sta_params.link_id))) {
7782 err = -ENOLINK;
7783 goto out;
7785 } else {
7786 if (params.link_sta_params.link_id >= 0) {
7787 err = -EINVAL;
7788 goto out;
7791 err = rdev_add_station(rdev, dev, mac_addr, &params);
7792 out:
7793 dev_put(params.vlan);
7794 return err;
7797 static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
7799 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7800 struct net_device *dev = info->user_ptr[1];
7801 struct wireless_dev *wdev = dev->ieee80211_ptr;
7802 struct station_del_parameters params;
7803 int link_id = nl80211_link_id_or_invalid(info->attrs);
7805 memset(&params, 0, sizeof(params));
7807 if (info->attrs[NL80211_ATTR_MAC])
7808 params.mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
7810 switch (wdev->iftype) {
7811 case NL80211_IFTYPE_AP:
7812 case NL80211_IFTYPE_AP_VLAN:
7813 case NL80211_IFTYPE_MESH_POINT:
7814 case NL80211_IFTYPE_P2P_GO:
7815 /* always accept these */
7816 break;
7817 case NL80211_IFTYPE_ADHOC:
7818 /* conditionally accept */
7819 if (wiphy_ext_feature_isset(&rdev->wiphy,
7820 NL80211_EXT_FEATURE_DEL_IBSS_STA))
7821 break;
7822 return -EINVAL;
7823 default:
7824 return -EINVAL;
7827 if (!rdev->ops->del_station)
7828 return -EOPNOTSUPP;
7830 if (info->attrs[NL80211_ATTR_MGMT_SUBTYPE]) {
7831 params.subtype =
7832 nla_get_u8(info->attrs[NL80211_ATTR_MGMT_SUBTYPE]);
7833 if (params.subtype != IEEE80211_STYPE_DISASSOC >> 4 &&
7834 params.subtype != IEEE80211_STYPE_DEAUTH >> 4)
7835 return -EINVAL;
7836 } else {
7837 /* Default to Deauthentication frame */
7838 params.subtype = IEEE80211_STYPE_DEAUTH >> 4;
7841 if (info->attrs[NL80211_ATTR_REASON_CODE]) {
7842 params.reason_code =
7843 nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
7844 if (params.reason_code == 0)
7845 return -EINVAL; /* 0 is reserved */
7846 } else {
7847 /* Default to reason code 2 */
7848 params.reason_code = WLAN_REASON_PREV_AUTH_NOT_VALID;
7851 /* Link ID not expected in case of non-ML operation */
7852 if (!wdev->valid_links && link_id != -1)
7853 return -EINVAL;
7855 /* If given, a valid link ID should be passed during MLO */
7856 if (wdev->valid_links && link_id >= 0 &&
7857 !(wdev->valid_links & BIT(link_id)))
7858 return -EINVAL;
7860 params.link_id = link_id;
7862 return rdev_del_station(rdev, dev, &params);
7865 static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq,
7866 int flags, struct net_device *dev,
7867 u8 *dst, u8 *next_hop,
7868 struct mpath_info *pinfo)
7870 void *hdr;
7871 struct nlattr *pinfoattr;
7873 hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_MPATH);
7874 if (!hdr)
7875 return -1;
7877 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
7878 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) ||
7879 nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) ||
7880 nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation))
7881 goto nla_put_failure;
7883 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MPATH_INFO);
7884 if (!pinfoattr)
7885 goto nla_put_failure;
7886 if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) &&
7887 nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN,
7888 pinfo->frame_qlen))
7889 goto nla_put_failure;
7890 if (((pinfo->filled & MPATH_INFO_SN) &&
7891 nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) ||
7892 ((pinfo->filled & MPATH_INFO_METRIC) &&
7893 nla_put_u32(msg, NL80211_MPATH_INFO_METRIC,
7894 pinfo->metric)) ||
7895 ((pinfo->filled & MPATH_INFO_EXPTIME) &&
7896 nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME,
7897 pinfo->exptime)) ||
7898 ((pinfo->filled & MPATH_INFO_FLAGS) &&
7899 nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS,
7900 pinfo->flags)) ||
7901 ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) &&
7902 nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT,
7903 pinfo->discovery_timeout)) ||
7904 ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) &&
7905 nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES,
7906 pinfo->discovery_retries)) ||
7907 ((pinfo->filled & MPATH_INFO_HOP_COUNT) &&
7908 nla_put_u8(msg, NL80211_MPATH_INFO_HOP_COUNT,
7909 pinfo->hop_count)) ||
7910 ((pinfo->filled & MPATH_INFO_PATH_CHANGE) &&
7911 nla_put_u32(msg, NL80211_MPATH_INFO_PATH_CHANGE,
7912 pinfo->path_change_count)))
7913 goto nla_put_failure;
7915 nla_nest_end(msg, pinfoattr);
7917 genlmsg_end(msg, hdr);
7918 return 0;
7920 nla_put_failure:
7921 genlmsg_cancel(msg, hdr);
7922 return -EMSGSIZE;
7925 static int nl80211_dump_mpath(struct sk_buff *skb,
7926 struct netlink_callback *cb)
7928 struct mpath_info pinfo;
7929 struct cfg80211_registered_device *rdev;
7930 struct wireless_dev *wdev;
7931 u8 dst[ETH_ALEN];
7932 u8 next_hop[ETH_ALEN];
7933 int path_idx = cb->args[2];
7934 int err;
7936 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
7937 if (err)
7938 return err;
7939 /* nl80211_prepare_wdev_dump acquired it in the successful case */
7940 __acquire(&rdev->wiphy.mtx);
7942 if (!rdev->ops->dump_mpath) {
7943 err = -EOPNOTSUPP;
7944 goto out_err;
7947 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
7948 err = -EOPNOTSUPP;
7949 goto out_err;
7952 while (1) {
7953 err = rdev_dump_mpath(rdev, wdev->netdev, path_idx, dst,
7954 next_hop, &pinfo);
7955 if (err == -ENOENT)
7956 break;
7957 if (err)
7958 goto out_err;
7960 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
7961 cb->nlh->nlmsg_seq, NLM_F_MULTI,
7962 wdev->netdev, dst, next_hop,
7963 &pinfo) < 0)
7964 goto out;
7966 path_idx++;
7969 out:
7970 cb->args[2] = path_idx;
7971 err = skb->len;
7972 out_err:
7973 wiphy_unlock(&rdev->wiphy);
7974 return err;
7977 static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
7979 struct cfg80211_registered_device *rdev = info->user_ptr[0];
7980 int err;
7981 struct net_device *dev = info->user_ptr[1];
7982 struct mpath_info pinfo;
7983 struct sk_buff *msg;
7984 u8 *dst = NULL;
7985 u8 next_hop[ETH_ALEN];
7987 memset(&pinfo, 0, sizeof(pinfo));
7989 if (!info->attrs[NL80211_ATTR_MAC])
7990 return -EINVAL;
7992 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
7994 if (!rdev->ops->get_mpath)
7995 return -EOPNOTSUPP;
7997 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
7998 return -EOPNOTSUPP;
8000 err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo);
8001 if (err)
8002 return err;
8004 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8005 if (!msg)
8006 return -ENOMEM;
8008 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
8009 dev, dst, next_hop, &pinfo) < 0) {
8010 nlmsg_free(msg);
8011 return -ENOBUFS;
8014 return genlmsg_reply(msg, info);
8017 static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
8019 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8020 struct net_device *dev = info->user_ptr[1];
8021 u8 *dst = NULL;
8022 u8 *next_hop = NULL;
8024 if (!info->attrs[NL80211_ATTR_MAC])
8025 return -EINVAL;
8027 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
8028 return -EINVAL;
8030 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
8031 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
8033 if (!rdev->ops->change_mpath)
8034 return -EOPNOTSUPP;
8036 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
8037 return -EOPNOTSUPP;
8039 return rdev_change_mpath(rdev, dev, dst, next_hop);
8042 static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
8044 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8045 struct net_device *dev = info->user_ptr[1];
8046 u8 *dst = NULL;
8047 u8 *next_hop = NULL;
8049 if (!info->attrs[NL80211_ATTR_MAC])
8050 return -EINVAL;
8052 if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP])
8053 return -EINVAL;
8055 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
8056 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);
8058 if (!rdev->ops->add_mpath)
8059 return -EOPNOTSUPP;
8061 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
8062 return -EOPNOTSUPP;
8064 return rdev_add_mpath(rdev, dev, dst, next_hop);
8067 static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
8069 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8070 struct net_device *dev = info->user_ptr[1];
8071 u8 *dst = NULL;
8073 if (info->attrs[NL80211_ATTR_MAC])
8074 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
8076 if (!rdev->ops->del_mpath)
8077 return -EOPNOTSUPP;
8079 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
8080 return -EOPNOTSUPP;
8082 return rdev_del_mpath(rdev, dev, dst);
8085 static int nl80211_get_mpp(struct sk_buff *skb, struct genl_info *info)
8087 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8088 int err;
8089 struct net_device *dev = info->user_ptr[1];
8090 struct mpath_info pinfo;
8091 struct sk_buff *msg;
8092 u8 *dst = NULL;
8093 u8 mpp[ETH_ALEN];
8095 memset(&pinfo, 0, sizeof(pinfo));
8097 if (!info->attrs[NL80211_ATTR_MAC])
8098 return -EINVAL;
8100 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);
8102 if (!rdev->ops->get_mpp)
8103 return -EOPNOTSUPP;
8105 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
8106 return -EOPNOTSUPP;
8108 err = rdev_get_mpp(rdev, dev, dst, mpp, &pinfo);
8109 if (err)
8110 return err;
8112 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8113 if (!msg)
8114 return -ENOMEM;
8116 if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0,
8117 dev, dst, mpp, &pinfo) < 0) {
8118 nlmsg_free(msg);
8119 return -ENOBUFS;
8122 return genlmsg_reply(msg, info);
8125 static int nl80211_dump_mpp(struct sk_buff *skb,
8126 struct netlink_callback *cb)
8128 struct mpath_info pinfo;
8129 struct cfg80211_registered_device *rdev;
8130 struct wireless_dev *wdev;
8131 u8 dst[ETH_ALEN];
8132 u8 mpp[ETH_ALEN];
8133 int path_idx = cb->args[2];
8134 int err;
8136 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, NULL);
8137 if (err)
8138 return err;
8139 /* nl80211_prepare_wdev_dump acquired it in the successful case */
8140 __acquire(&rdev->wiphy.mtx);
8142 if (!rdev->ops->dump_mpp) {
8143 err = -EOPNOTSUPP;
8144 goto out_err;
8147 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) {
8148 err = -EOPNOTSUPP;
8149 goto out_err;
8152 while (1) {
8153 err = rdev_dump_mpp(rdev, wdev->netdev, path_idx, dst,
8154 mpp, &pinfo);
8155 if (err == -ENOENT)
8156 break;
8157 if (err)
8158 goto out_err;
8160 if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid,
8161 cb->nlh->nlmsg_seq, NLM_F_MULTI,
8162 wdev->netdev, dst, mpp,
8163 &pinfo) < 0)
8164 goto out;
8166 path_idx++;
8169 out:
8170 cb->args[2] = path_idx;
8171 err = skb->len;
8172 out_err:
8173 wiphy_unlock(&rdev->wiphy);
8174 return err;
8177 static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
8179 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8180 struct net_device *dev = info->user_ptr[1];
8181 struct bss_parameters params;
8183 memset(&params, 0, sizeof(params));
8184 params.link_id = nl80211_link_id_or_invalid(info->attrs);
8185 /* default to not changing parameters */
8186 params.use_cts_prot = -1;
8187 params.use_short_preamble = -1;
8188 params.use_short_slot_time = -1;
8189 params.ap_isolate = -1;
8190 params.ht_opmode = -1;
8191 params.p2p_ctwindow = -1;
8192 params.p2p_opp_ps = -1;
8194 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
8195 params.use_cts_prot =
8196 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
8197 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
8198 params.use_short_preamble =
8199 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
8200 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
8201 params.use_short_slot_time =
8202 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
8203 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
8204 params.basic_rates =
8205 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8206 params.basic_rates_len =
8207 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
8209 if (info->attrs[NL80211_ATTR_AP_ISOLATE])
8210 params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]);
8211 if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
8212 params.ht_opmode =
8213 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
8215 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
8216 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
8217 return -EINVAL;
8218 params.p2p_ctwindow =
8219 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
8220 if (params.p2p_ctwindow != 0 &&
8221 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
8222 return -EINVAL;
8225 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
8226 u8 tmp;
8228 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
8229 return -EINVAL;
8230 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
8231 params.p2p_opp_ps = tmp;
8232 if (params.p2p_opp_ps &&
8233 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
8234 return -EINVAL;
8237 if (!rdev->ops->change_bss)
8238 return -EOPNOTSUPP;
8240 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
8241 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
8242 return -EOPNOTSUPP;
8244 return rdev_change_bss(rdev, dev, &params);
8247 static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
8249 char *data = NULL;
8250 bool is_indoor;
8251 enum nl80211_user_reg_hint_type user_reg_hint_type;
8252 u32 owner_nlportid;
8255 * You should only get this when cfg80211 hasn't yet initialized
8256 * completely when built-in to the kernel right between the time
8257 * window between nl80211_init() and regulatory_init(), if that is
8258 * even possible.
8260 if (unlikely(!rcu_access_pointer(cfg80211_regdomain)))
8261 return -EINPROGRESS;
8263 user_reg_hint_type =
8264 nla_get_u32_default(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE],
8265 NL80211_USER_REG_HINT_USER);
8267 switch (user_reg_hint_type) {
8268 case NL80211_USER_REG_HINT_USER:
8269 case NL80211_USER_REG_HINT_CELL_BASE:
8270 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
8271 return -EINVAL;
8273 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
8274 return regulatory_hint_user(data, user_reg_hint_type);
8275 case NL80211_USER_REG_HINT_INDOOR:
8276 if (info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
8277 owner_nlportid = info->snd_portid;
8278 is_indoor = !!info->attrs[NL80211_ATTR_REG_INDOOR];
8279 } else {
8280 owner_nlportid = 0;
8281 is_indoor = true;
8284 regulatory_hint_indoor(is_indoor, owner_nlportid);
8285 return 0;
8286 default:
8287 return -EINVAL;
8291 static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
8293 return reg_reload_regdb();
8296 static int nl80211_get_mesh_config(struct sk_buff *skb,
8297 struct genl_info *info)
8299 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8300 struct net_device *dev = info->user_ptr[1];
8301 struct wireless_dev *wdev = dev->ieee80211_ptr;
8302 struct mesh_config cur_params;
8303 int err = 0;
8304 void *hdr;
8305 struct nlattr *pinfoattr;
8306 struct sk_buff *msg;
8308 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
8309 return -EOPNOTSUPP;
8311 if (!rdev->ops->get_mesh_config)
8312 return -EOPNOTSUPP;
8314 /* If not connected, get default parameters */
8315 if (!wdev->u.mesh.id_len)
8316 memcpy(&cur_params, &default_mesh_config, sizeof(cur_params));
8317 else
8318 err = rdev_get_mesh_config(rdev, dev, &cur_params);
8320 if (err)
8321 return err;
8323 /* Draw up a netlink message to send back */
8324 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8325 if (!msg)
8326 return -ENOMEM;
8327 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
8328 NL80211_CMD_GET_MESH_CONFIG);
8329 if (!hdr)
8330 goto out;
8331 pinfoattr = nla_nest_start_noflag(msg, NL80211_ATTR_MESH_CONFIG);
8332 if (!pinfoattr)
8333 goto nla_put_failure;
8334 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
8335 nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT,
8336 cur_params.dot11MeshRetryTimeout) ||
8337 nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT,
8338 cur_params.dot11MeshConfirmTimeout) ||
8339 nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT,
8340 cur_params.dot11MeshHoldingTimeout) ||
8341 nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS,
8342 cur_params.dot11MeshMaxPeerLinks) ||
8343 nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES,
8344 cur_params.dot11MeshMaxRetries) ||
8345 nla_put_u8(msg, NL80211_MESHCONF_TTL,
8346 cur_params.dot11MeshTTL) ||
8347 nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL,
8348 cur_params.element_ttl) ||
8349 nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS,
8350 cur_params.auto_open_plinks) ||
8351 nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
8352 cur_params.dot11MeshNbrOffsetMaxNeighbor) ||
8353 nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
8354 cur_params.dot11MeshHWMPmaxPREQretries) ||
8355 nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME,
8356 cur_params.path_refresh_time) ||
8357 nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
8358 cur_params.min_discovery_timeout) ||
8359 nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
8360 cur_params.dot11MeshHWMPactivePathTimeout) ||
8361 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
8362 cur_params.dot11MeshHWMPpreqMinInterval) ||
8363 nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
8364 cur_params.dot11MeshHWMPperrMinInterval) ||
8365 nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
8366 cur_params.dot11MeshHWMPnetDiameterTraversalTime) ||
8367 nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE,
8368 cur_params.dot11MeshHWMPRootMode) ||
8369 nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL,
8370 cur_params.dot11MeshHWMPRannInterval) ||
8371 nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
8372 cur_params.dot11MeshGateAnnouncementProtocol) ||
8373 nla_put_u8(msg, NL80211_MESHCONF_FORWARDING,
8374 cur_params.dot11MeshForwarding) ||
8375 nla_put_s32(msg, NL80211_MESHCONF_RSSI_THRESHOLD,
8376 cur_params.rssi_threshold) ||
8377 nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE,
8378 cur_params.ht_opmode) ||
8379 nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
8380 cur_params.dot11MeshHWMPactivePathToRootTimeout) ||
8381 nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
8382 cur_params.dot11MeshHWMProotInterval) ||
8383 nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
8384 cur_params.dot11MeshHWMPconfirmationInterval) ||
8385 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
8386 cur_params.power_mode) ||
8387 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
8388 cur_params.dot11MeshAwakeWindowDuration) ||
8389 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
8390 cur_params.plink_timeout) ||
8391 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_GATE,
8392 cur_params.dot11MeshConnectedToMeshGate) ||
8393 nla_put_u8(msg, NL80211_MESHCONF_NOLEARN,
8394 cur_params.dot11MeshNolearn) ||
8395 nla_put_u8(msg, NL80211_MESHCONF_CONNECTED_TO_AS,
8396 cur_params.dot11MeshConnectedToAuthServer))
8397 goto nla_put_failure;
8398 nla_nest_end(msg, pinfoattr);
8399 genlmsg_end(msg, hdr);
8400 return genlmsg_reply(msg, info);
8402 nla_put_failure:
8403 out:
8404 nlmsg_free(msg);
8405 return -ENOBUFS;
8408 static const struct nla_policy
8409 nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = {
8410 [NL80211_MESHCONF_RETRY_TIMEOUT] =
8411 NLA_POLICY_RANGE(NLA_U16, 1, 255),
8412 [NL80211_MESHCONF_CONFIRM_TIMEOUT] =
8413 NLA_POLICY_RANGE(NLA_U16, 1, 255),
8414 [NL80211_MESHCONF_HOLDING_TIMEOUT] =
8415 NLA_POLICY_RANGE(NLA_U16, 1, 255),
8416 [NL80211_MESHCONF_MAX_PEER_LINKS] =
8417 NLA_POLICY_RANGE(NLA_U16, 0, 255),
8418 [NL80211_MESHCONF_MAX_RETRIES] = NLA_POLICY_MAX(NLA_U8, 16),
8419 [NL80211_MESHCONF_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
8420 [NL80211_MESHCONF_ELEMENT_TTL] = NLA_POLICY_MIN(NLA_U8, 1),
8421 [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = NLA_POLICY_MAX(NLA_U8, 1),
8422 [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] =
8423 NLA_POLICY_RANGE(NLA_U32, 1, 255),
8424 [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 },
8425 [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 },
8426 [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = NLA_POLICY_MIN(NLA_U16, 1),
8427 [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 },
8428 [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] =
8429 NLA_POLICY_MIN(NLA_U16, 1),
8430 [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] =
8431 NLA_POLICY_MIN(NLA_U16, 1),
8432 [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] =
8433 NLA_POLICY_MIN(NLA_U16, 1),
8434 [NL80211_MESHCONF_HWMP_ROOTMODE] = NLA_POLICY_MAX(NLA_U8, 4),
8435 [NL80211_MESHCONF_HWMP_RANN_INTERVAL] =
8436 NLA_POLICY_MIN(NLA_U16, 1),
8437 [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = NLA_POLICY_MAX(NLA_U8, 1),
8438 [NL80211_MESHCONF_FORWARDING] = NLA_POLICY_MAX(NLA_U8, 1),
8439 [NL80211_MESHCONF_RSSI_THRESHOLD] =
8440 NLA_POLICY_RANGE(NLA_S32, -255, 0),
8441 [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 },
8442 [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 },
8443 [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] =
8444 NLA_POLICY_MIN(NLA_U16, 1),
8445 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] =
8446 NLA_POLICY_MIN(NLA_U16, 1),
8447 [NL80211_MESHCONF_POWER_MODE] =
8448 NLA_POLICY_RANGE(NLA_U32,
8449 NL80211_MESH_POWER_ACTIVE,
8450 NL80211_MESH_POWER_MAX),
8451 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
8452 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
8453 [NL80211_MESHCONF_CONNECTED_TO_GATE] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
8454 [NL80211_MESHCONF_NOLEARN] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
8455 [NL80211_MESHCONF_CONNECTED_TO_AS] = NLA_POLICY_RANGE(NLA_U8, 0, 1),
8458 static const struct nla_policy
8459 nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = {
8460 [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 },
8461 [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 },
8462 [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 },
8463 [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG },
8464 [NL80211_MESH_SETUP_AUTH_PROTOCOL] = { .type = NLA_U8 },
8465 [NL80211_MESH_SETUP_USERSPACE_MPM] = { .type = NLA_FLAG },
8466 [NL80211_MESH_SETUP_IE] =
8467 NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr,
8468 IEEE80211_MAX_DATA_LEN),
8469 [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG },
8472 static int nl80211_parse_mesh_config(struct genl_info *info,
8473 struct mesh_config *cfg,
8474 u32 *mask_out)
8476 struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1];
8477 u32 mask = 0;
8478 u16 ht_opmode;
8480 #define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, mask, attr, fn) \
8481 do { \
8482 if (tb[attr]) { \
8483 cfg->param = fn(tb[attr]); \
8484 mask |= BIT((attr) - 1); \
8486 } while (0)
8488 if (!info->attrs[NL80211_ATTR_MESH_CONFIG])
8489 return -EINVAL;
8490 if (nla_parse_nested_deprecated(tb, NL80211_MESHCONF_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_CONFIG], nl80211_meshconf_params_policy, info->extack))
8491 return -EINVAL;
8493 /* This makes sure that there aren't more than 32 mesh config
8494 * parameters (otherwise our bitfield scheme would not work.) */
8495 BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32);
8497 /* Fill in the params struct */
8498 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, mask,
8499 NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16);
8500 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, mask,
8501 NL80211_MESHCONF_CONFIRM_TIMEOUT,
8502 nla_get_u16);
8503 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, mask,
8504 NL80211_MESHCONF_HOLDING_TIMEOUT,
8505 nla_get_u16);
8506 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, mask,
8507 NL80211_MESHCONF_MAX_PEER_LINKS,
8508 nla_get_u16);
8509 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, mask,
8510 NL80211_MESHCONF_MAX_RETRIES, nla_get_u8);
8511 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, mask,
8512 NL80211_MESHCONF_TTL, nla_get_u8);
8513 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, mask,
8514 NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8);
8515 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, mask,
8516 NL80211_MESHCONF_AUTO_OPEN_PLINKS,
8517 nla_get_u8);
8518 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor,
8519 mask,
8520 NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR,
8521 nla_get_u32);
8522 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, mask,
8523 NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES,
8524 nla_get_u8);
8525 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, mask,
8526 NL80211_MESHCONF_PATH_REFRESH_TIME,
8527 nla_get_u32);
8528 if (mask & BIT(NL80211_MESHCONF_PATH_REFRESH_TIME) &&
8529 (cfg->path_refresh_time < 1 || cfg->path_refresh_time > 65535))
8530 return -EINVAL;
8531 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, mask,
8532 NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT,
8533 nla_get_u16);
8534 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout,
8535 mask,
8536 NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT,
8537 nla_get_u32);
8538 if (mask & BIT(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT) &&
8539 (cfg->dot11MeshHWMPactivePathTimeout < 1 ||
8540 cfg->dot11MeshHWMPactivePathTimeout > 65535))
8541 return -EINVAL;
8542 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, mask,
8543 NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL,
8544 nla_get_u16);
8545 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, mask,
8546 NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL,
8547 nla_get_u16);
8548 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
8549 dot11MeshHWMPnetDiameterTraversalTime, mask,
8550 NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME,
8551 nla_get_u16);
8552 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask,
8553 NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8);
8554 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask,
8555 NL80211_MESHCONF_HWMP_RANN_INTERVAL,
8556 nla_get_u16);
8557 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshGateAnnouncementProtocol,
8558 mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS,
8559 nla_get_u8);
8560 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, mask,
8561 NL80211_MESHCONF_FORWARDING, nla_get_u8);
8562 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, mask,
8563 NL80211_MESHCONF_RSSI_THRESHOLD,
8564 nla_get_s32);
8565 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToMeshGate, mask,
8566 NL80211_MESHCONF_CONNECTED_TO_GATE,
8567 nla_get_u8);
8568 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConnectedToAuthServer, mask,
8569 NL80211_MESHCONF_CONNECTED_TO_AS,
8570 nla_get_u8);
8572 * Check HT operation mode based on
8573 * IEEE 802.11-2016 9.4.2.57 HT Operation element.
8575 if (tb[NL80211_MESHCONF_HT_OPMODE]) {
8576 ht_opmode = nla_get_u16(tb[NL80211_MESHCONF_HT_OPMODE]);
8578 if (ht_opmode & ~(IEEE80211_HT_OP_MODE_PROTECTION |
8579 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT |
8580 IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT))
8581 return -EINVAL;
8583 /* NON_HT_STA bit is reserved, but some programs set it */
8584 ht_opmode &= ~IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT;
8586 cfg->ht_opmode = ht_opmode;
8587 mask |= (1 << (NL80211_MESHCONF_HT_OPMODE - 1));
8589 FILL_IN_MESH_PARAM_IF_SET(tb, cfg,
8590 dot11MeshHWMPactivePathToRootTimeout, mask,
8591 NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT,
8592 nla_get_u32);
8593 if (mask & BIT(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT) &&
8594 (cfg->dot11MeshHWMPactivePathToRootTimeout < 1 ||
8595 cfg->dot11MeshHWMPactivePathToRootTimeout > 65535))
8596 return -EINVAL;
8597 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, mask,
8598 NL80211_MESHCONF_HWMP_ROOT_INTERVAL,
8599 nla_get_u16);
8600 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPconfirmationInterval,
8601 mask,
8602 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL,
8603 nla_get_u16);
8604 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, mask,
8605 NL80211_MESHCONF_POWER_MODE, nla_get_u32);
8606 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, mask,
8607 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
8608 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, mask,
8609 NL80211_MESHCONF_PLINK_TIMEOUT, nla_get_u32);
8610 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNolearn, mask,
8611 NL80211_MESHCONF_NOLEARN, nla_get_u8);
8612 if (mask_out)
8613 *mask_out = mask;
8615 return 0;
8617 #undef FILL_IN_MESH_PARAM_IF_SET
8620 static int nl80211_parse_mesh_setup(struct genl_info *info,
8621 struct mesh_setup *setup)
8623 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8624 struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1];
8626 if (!info->attrs[NL80211_ATTR_MESH_SETUP])
8627 return -EINVAL;
8628 if (nla_parse_nested_deprecated(tb, NL80211_MESH_SETUP_ATTR_MAX, info->attrs[NL80211_ATTR_MESH_SETUP], nl80211_mesh_setup_params_policy, info->extack))
8629 return -EINVAL;
8631 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])
8632 setup->sync_method =
8633 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ?
8634 IEEE80211_SYNC_METHOD_VENDOR :
8635 IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET;
8637 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])
8638 setup->path_sel_proto =
8639 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ?
8640 IEEE80211_PATH_PROTOCOL_VENDOR :
8641 IEEE80211_PATH_PROTOCOL_HWMP;
8643 if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])
8644 setup->path_metric =
8645 (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ?
8646 IEEE80211_PATH_METRIC_VENDOR :
8647 IEEE80211_PATH_METRIC_AIRTIME;
8649 if (tb[NL80211_MESH_SETUP_IE]) {
8650 struct nlattr *ieattr =
8651 tb[NL80211_MESH_SETUP_IE];
8652 setup->ie = nla_data(ieattr);
8653 setup->ie_len = nla_len(ieattr);
8655 if (tb[NL80211_MESH_SETUP_USERSPACE_MPM] &&
8656 !(rdev->wiphy.features & NL80211_FEATURE_USERSPACE_MPM))
8657 return -EINVAL;
8658 setup->user_mpm = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_MPM]);
8659 setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]);
8660 setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]);
8661 if (setup->is_secure)
8662 setup->user_mpm = true;
8664 if (tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]) {
8665 if (!setup->user_mpm)
8666 return -EINVAL;
8667 setup->auth_id =
8668 nla_get_u8(tb[NL80211_MESH_SETUP_AUTH_PROTOCOL]);
8671 return 0;
8674 static int nl80211_update_mesh_config(struct sk_buff *skb,
8675 struct genl_info *info)
8677 struct cfg80211_registered_device *rdev = info->user_ptr[0];
8678 struct net_device *dev = info->user_ptr[1];
8679 struct wireless_dev *wdev = dev->ieee80211_ptr;
8680 struct mesh_config cfg = {};
8681 u32 mask;
8682 int err;
8684 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
8685 return -EOPNOTSUPP;
8687 if (!rdev->ops->update_mesh_config)
8688 return -EOPNOTSUPP;
8690 err = nl80211_parse_mesh_config(info, &cfg, &mask);
8691 if (err)
8692 return err;
8694 if (!wdev->u.mesh.id_len)
8695 err = -ENOLINK;
8697 if (!err)
8698 err = rdev_update_mesh_config(rdev, dev, mask, &cfg);
8700 return err;
8703 static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
8704 struct sk_buff *msg)
8706 struct nlattr *nl_reg_rules;
8707 unsigned int i;
8709 if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) ||
8710 (regdom->dfs_region &&
8711 nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region)))
8712 goto nla_put_failure;
8714 nl_reg_rules = nla_nest_start_noflag(msg, NL80211_ATTR_REG_RULES);
8715 if (!nl_reg_rules)
8716 goto nla_put_failure;
8718 for (i = 0; i < regdom->n_reg_rules; i++) {
8719 struct nlattr *nl_reg_rule;
8720 const struct ieee80211_reg_rule *reg_rule;
8721 const struct ieee80211_freq_range *freq_range;
8722 const struct ieee80211_power_rule *power_rule;
8723 unsigned int max_bandwidth_khz;
8725 reg_rule = &regdom->reg_rules[i];
8726 freq_range = &reg_rule->freq_range;
8727 power_rule = &reg_rule->power_rule;
8729 nl_reg_rule = nla_nest_start_noflag(msg, i);
8730 if (!nl_reg_rule)
8731 goto nla_put_failure;
8733 max_bandwidth_khz = freq_range->max_bandwidth_khz;
8734 if (!max_bandwidth_khz)
8735 max_bandwidth_khz = reg_get_max_bandwidth(regdom,
8736 reg_rule);
8738 if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS,
8739 reg_rule->flags) ||
8740 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START,
8741 freq_range->start_freq_khz) ||
8742 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END,
8743 freq_range->end_freq_khz) ||
8744 nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW,
8745 max_bandwidth_khz) ||
8746 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN,
8747 power_rule->max_antenna_gain) ||
8748 nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP,
8749 power_rule->max_eirp) ||
8750 nla_put_u32(msg, NL80211_ATTR_DFS_CAC_TIME,
8751 reg_rule->dfs_cac_ms))
8752 goto nla_put_failure;
8754 if ((reg_rule->flags & NL80211_RRF_PSD) &&
8755 nla_put_s8(msg, NL80211_ATTR_POWER_RULE_PSD,
8756 reg_rule->psd))
8757 goto nla_put_failure;
8759 nla_nest_end(msg, nl_reg_rule);
8762 nla_nest_end(msg, nl_reg_rules);
8763 return 0;
8765 nla_put_failure:
8766 return -EMSGSIZE;
8769 static int nl80211_get_reg_do(struct sk_buff *skb, struct genl_info *info)
8771 const struct ieee80211_regdomain *regdom = NULL;
8772 struct cfg80211_registered_device *rdev;
8773 struct wiphy *wiphy = NULL;
8774 struct sk_buff *msg;
8775 int err = -EMSGSIZE;
8776 void *hdr;
8778 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8779 if (!msg)
8780 return -ENOBUFS;
8782 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
8783 NL80211_CMD_GET_REG);
8784 if (!hdr)
8785 goto put_failure;
8787 rtnl_lock();
8789 if (info->attrs[NL80211_ATTR_WIPHY]) {
8790 bool self_managed;
8792 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
8793 if (IS_ERR(rdev)) {
8794 err = PTR_ERR(rdev);
8795 goto nla_put_failure;
8798 wiphy = &rdev->wiphy;
8799 self_managed = wiphy->regulatory_flags &
8800 REGULATORY_WIPHY_SELF_MANAGED;
8802 rcu_read_lock();
8804 regdom = get_wiphy_regdom(wiphy);
8806 /* a self-managed-reg device must have a private regdom */
8807 if (WARN_ON(!regdom && self_managed)) {
8808 err = -EINVAL;
8809 goto nla_put_failure_rcu;
8812 if (regdom &&
8813 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
8814 goto nla_put_failure_rcu;
8815 } else {
8816 rcu_read_lock();
8819 if (!wiphy && reg_last_request_cell_base() &&
8820 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
8821 NL80211_USER_REG_HINT_CELL_BASE))
8822 goto nla_put_failure_rcu;
8824 if (!regdom)
8825 regdom = rcu_dereference(cfg80211_regdomain);
8827 if (nl80211_put_regdom(regdom, msg))
8828 goto nla_put_failure_rcu;
8830 rcu_read_unlock();
8832 genlmsg_end(msg, hdr);
8833 rtnl_unlock();
8834 return genlmsg_reply(msg, info);
8836 nla_put_failure_rcu:
8837 rcu_read_unlock();
8838 nla_put_failure:
8839 rtnl_unlock();
8840 put_failure:
8841 nlmsg_free(msg);
8842 return err;
8845 static int nl80211_send_regdom(struct sk_buff *msg, struct netlink_callback *cb,
8846 u32 seq, int flags, struct wiphy *wiphy,
8847 const struct ieee80211_regdomain *regdom)
8849 void *hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
8850 NL80211_CMD_GET_REG);
8852 if (!hdr)
8853 return -1;
8855 genl_dump_check_consistent(cb, hdr);
8857 if (nl80211_put_regdom(regdom, msg))
8858 goto nla_put_failure;
8860 if (!wiphy && reg_last_request_cell_base() &&
8861 nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE,
8862 NL80211_USER_REG_HINT_CELL_BASE))
8863 goto nla_put_failure;
8865 if (wiphy &&
8866 nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
8867 goto nla_put_failure;
8869 if (wiphy && wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
8870 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
8871 goto nla_put_failure;
8873 genlmsg_end(msg, hdr);
8874 return 0;
8876 nla_put_failure:
8877 genlmsg_cancel(msg, hdr);
8878 return -EMSGSIZE;
8881 static int nl80211_get_reg_dump(struct sk_buff *skb,
8882 struct netlink_callback *cb)
8884 const struct ieee80211_regdomain *regdom = NULL;
8885 struct cfg80211_registered_device *rdev;
8886 int err, reg_idx, start = cb->args[2];
8888 rcu_read_lock();
8890 if (cfg80211_regdomain && start == 0) {
8891 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
8892 NLM_F_MULTI, NULL,
8893 rcu_dereference(cfg80211_regdomain));
8894 if (err < 0)
8895 goto out_err;
8898 /* the global regdom is idx 0 */
8899 reg_idx = 1;
8900 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
8901 regdom = get_wiphy_regdom(&rdev->wiphy);
8902 if (!regdom)
8903 continue;
8905 if (++reg_idx <= start)
8906 continue;
8908 err = nl80211_send_regdom(skb, cb, cb->nlh->nlmsg_seq,
8909 NLM_F_MULTI, &rdev->wiphy, regdom);
8910 if (err < 0) {
8911 reg_idx--;
8912 break;
8916 cb->args[2] = reg_idx;
8917 err = skb->len;
8918 out_err:
8919 rcu_read_unlock();
8920 return err;
8923 #ifdef CONFIG_CFG80211_CRDA_SUPPORT
8924 static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
8925 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
8926 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
8927 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
8928 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
8929 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
8930 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
8931 [NL80211_ATTR_DFS_CAC_TIME] = { .type = NLA_U32 },
8934 static int parse_reg_rule(struct nlattr *tb[],
8935 struct ieee80211_reg_rule *reg_rule)
8937 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
8938 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
8940 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
8941 return -EINVAL;
8942 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
8943 return -EINVAL;
8944 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
8945 return -EINVAL;
8946 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
8947 return -EINVAL;
8948 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
8949 return -EINVAL;
8951 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
8953 freq_range->start_freq_khz =
8954 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
8955 freq_range->end_freq_khz =
8956 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
8957 freq_range->max_bandwidth_khz =
8958 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
8960 power_rule->max_eirp =
8961 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
8963 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
8964 power_rule->max_antenna_gain =
8965 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
8967 if (tb[NL80211_ATTR_DFS_CAC_TIME])
8968 reg_rule->dfs_cac_ms =
8969 nla_get_u32(tb[NL80211_ATTR_DFS_CAC_TIME]);
8971 return 0;
8974 static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
8976 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
8977 struct nlattr *nl_reg_rule;
8978 char *alpha2;
8979 int rem_reg_rules, r;
8980 u32 num_rules = 0, rule_idx = 0;
8981 enum nl80211_dfs_regions dfs_region = NL80211_DFS_UNSET;
8982 struct ieee80211_regdomain *rd;
8984 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
8985 return -EINVAL;
8987 if (!info->attrs[NL80211_ATTR_REG_RULES])
8988 return -EINVAL;
8990 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
8992 if (info->attrs[NL80211_ATTR_DFS_REGION])
8993 dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]);
8995 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
8996 rem_reg_rules) {
8997 num_rules++;
8998 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
8999 return -EINVAL;
9002 rtnl_lock();
9003 if (!reg_is_valid_request(alpha2)) {
9004 r = -EINVAL;
9005 goto out;
9008 rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL);
9009 if (!rd) {
9010 r = -ENOMEM;
9011 goto out;
9014 rd->n_reg_rules = num_rules;
9015 rd->alpha2[0] = alpha2[0];
9016 rd->alpha2[1] = alpha2[1];
9019 * Disable DFS master mode if the DFS region was
9020 * not supported or known on this kernel.
9022 if (reg_supported_dfs_region(dfs_region))
9023 rd->dfs_region = dfs_region;
9025 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
9026 rem_reg_rules) {
9027 r = nla_parse_nested_deprecated(tb, NL80211_REG_RULE_ATTR_MAX,
9028 nl_reg_rule, reg_rule_policy,
9029 info->extack);
9030 if (r)
9031 goto bad_reg;
9032 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
9033 if (r)
9034 goto bad_reg;
9036 rule_idx++;
9038 if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
9039 r = -EINVAL;
9040 goto bad_reg;
9044 r = set_regdom(rd, REGD_SOURCE_CRDA);
9045 /* set_regdom takes ownership of rd */
9046 rd = NULL;
9047 bad_reg:
9048 kfree(rd);
9049 out:
9050 rtnl_unlock();
9051 return r;
9053 #endif /* CONFIG_CFG80211_CRDA_SUPPORT */
9055 static int validate_scan_freqs(struct nlattr *freqs)
9057 struct nlattr *attr1, *attr2;
9058 int n_channels = 0, tmp1, tmp2;
9060 nla_for_each_nested(attr1, freqs, tmp1)
9061 if (nla_len(attr1) != sizeof(u32))
9062 return 0;
9064 nla_for_each_nested(attr1, freqs, tmp1) {
9065 n_channels++;
9067 * Some hardware has a limited channel list for
9068 * scanning, and it is pretty much nonsensical
9069 * to scan for a channel twice, so disallow that
9070 * and don't require drivers to check that the
9071 * channel list they get isn't longer than what
9072 * they can scan, as long as they can scan all
9073 * the channels they registered at once.
9075 nla_for_each_nested(attr2, freqs, tmp2)
9076 if (attr1 != attr2 &&
9077 nla_get_u32(attr1) == nla_get_u32(attr2))
9078 return 0;
9081 return n_channels;
9084 static bool is_band_valid(struct wiphy *wiphy, enum nl80211_band b)
9086 return b < NUM_NL80211_BANDS && wiphy->bands[b];
9089 static int parse_bss_select(struct nlattr *nla, struct wiphy *wiphy,
9090 struct cfg80211_bss_selection *bss_select)
9092 struct nlattr *attr[NL80211_BSS_SELECT_ATTR_MAX + 1];
9093 struct nlattr *nest;
9094 int err;
9095 bool found = false;
9096 int i;
9098 /* only process one nested attribute */
9099 nest = nla_data(nla);
9100 if (!nla_ok(nest, nla_len(nest)))
9101 return -EINVAL;
9103 err = nla_parse_nested_deprecated(attr, NL80211_BSS_SELECT_ATTR_MAX,
9104 nest, nl80211_bss_select_policy,
9105 NULL);
9106 if (err)
9107 return err;
9109 /* only one attribute may be given */
9110 for (i = 0; i <= NL80211_BSS_SELECT_ATTR_MAX; i++) {
9111 if (attr[i]) {
9112 if (found)
9113 return -EINVAL;
9114 found = true;
9118 bss_select->behaviour = __NL80211_BSS_SELECT_ATTR_INVALID;
9120 if (attr[NL80211_BSS_SELECT_ATTR_RSSI])
9121 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI;
9123 if (attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]) {
9124 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_BAND_PREF;
9125 bss_select->param.band_pref =
9126 nla_get_u32(attr[NL80211_BSS_SELECT_ATTR_BAND_PREF]);
9127 if (!is_band_valid(wiphy, bss_select->param.band_pref))
9128 return -EINVAL;
9131 if (attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]) {
9132 struct nl80211_bss_select_rssi_adjust *adj_param;
9134 adj_param = nla_data(attr[NL80211_BSS_SELECT_ATTR_RSSI_ADJUST]);
9135 bss_select->behaviour = NL80211_BSS_SELECT_ATTR_RSSI_ADJUST;
9136 bss_select->param.adjust.band = adj_param->band;
9137 bss_select->param.adjust.delta = adj_param->delta;
9138 if (!is_band_valid(wiphy, bss_select->param.adjust.band))
9139 return -EINVAL;
9142 /* user-space did not provide behaviour attribute */
9143 if (bss_select->behaviour == __NL80211_BSS_SELECT_ATTR_INVALID)
9144 return -EINVAL;
9146 if (!(wiphy->bss_select_support & BIT(bss_select->behaviour)))
9147 return -EINVAL;
9149 return 0;
9152 int nl80211_parse_random_mac(struct nlattr **attrs,
9153 u8 *mac_addr, u8 *mac_addr_mask)
9155 int i;
9157 if (!attrs[NL80211_ATTR_MAC] && !attrs[NL80211_ATTR_MAC_MASK]) {
9158 eth_zero_addr(mac_addr);
9159 eth_zero_addr(mac_addr_mask);
9160 mac_addr[0] = 0x2;
9161 mac_addr_mask[0] = 0x3;
9163 return 0;
9166 /* need both or none */
9167 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_MAC_MASK])
9168 return -EINVAL;
9170 memcpy(mac_addr, nla_data(attrs[NL80211_ATTR_MAC]), ETH_ALEN);
9171 memcpy(mac_addr_mask, nla_data(attrs[NL80211_ATTR_MAC_MASK]), ETH_ALEN);
9173 /* don't allow or configure an mcast address */
9174 if (!is_multicast_ether_addr(mac_addr_mask) ||
9175 is_multicast_ether_addr(mac_addr))
9176 return -EINVAL;
9179 * allow users to pass a MAC address that has bits set outside
9180 * of the mask, but don't bother drivers with having to deal
9181 * with such bits
9183 for (i = 0; i < ETH_ALEN; i++)
9184 mac_addr[i] &= mac_addr_mask[i];
9186 return 0;
9189 static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev,
9190 struct ieee80211_channel *chan)
9192 unsigned int link_id;
9193 bool all_ok = true;
9195 lockdep_assert_wiphy(wdev->wiphy);
9197 if (!cfg80211_wdev_channel_allowed(wdev, chan))
9198 return false;
9200 if (!cfg80211_beaconing_iface_active(wdev))
9201 return true;
9204 * FIXME: check if we have a free HW resource/link for chan
9206 * This, as well as the FIXME below, requires knowing the link
9207 * capabilities of the hardware.
9210 /* we cannot leave radar channels */
9211 for_each_valid_link(wdev, link_id) {
9212 struct cfg80211_chan_def *chandef;
9214 chandef = wdev_chandef(wdev, link_id);
9215 if (!chandef || !chandef->chan)
9216 continue;
9219 * FIXME: don't require all_ok, but rather check only the
9220 * correct HW resource/link onto which 'chan' falls,
9221 * as only that link leaves the channel for doing
9222 * the off-channel operation.
9225 if (chandef->chan->flags & IEEE80211_CHAN_RADAR)
9226 all_ok = false;
9229 if (all_ok)
9230 return true;
9232 return regulatory_pre_cac_allowed(wdev->wiphy);
9235 static bool nl80211_check_scan_feat(struct wiphy *wiphy, u32 flags, u32 flag,
9236 enum nl80211_ext_feature_index feat)
9238 if (!(flags & flag))
9239 return true;
9240 if (wiphy_ext_feature_isset(wiphy, feat))
9241 return true;
9242 return false;
9245 static int
9246 nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
9247 void *request, struct nlattr **attrs,
9248 bool is_sched_scan)
9250 u8 *mac_addr, *mac_addr_mask;
9251 u32 *flags;
9252 enum nl80211_feature_flags randomness_flag;
9254 if (!attrs[NL80211_ATTR_SCAN_FLAGS])
9255 return 0;
9257 if (is_sched_scan) {
9258 struct cfg80211_sched_scan_request *req = request;
9260 randomness_flag = wdev ?
9261 NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
9262 NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
9263 flags = &req->flags;
9264 mac_addr = req->mac_addr;
9265 mac_addr_mask = req->mac_addr_mask;
9266 } else {
9267 struct cfg80211_scan_request *req = request;
9269 randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
9270 flags = &req->flags;
9271 mac_addr = req->mac_addr;
9272 mac_addr_mask = req->mac_addr_mask;
9275 *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
9277 if (((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
9278 !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) ||
9279 !nl80211_check_scan_feat(wiphy, *flags,
9280 NL80211_SCAN_FLAG_LOW_SPAN,
9281 NL80211_EXT_FEATURE_LOW_SPAN_SCAN) ||
9282 !nl80211_check_scan_feat(wiphy, *flags,
9283 NL80211_SCAN_FLAG_LOW_POWER,
9284 NL80211_EXT_FEATURE_LOW_POWER_SCAN) ||
9285 !nl80211_check_scan_feat(wiphy, *flags,
9286 NL80211_SCAN_FLAG_HIGH_ACCURACY,
9287 NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN) ||
9288 !nl80211_check_scan_feat(wiphy, *flags,
9289 NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME,
9290 NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME) ||
9291 !nl80211_check_scan_feat(wiphy, *flags,
9292 NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP,
9293 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP) ||
9294 !nl80211_check_scan_feat(wiphy, *flags,
9295 NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
9296 NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) ||
9297 !nl80211_check_scan_feat(wiphy, *flags,
9298 NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE,
9299 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE) ||
9300 !nl80211_check_scan_feat(wiphy, *flags,
9301 NL80211_SCAN_FLAG_RANDOM_SN,
9302 NL80211_EXT_FEATURE_SCAN_RANDOM_SN) ||
9303 !nl80211_check_scan_feat(wiphy, *flags,
9304 NL80211_SCAN_FLAG_MIN_PREQ_CONTENT,
9305 NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT))
9306 return -EOPNOTSUPP;
9308 if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
9309 int err;
9311 if (!(wiphy->features & randomness_flag) ||
9312 (wdev && wdev->connected))
9313 return -EOPNOTSUPP;
9315 err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
9316 if (err)
9317 return err;
9320 return 0;
9323 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
9325 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9326 struct wireless_dev *wdev = info->user_ptr[1];
9327 struct cfg80211_scan_request *request;
9328 struct nlattr *scan_freqs = NULL;
9329 bool scan_freqs_khz = false;
9330 struct nlattr *attr;
9331 struct wiphy *wiphy;
9332 int err, tmp, n_ssids = 0, n_channels, i;
9333 size_t ie_len, size;
9334 size_t ssids_offset, ie_offset;
9336 wiphy = &rdev->wiphy;
9338 if (wdev->iftype == NL80211_IFTYPE_NAN)
9339 return -EOPNOTSUPP;
9341 if (!rdev->ops->scan)
9342 return -EOPNOTSUPP;
9344 if (rdev->scan_req || rdev->scan_msg)
9345 return -EBUSY;
9347 if (info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ]) {
9348 if (!wiphy_ext_feature_isset(wiphy,
9349 NL80211_EXT_FEATURE_SCAN_FREQ_KHZ))
9350 return -EOPNOTSUPP;
9351 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQ_KHZ];
9352 scan_freqs_khz = true;
9353 } else if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES])
9354 scan_freqs = info->attrs[NL80211_ATTR_SCAN_FREQUENCIES];
9356 if (scan_freqs) {
9357 n_channels = validate_scan_freqs(scan_freqs);
9358 if (!n_channels)
9359 return -EINVAL;
9360 } else {
9361 n_channels = ieee80211_get_num_supported_channels(wiphy);
9364 if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
9365 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
9366 n_ssids++;
9368 if (n_ssids > wiphy->max_scan_ssids)
9369 return -EINVAL;
9371 if (info->attrs[NL80211_ATTR_IE])
9372 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9373 else
9374 ie_len = 0;
9376 if (ie_len > wiphy->max_scan_ie_len)
9377 return -EINVAL;
9379 size = struct_size(request, channels, n_channels);
9380 ssids_offset = size;
9381 size = size_add(size, array_size(sizeof(*request->ssids), n_ssids));
9382 ie_offset = size;
9383 size = size_add(size, ie_len);
9384 request = kzalloc(size, GFP_KERNEL);
9385 if (!request)
9386 return -ENOMEM;
9387 request->n_channels = n_channels;
9389 if (n_ssids)
9390 request->ssids = (void *)request + ssids_offset;
9391 request->n_ssids = n_ssids;
9392 if (ie_len)
9393 request->ie = (void *)request + ie_offset;
9395 i = 0;
9396 if (scan_freqs) {
9397 /* user specified, bail out if channel not found */
9398 nla_for_each_nested(attr, scan_freqs, tmp) {
9399 struct ieee80211_channel *chan;
9400 int freq = nla_get_u32(attr);
9402 if (!scan_freqs_khz)
9403 freq = MHZ_TO_KHZ(freq);
9405 chan = ieee80211_get_channel_khz(wiphy, freq);
9406 if (!chan) {
9407 err = -EINVAL;
9408 goto out_free;
9411 /* ignore disabled channels */
9412 if (chan->flags & IEEE80211_CHAN_DISABLED ||
9413 !cfg80211_wdev_channel_allowed(wdev, chan))
9414 continue;
9416 request->channels[i] = chan;
9417 i++;
9419 } else {
9420 enum nl80211_band band;
9422 /* all channels */
9423 for (band = 0; band < NUM_NL80211_BANDS; band++) {
9424 int j;
9426 if (!wiphy->bands[band])
9427 continue;
9428 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
9429 struct ieee80211_channel *chan;
9431 chan = &wiphy->bands[band]->channels[j];
9433 if (chan->flags & IEEE80211_CHAN_DISABLED ||
9434 !cfg80211_wdev_channel_allowed(wdev, chan))
9435 continue;
9437 request->channels[i] = chan;
9438 i++;
9443 if (!i) {
9444 err = -EINVAL;
9445 goto out_free;
9448 request->n_channels = i;
9450 for (i = 0; i < request->n_channels; i++) {
9451 struct ieee80211_channel *chan = request->channels[i];
9453 /* if we can go off-channel to the target channel we're good */
9454 if (cfg80211_off_channel_oper_allowed(wdev, chan))
9455 continue;
9457 if (!cfg80211_wdev_on_sub_chan(wdev, chan, true)) {
9458 err = -EBUSY;
9459 goto out_free;
9463 i = 0;
9464 if (n_ssids) {
9465 nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
9466 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
9467 err = -EINVAL;
9468 goto out_free;
9470 request->ssids[i].ssid_len = nla_len(attr);
9471 memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
9472 i++;
9476 if (info->attrs[NL80211_ATTR_IE]) {
9477 request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
9478 memcpy((void *)request->ie,
9479 nla_data(info->attrs[NL80211_ATTR_IE]),
9480 request->ie_len);
9483 for (i = 0; i < NUM_NL80211_BANDS; i++)
9484 if (wiphy->bands[i])
9485 request->rates[i] =
9486 (1 << wiphy->bands[i]->n_bitrates) - 1;
9488 if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) {
9489 nla_for_each_nested(attr,
9490 info->attrs[NL80211_ATTR_SCAN_SUPP_RATES],
9491 tmp) {
9492 enum nl80211_band band = nla_type(attr);
9494 if (band < 0 || band >= NUM_NL80211_BANDS) {
9495 err = -EINVAL;
9496 goto out_free;
9499 if (!wiphy->bands[band])
9500 continue;
9502 err = ieee80211_get_ratemask(wiphy->bands[band],
9503 nla_data(attr),
9504 nla_len(attr),
9505 &request->rates[band]);
9506 if (err)
9507 goto out_free;
9511 if (info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]) {
9512 request->duration =
9513 nla_get_u16(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION]);
9514 request->duration_mandatory =
9515 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
9518 err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
9519 false);
9520 if (err)
9521 goto out_free;
9523 request->no_cck =
9524 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
9526 /* Initial implementation used NL80211_ATTR_MAC to set the specific
9527 * BSSID to scan for. This was problematic because that same attribute
9528 * was already used for another purpose (local random MAC address). The
9529 * NL80211_ATTR_BSSID attribute was added to fix this. For backwards
9530 * compatibility with older userspace components, also use the
9531 * NL80211_ATTR_MAC value here if it can be determined to be used for
9532 * the specific BSSID use case instead of the random MAC address
9533 * (NL80211_ATTR_SCAN_FLAGS is used to enable random MAC address use).
9535 if (info->attrs[NL80211_ATTR_BSSID])
9536 memcpy(request->bssid,
9537 nla_data(info->attrs[NL80211_ATTR_BSSID]), ETH_ALEN);
9538 else if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) &&
9539 info->attrs[NL80211_ATTR_MAC])
9540 memcpy(request->bssid, nla_data(info->attrs[NL80211_ATTR_MAC]),
9541 ETH_ALEN);
9542 else
9543 eth_broadcast_addr(request->bssid);
9545 request->tsf_report_link_id = nl80211_link_id_or_invalid(info->attrs);
9546 request->wdev = wdev;
9547 request->wiphy = &rdev->wiphy;
9548 request->scan_start = jiffies;
9550 rdev->scan_req = request;
9551 err = cfg80211_scan(rdev);
9553 if (err)
9554 goto out_free;
9556 nl80211_send_scan_start(rdev, wdev);
9557 dev_hold(wdev->netdev);
9559 return 0;
9561 out_free:
9562 rdev->scan_req = NULL;
9563 kfree(request);
9565 return err;
9568 static int nl80211_abort_scan(struct sk_buff *skb, struct genl_info *info)
9570 struct cfg80211_registered_device *rdev = info->user_ptr[0];
9571 struct wireless_dev *wdev = info->user_ptr[1];
9573 if (!rdev->ops->abort_scan)
9574 return -EOPNOTSUPP;
9576 if (rdev->scan_msg)
9577 return 0;
9579 if (!rdev->scan_req)
9580 return -ENOENT;
9582 rdev_abort_scan(rdev, wdev);
9583 return 0;
9586 static int
9587 nl80211_parse_sched_scan_plans(struct wiphy *wiphy, int n_plans,
9588 struct cfg80211_sched_scan_request *request,
9589 struct nlattr **attrs)
9591 int tmp, err, i = 0;
9592 struct nlattr *attr;
9594 if (!attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
9595 u32 interval;
9598 * If scan plans are not specified,
9599 * %NL80211_ATTR_SCHED_SCAN_INTERVAL will be specified. In this
9600 * case one scan plan will be set with the specified scan
9601 * interval and infinite number of iterations.
9603 interval = nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]);
9604 if (!interval)
9605 return -EINVAL;
9607 request->scan_plans[0].interval =
9608 DIV_ROUND_UP(interval, MSEC_PER_SEC);
9609 if (!request->scan_plans[0].interval)
9610 return -EINVAL;
9612 if (request->scan_plans[0].interval >
9613 wiphy->max_sched_scan_plan_interval)
9614 request->scan_plans[0].interval =
9615 wiphy->max_sched_scan_plan_interval;
9617 return 0;
9620 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp) {
9621 struct nlattr *plan[NL80211_SCHED_SCAN_PLAN_MAX + 1];
9623 if (WARN_ON(i >= n_plans))
9624 return -EINVAL;
9626 err = nla_parse_nested_deprecated(plan,
9627 NL80211_SCHED_SCAN_PLAN_MAX,
9628 attr, nl80211_plan_policy,
9629 NULL);
9630 if (err)
9631 return err;
9633 if (!plan[NL80211_SCHED_SCAN_PLAN_INTERVAL])
9634 return -EINVAL;
9636 request->scan_plans[i].interval =
9637 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_INTERVAL]);
9638 if (!request->scan_plans[i].interval ||
9639 request->scan_plans[i].interval >
9640 wiphy->max_sched_scan_plan_interval)
9641 return -EINVAL;
9643 if (plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]) {
9644 request->scan_plans[i].iterations =
9645 nla_get_u32(plan[NL80211_SCHED_SCAN_PLAN_ITERATIONS]);
9646 if (!request->scan_plans[i].iterations ||
9647 (request->scan_plans[i].iterations >
9648 wiphy->max_sched_scan_plan_iterations))
9649 return -EINVAL;
9650 } else if (i < n_plans - 1) {
9652 * All scan plans but the last one must specify
9653 * a finite number of iterations
9655 return -EINVAL;
9658 i++;
9662 * The last scan plan must not specify the number of
9663 * iterations, it is supposed to run infinitely
9665 if (request->scan_plans[n_plans - 1].iterations)
9666 return -EINVAL;
9668 return 0;
9671 static struct cfg80211_sched_scan_request *
9672 nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
9673 struct nlattr **attrs, int max_match_sets)
9675 struct cfg80211_sched_scan_request *request;
9676 struct nlattr *attr;
9677 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0;
9678 enum nl80211_band band;
9679 size_t ie_len, size;
9680 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1];
9681 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF;
9683 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
9684 n_channels = validate_scan_freqs(
9685 attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
9686 if (!n_channels)
9687 return ERR_PTR(-EINVAL);
9688 } else {
9689 n_channels = ieee80211_get_num_supported_channels(wiphy);
9692 if (attrs[NL80211_ATTR_SCAN_SSIDS])
9693 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
9694 tmp)
9695 n_ssids++;
9697 if (n_ssids > wiphy->max_sched_scan_ssids)
9698 return ERR_PTR(-EINVAL);
9701 * First, count the number of 'real' matchsets. Due to an issue with
9702 * the old implementation, matchsets containing only the RSSI attribute
9703 * (NL80211_SCHED_SCAN_MATCH_ATTR_RSSI) are considered as the 'default'
9704 * RSSI for all matchsets, rather than their own matchset for reporting
9705 * all APs with a strong RSSI. This is needed to be compatible with
9706 * older userspace that treated a matchset with only the RSSI as the
9707 * global RSSI for all other matchsets - if there are other matchsets.
9709 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
9710 nla_for_each_nested(attr,
9711 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
9712 tmp) {
9713 struct nlattr *rssi;
9715 err = nla_parse_nested_deprecated(tb,
9716 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
9717 attr,
9718 nl80211_match_policy,
9719 NULL);
9720 if (err)
9721 return ERR_PTR(err);
9723 /* SSID and BSSID are mutually exclusive */
9724 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
9725 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
9726 return ERR_PTR(-EINVAL);
9728 /* add other standalone attributes here */
9729 if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
9730 tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
9731 n_match_sets++;
9732 continue;
9734 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
9735 if (rssi)
9736 default_match_rssi = nla_get_s32(rssi);
9740 /* However, if there's no other matchset, add the RSSI one */
9741 if (!n_match_sets && default_match_rssi != NL80211_SCAN_RSSI_THOLD_OFF)
9742 n_match_sets = 1;
9744 if (n_match_sets > max_match_sets)
9745 return ERR_PTR(-EINVAL);
9747 if (attrs[NL80211_ATTR_IE])
9748 ie_len = nla_len(attrs[NL80211_ATTR_IE]);
9749 else
9750 ie_len = 0;
9752 if (ie_len > wiphy->max_sched_scan_ie_len)
9753 return ERR_PTR(-EINVAL);
9755 if (attrs[NL80211_ATTR_SCHED_SCAN_PLANS]) {
9757 * NL80211_ATTR_SCHED_SCAN_INTERVAL must not be specified since
9758 * each scan plan already specifies its own interval
9760 if (attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
9761 return ERR_PTR(-EINVAL);
9763 nla_for_each_nested(attr,
9764 attrs[NL80211_ATTR_SCHED_SCAN_PLANS], tmp)
9765 n_plans++;
9766 } else {
9768 * The scan interval attribute is kept for backward
9769 * compatibility. If no scan plans are specified and sched scan
9770 * interval is specified, one scan plan will be set with this
9771 * scan interval and infinite number of iterations.
9773 if (!attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL])
9774 return ERR_PTR(-EINVAL);
9776 n_plans = 1;
9779 if (!n_plans || n_plans > wiphy->max_sched_scan_plans)
9780 return ERR_PTR(-EINVAL);
9782 if (!wiphy_ext_feature_isset(
9783 wiphy, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI) &&
9784 (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] ||
9785 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]))
9786 return ERR_PTR(-EINVAL);
9788 size = struct_size(request, channels, n_channels);
9789 size = size_add(size, array_size(sizeof(*request->ssids), n_ssids));
9790 size = size_add(size, array_size(sizeof(*request->match_sets),
9791 n_match_sets));
9792 size = size_add(size, array_size(sizeof(*request->scan_plans),
9793 n_plans));
9794 size = size_add(size, ie_len);
9795 request = kzalloc(size, GFP_KERNEL);
9796 if (!request)
9797 return ERR_PTR(-ENOMEM);
9798 request->n_channels = n_channels;
9800 if (n_ssids)
9801 request->ssids = (void *)request +
9802 struct_size(request, channels, n_channels);
9803 request->n_ssids = n_ssids;
9804 if (ie_len) {
9805 if (n_ssids)
9806 request->ie = (void *)(request->ssids + n_ssids);
9807 else
9808 request->ie = (void *)(request->channels + n_channels);
9811 if (n_match_sets) {
9812 if (request->ie)
9813 request->match_sets = (void *)(request->ie + ie_len);
9814 else if (n_ssids)
9815 request->match_sets =
9816 (void *)(request->ssids + n_ssids);
9817 else
9818 request->match_sets =
9819 (void *)(request->channels + n_channels);
9821 request->n_match_sets = n_match_sets;
9823 if (n_match_sets)
9824 request->scan_plans = (void *)(request->match_sets +
9825 n_match_sets);
9826 else if (request->ie)
9827 request->scan_plans = (void *)(request->ie + ie_len);
9828 else if (n_ssids)
9829 request->scan_plans = (void *)(request->ssids + n_ssids);
9830 else
9831 request->scan_plans = (void *)(request->channels + n_channels);
9833 request->n_scan_plans = n_plans;
9835 i = 0;
9836 if (attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
9837 /* user specified, bail out if channel not found */
9838 nla_for_each_nested(attr,
9839 attrs[NL80211_ATTR_SCAN_FREQUENCIES],
9840 tmp) {
9841 struct ieee80211_channel *chan;
9843 chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
9845 if (!chan) {
9846 err = -EINVAL;
9847 goto out_free;
9850 /* ignore disabled channels */
9851 if (chan->flags & IEEE80211_CHAN_DISABLED)
9852 continue;
9854 request->channels[i] = chan;
9855 i++;
9857 } else {
9858 /* all channels */
9859 for (band = 0; band < NUM_NL80211_BANDS; band++) {
9860 int j;
9862 if (!wiphy->bands[band])
9863 continue;
9864 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
9865 struct ieee80211_channel *chan;
9867 chan = &wiphy->bands[band]->channels[j];
9869 if (chan->flags & IEEE80211_CHAN_DISABLED)
9870 continue;
9872 request->channels[i] = chan;
9873 i++;
9878 if (!i) {
9879 err = -EINVAL;
9880 goto out_free;
9883 request->n_channels = i;
9885 i = 0;
9886 if (n_ssids) {
9887 nla_for_each_nested(attr, attrs[NL80211_ATTR_SCAN_SSIDS],
9888 tmp) {
9889 if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
9890 err = -EINVAL;
9891 goto out_free;
9893 request->ssids[i].ssid_len = nla_len(attr);
9894 memcpy(request->ssids[i].ssid, nla_data(attr),
9895 nla_len(attr));
9896 i++;
9900 i = 0;
9901 if (attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) {
9902 nla_for_each_nested(attr,
9903 attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
9904 tmp) {
9905 struct nlattr *ssid, *bssid, *rssi;
9907 err = nla_parse_nested_deprecated(tb,
9908 NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
9909 attr,
9910 nl80211_match_policy,
9911 NULL);
9912 if (err)
9913 goto out_free;
9914 ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
9915 bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
9917 if (!ssid && !bssid) {
9918 i++;
9919 continue;
9922 if (WARN_ON(i >= n_match_sets)) {
9923 /* this indicates a programming error,
9924 * the loop above should have verified
9925 * things properly
9927 err = -EINVAL;
9928 goto out_free;
9931 if (ssid) {
9932 memcpy(request->match_sets[i].ssid.ssid,
9933 nla_data(ssid), nla_len(ssid));
9934 request->match_sets[i].ssid.ssid_len =
9935 nla_len(ssid);
9937 if (bssid)
9938 memcpy(request->match_sets[i].bssid,
9939 nla_data(bssid), ETH_ALEN);
9941 /* special attribute - old implementation w/a */
9942 request->match_sets[i].rssi_thold = default_match_rssi;
9943 rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI];
9944 if (rssi)
9945 request->match_sets[i].rssi_thold =
9946 nla_get_s32(rssi);
9947 i++;
9950 /* there was no other matchset, so the RSSI one is alone */
9951 if (i == 0 && n_match_sets)
9952 request->match_sets[0].rssi_thold = default_match_rssi;
9954 request->min_rssi_thold = INT_MAX;
9955 for (i = 0; i < n_match_sets; i++)
9956 request->min_rssi_thold =
9957 min(request->match_sets[i].rssi_thold,
9958 request->min_rssi_thold);
9959 } else {
9960 request->min_rssi_thold = NL80211_SCAN_RSSI_THOLD_OFF;
9963 if (ie_len) {
9964 request->ie_len = ie_len;
9965 memcpy((void *)request->ie,
9966 nla_data(attrs[NL80211_ATTR_IE]),
9967 request->ie_len);
9970 err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
9971 if (err)
9972 goto out_free;
9974 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
9975 request->delay =
9976 nla_get_u32(attrs[NL80211_ATTR_SCHED_SCAN_DELAY]);
9978 if (attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]) {
9979 request->relative_rssi = nla_get_s8(
9980 attrs[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI]);
9981 request->relative_rssi_set = true;
9984 if (request->relative_rssi_set &&
9985 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]) {
9986 struct nl80211_bss_select_rssi_adjust *rssi_adjust;
9988 rssi_adjust = nla_data(
9989 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST]);
9990 request->rssi_adjust.band = rssi_adjust->band;
9991 request->rssi_adjust.delta = rssi_adjust->delta;
9992 if (!is_band_valid(wiphy, request->rssi_adjust.band)) {
9993 err = -EINVAL;
9994 goto out_free;
9998 err = nl80211_parse_sched_scan_plans(wiphy, n_plans, request, attrs);
9999 if (err)
10000 goto out_free;
10002 request->scan_start = jiffies;
10004 return request;
10006 out_free:
10007 kfree(request);
10008 return ERR_PTR(err);
10011 static int nl80211_start_sched_scan(struct sk_buff *skb,
10012 struct genl_info *info)
10014 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10015 struct net_device *dev = info->user_ptr[1];
10016 struct wireless_dev *wdev = dev->ieee80211_ptr;
10017 struct cfg80211_sched_scan_request *sched_scan_req;
10018 bool want_multi;
10019 int err;
10021 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
10022 return -EOPNOTSUPP;
10024 want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
10025 err = cfg80211_sched_scan_req_possible(rdev, want_multi);
10026 if (err)
10027 return err;
10029 sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
10030 info->attrs,
10031 rdev->wiphy.max_match_sets);
10033 err = PTR_ERR_OR_ZERO(sched_scan_req);
10034 if (err)
10035 goto out_err;
10037 /* leave request id zero for legacy request
10038 * or if driver does not support multi-scheduled scan
10040 if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1)
10041 sched_scan_req->reqid = cfg80211_assign_cookie(rdev);
10043 err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
10044 if (err)
10045 goto out_free;
10047 sched_scan_req->dev = dev;
10048 sched_scan_req->wiphy = &rdev->wiphy;
10050 if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
10051 sched_scan_req->owner_nlportid = info->snd_portid;
10053 cfg80211_add_sched_scan_req(rdev, sched_scan_req);
10055 nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
10056 return 0;
10058 out_free:
10059 kfree(sched_scan_req);
10060 out_err:
10061 return err;
10064 static int nl80211_stop_sched_scan(struct sk_buff *skb,
10065 struct genl_info *info)
10067 struct cfg80211_sched_scan_request *req;
10068 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10069 u64 cookie;
10071 if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
10072 return -EOPNOTSUPP;
10074 if (info->attrs[NL80211_ATTR_COOKIE]) {
10075 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
10076 return __cfg80211_stop_sched_scan(rdev, cookie, false);
10079 req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
10080 struct cfg80211_sched_scan_request,
10081 list);
10082 if (!req || req->reqid ||
10083 (req->owner_nlportid &&
10084 req->owner_nlportid != info->snd_portid))
10085 return -ENOENT;
10087 return cfg80211_stop_sched_scan_req(rdev, req, false);
10090 static int nl80211_start_radar_detection(struct sk_buff *skb,
10091 struct genl_info *info)
10093 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10094 struct net_device *dev = info->user_ptr[1];
10095 struct wireless_dev *wdev = dev->ieee80211_ptr;
10096 int link_id = nl80211_link_id(info->attrs);
10097 struct wiphy *wiphy = wdev->wiphy;
10098 struct cfg80211_chan_def chandef;
10099 enum nl80211_dfs_regions dfs_region;
10100 unsigned int cac_time_ms;
10101 int err = -EINVAL;
10103 flush_delayed_work(&rdev->dfs_update_channels_wk);
10105 switch (wdev->iftype) {
10106 case NL80211_IFTYPE_AP:
10107 case NL80211_IFTYPE_P2P_GO:
10108 case NL80211_IFTYPE_MESH_POINT:
10109 case NL80211_IFTYPE_ADHOC:
10110 break;
10111 default:
10112 /* caution - see cfg80211_beaconing_iface_active() below */
10113 return -EINVAL;
10116 wiphy_lock(wiphy);
10118 dfs_region = reg_get_dfs_region(wiphy);
10119 if (dfs_region == NL80211_DFS_UNSET)
10120 goto unlock;
10122 err = nl80211_parse_chandef(rdev, info, &chandef);
10123 if (err)
10124 goto unlock;
10126 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
10127 if (err < 0)
10128 goto unlock;
10130 if (err == 0) {
10131 err = -EINVAL;
10132 goto unlock;
10135 if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) {
10136 err = -EINVAL;
10137 goto unlock;
10140 if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND])) {
10141 err = cfg80211_start_background_radar_detection(rdev, wdev,
10142 &chandef);
10143 goto unlock;
10146 if (cfg80211_beaconing_iface_active(wdev)) {
10147 /* During MLO other link(s) can beacon, only the current link
10148 * can not already beacon
10150 if (wdev->valid_links &&
10151 !wdev->links[link_id].ap.beacon_interval) {
10152 /* nothing */
10153 } else {
10154 err = -EBUSY;
10155 goto unlock;
10159 if (wdev->links[link_id].cac_started) {
10160 err = -EBUSY;
10161 goto unlock;
10164 /* CAC start is offloaded to HW and can't be started manually */
10165 if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) {
10166 err = -EOPNOTSUPP;
10167 goto unlock;
10170 if (!rdev->ops->start_radar_detection) {
10171 err = -EOPNOTSUPP;
10172 goto unlock;
10175 cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef);
10176 if (WARN_ON(!cac_time_ms))
10177 cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
10179 err = rdev_start_radar_detection(rdev, dev, &chandef, cac_time_ms,
10180 link_id);
10181 if (!err) {
10182 switch (wdev->iftype) {
10183 case NL80211_IFTYPE_AP:
10184 case NL80211_IFTYPE_P2P_GO:
10185 wdev->links[0].ap.chandef = chandef;
10186 break;
10187 case NL80211_IFTYPE_ADHOC:
10188 wdev->u.ibss.chandef = chandef;
10189 break;
10190 case NL80211_IFTYPE_MESH_POINT:
10191 wdev->u.mesh.chandef = chandef;
10192 break;
10193 default:
10194 break;
10196 wdev->links[link_id].cac_started = true;
10197 wdev->links[link_id].cac_start_time = jiffies;
10198 wdev->links[link_id].cac_time_ms = cac_time_ms;
10200 unlock:
10201 wiphy_unlock(wiphy);
10203 return err;
10206 static int nl80211_notify_radar_detection(struct sk_buff *skb,
10207 struct genl_info *info)
10209 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10210 struct net_device *dev = info->user_ptr[1];
10211 struct wireless_dev *wdev = dev->ieee80211_ptr;
10212 struct wiphy *wiphy = wdev->wiphy;
10213 struct cfg80211_chan_def chandef;
10214 enum nl80211_dfs_regions dfs_region;
10215 int err;
10217 dfs_region = reg_get_dfs_region(wiphy);
10218 if (dfs_region == NL80211_DFS_UNSET) {
10219 GENL_SET_ERR_MSG(info,
10220 "DFS Region is not set. Unexpected Radar indication");
10221 return -EINVAL;
10224 err = nl80211_parse_chandef(rdev, info, &chandef);
10225 if (err) {
10226 GENL_SET_ERR_MSG(info, "Unable to extract chandef info");
10227 return err;
10230 err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype);
10231 if (err < 0) {
10232 GENL_SET_ERR_MSG(info, "chandef is invalid");
10233 return err;
10236 if (err == 0) {
10237 GENL_SET_ERR_MSG(info,
10238 "Unexpected Radar indication for chandef/iftype");
10239 return -EINVAL;
10242 /* Do not process this notification if radar is already detected
10243 * by kernel on this channel, and return success.
10245 if (chandef.chan->dfs_state == NL80211_DFS_UNAVAILABLE)
10246 return 0;
10248 cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_UNAVAILABLE);
10250 cfg80211_sched_dfs_chan_update(rdev);
10252 rdev->radar_chandef = chandef;
10254 /* Propagate this notification to other radios as well */
10255 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
10257 return 0;
10260 static int nl80211_parse_counter_offsets(struct cfg80211_registered_device *rdev,
10261 const u8 *data, size_t datalen,
10262 int first_count, struct nlattr *attr,
10263 const u16 **offsets, unsigned int *n_offsets)
10265 int i;
10267 *n_offsets = 0;
10269 if (!attr)
10270 return 0;
10272 if (!nla_len(attr) || (nla_len(attr) % sizeof(u16)))
10273 return -EINVAL;
10275 *n_offsets = nla_len(attr) / sizeof(u16);
10276 if (rdev->wiphy.max_num_csa_counters &&
10277 (*n_offsets > rdev->wiphy.max_num_csa_counters))
10278 return -EINVAL;
10280 *offsets = nla_data(attr);
10282 /* sanity checks - counters should fit and be the same */
10283 for (i = 0; i < *n_offsets; i++) {
10284 u16 offset = (*offsets)[i];
10286 if (offset >= datalen)
10287 return -EINVAL;
10289 if (first_count != -1 && data[offset] != first_count)
10290 return -EINVAL;
10293 return 0;
10296 static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
10298 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10299 unsigned int link_id = nl80211_link_id(info->attrs);
10300 struct net_device *dev = info->user_ptr[1];
10301 struct wireless_dev *wdev = dev->ieee80211_ptr;
10302 struct cfg80211_csa_settings params;
10303 struct nlattr **csa_attrs = NULL;
10304 int err;
10305 bool need_new_beacon = false;
10306 bool need_handle_dfs_flag = true;
10307 u32 cs_count;
10309 if (!rdev->ops->channel_switch ||
10310 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH))
10311 return -EOPNOTSUPP;
10313 switch (dev->ieee80211_ptr->iftype) {
10314 case NL80211_IFTYPE_AP:
10315 case NL80211_IFTYPE_P2P_GO:
10316 need_new_beacon = true;
10317 /* For all modes except AP the handle_dfs flag needs to be
10318 * supplied to tell the kernel that userspace will handle radar
10319 * events when they happen. Otherwise a switch to a channel
10320 * requiring DFS will be rejected.
10322 need_handle_dfs_flag = false;
10324 /* useless if AP is not running */
10325 if (!wdev->links[link_id].ap.beacon_interval)
10326 return -ENOTCONN;
10327 break;
10328 case NL80211_IFTYPE_ADHOC:
10329 if (!wdev->u.ibss.ssid_len)
10330 return -ENOTCONN;
10331 break;
10332 case NL80211_IFTYPE_MESH_POINT:
10333 if (!wdev->u.mesh.id_len)
10334 return -ENOTCONN;
10335 break;
10336 default:
10337 return -EOPNOTSUPP;
10340 memset(&params, 0, sizeof(params));
10341 params.beacon_csa.ftm_responder = -1;
10343 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
10344 !info->attrs[NL80211_ATTR_CH_SWITCH_COUNT])
10345 return -EINVAL;
10347 /* only important for AP, IBSS and mesh create IEs internally */
10348 if (need_new_beacon && !info->attrs[NL80211_ATTR_CSA_IES])
10349 return -EINVAL;
10351 /* Even though the attribute is u32, the specification says
10352 * u8, so let's make sure we don't overflow.
10354 cs_count = nla_get_u32(info->attrs[NL80211_ATTR_CH_SWITCH_COUNT]);
10355 if (cs_count > 255)
10356 return -EINVAL;
10358 params.count = cs_count;
10360 if (!need_new_beacon)
10361 goto skip_beacons;
10363 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_after,
10364 info->extack);
10365 if (err)
10366 goto free;
10368 csa_attrs = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*csa_attrs),
10369 GFP_KERNEL);
10370 if (!csa_attrs) {
10371 err = -ENOMEM;
10372 goto free;
10375 err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX,
10376 info->attrs[NL80211_ATTR_CSA_IES],
10377 nl80211_policy, info->extack);
10378 if (err)
10379 goto free;
10381 err = nl80211_parse_beacon(rdev, csa_attrs, &params.beacon_csa,
10382 info->extack);
10383 if (err)
10384 goto free;
10386 if (!csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
10387 err = -EINVAL;
10388 goto free;
10391 err = nl80211_parse_counter_offsets(rdev, params.beacon_csa.tail,
10392 params.beacon_csa.tail_len,
10393 params.count,
10394 csa_attrs[NL80211_ATTR_CNTDWN_OFFS_BEACON],
10395 &params.counter_offsets_beacon,
10396 &params.n_counter_offsets_beacon);
10397 if (err)
10398 goto free;
10400 err = nl80211_parse_counter_offsets(rdev, params.beacon_csa.probe_resp,
10401 params.beacon_csa.probe_resp_len,
10402 params.count,
10403 csa_attrs[NL80211_ATTR_CNTDWN_OFFS_PRESP],
10404 &params.counter_offsets_presp,
10405 &params.n_counter_offsets_presp);
10406 if (err)
10407 goto free;
10409 skip_beacons:
10410 err = nl80211_parse_chandef(rdev, info, &params.chandef);
10411 if (err)
10412 goto free;
10414 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &params.chandef,
10415 wdev->iftype)) {
10416 err = -EINVAL;
10417 goto free;
10420 err = cfg80211_chandef_dfs_required(wdev->wiphy,
10421 &params.chandef,
10422 wdev->iftype);
10423 if (err < 0)
10424 goto free;
10426 if (err > 0) {
10427 params.radar_required = true;
10428 if (need_handle_dfs_flag &&
10429 !nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS])) {
10430 err = -EINVAL;
10431 goto free;
10435 if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX])
10436 params.block_tx = true;
10438 params.link_id = link_id;
10439 err = rdev_channel_switch(rdev, dev, &params);
10441 free:
10442 kfree(params.beacon_after.mbssid_ies);
10443 kfree(params.beacon_csa.mbssid_ies);
10444 kfree(params.beacon_after.rnr_ies);
10445 kfree(params.beacon_csa.rnr_ies);
10446 kfree(csa_attrs);
10447 return err;
10450 static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
10451 u32 seq, int flags,
10452 struct cfg80211_registered_device *rdev,
10453 struct wireless_dev *wdev,
10454 struct cfg80211_internal_bss *intbss)
10456 struct cfg80211_bss *res = &intbss->pub;
10457 const struct cfg80211_bss_ies *ies;
10458 unsigned int link_id;
10459 void *hdr;
10460 struct nlattr *bss;
10462 lockdep_assert_wiphy(wdev->wiphy);
10464 hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags,
10465 NL80211_CMD_NEW_SCAN_RESULTS);
10466 if (!hdr)
10467 return -1;
10469 genl_dump_check_consistent(cb, hdr);
10471 if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation))
10472 goto nla_put_failure;
10473 if (wdev->netdev &&
10474 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex))
10475 goto nla_put_failure;
10476 if (nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
10477 NL80211_ATTR_PAD))
10478 goto nla_put_failure;
10480 bss = nla_nest_start_noflag(msg, NL80211_ATTR_BSS);
10481 if (!bss)
10482 goto nla_put_failure;
10483 if ((!is_zero_ether_addr(res->bssid) &&
10484 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
10485 goto nla_put_failure;
10487 rcu_read_lock();
10488 /* indicate whether we have probe response data or not */
10489 if (rcu_access_pointer(res->proberesp_ies) &&
10490 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
10491 goto fail_unlock_rcu;
10493 /* this pointer prefers to be pointed to probe response data
10494 * but is always valid
10496 ies = rcu_dereference(res->ies);
10497 if (ies) {
10498 if (nla_put_u64_64bit(msg, NL80211_BSS_TSF, ies->tsf,
10499 NL80211_BSS_PAD))
10500 goto fail_unlock_rcu;
10501 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
10502 ies->len, ies->data))
10503 goto fail_unlock_rcu;
10506 /* and this pointer is always (unless driver didn't know) beacon data */
10507 ies = rcu_dereference(res->beacon_ies);
10508 if (ies && ies->from_beacon) {
10509 if (nla_put_u64_64bit(msg, NL80211_BSS_BEACON_TSF, ies->tsf,
10510 NL80211_BSS_PAD))
10511 goto fail_unlock_rcu;
10512 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
10513 ies->len, ies->data))
10514 goto fail_unlock_rcu;
10516 rcu_read_unlock();
10518 if (res->beacon_interval &&
10519 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
10520 goto nla_put_failure;
10521 if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) ||
10522 nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) ||
10523 nla_put_u32(msg, NL80211_BSS_FREQUENCY_OFFSET,
10524 res->channel->freq_offset) ||
10525 nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO,
10526 jiffies_to_msecs(jiffies - intbss->ts)))
10527 goto nla_put_failure;
10529 if (intbss->parent_tsf &&
10530 (nla_put_u64_64bit(msg, NL80211_BSS_PARENT_TSF,
10531 intbss->parent_tsf, NL80211_BSS_PAD) ||
10532 nla_put(msg, NL80211_BSS_PARENT_BSSID, ETH_ALEN,
10533 intbss->parent_bssid)))
10534 goto nla_put_failure;
10536 if (intbss->ts_boottime &&
10537 nla_put_u64_64bit(msg, NL80211_BSS_LAST_SEEN_BOOTTIME,
10538 intbss->ts_boottime, NL80211_BSS_PAD))
10539 goto nla_put_failure;
10541 if (!nl80211_put_signal(msg, intbss->pub.chains,
10542 intbss->pub.chain_signal,
10543 NL80211_BSS_CHAIN_SIGNAL))
10544 goto nla_put_failure;
10546 if (intbss->bss_source != BSS_SOURCE_STA_PROFILE) {
10547 switch (rdev->wiphy.signal_type) {
10548 case CFG80211_SIGNAL_TYPE_MBM:
10549 if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM,
10550 res->signal))
10551 goto nla_put_failure;
10552 break;
10553 case CFG80211_SIGNAL_TYPE_UNSPEC:
10554 if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC,
10555 res->signal))
10556 goto nla_put_failure;
10557 break;
10558 default:
10559 break;
10563 switch (wdev->iftype) {
10564 case NL80211_IFTYPE_P2P_CLIENT:
10565 case NL80211_IFTYPE_STATION:
10566 for_each_valid_link(wdev, link_id) {
10567 if (intbss == wdev->links[link_id].client.current_bss &&
10568 (nla_put_u32(msg, NL80211_BSS_STATUS,
10569 NL80211_BSS_STATUS_ASSOCIATED) ||
10570 (wdev->valid_links &&
10571 (nla_put_u8(msg, NL80211_BSS_MLO_LINK_ID,
10572 link_id) ||
10573 nla_put(msg, NL80211_BSS_MLD_ADDR, ETH_ALEN,
10574 wdev->u.client.connected_addr)))))
10575 goto nla_put_failure;
10577 break;
10578 case NL80211_IFTYPE_ADHOC:
10579 if (intbss == wdev->u.ibss.current_bss &&
10580 nla_put_u32(msg, NL80211_BSS_STATUS,
10581 NL80211_BSS_STATUS_IBSS_JOINED))
10582 goto nla_put_failure;
10583 break;
10584 default:
10585 break;
10588 if (nla_put_u32(msg, NL80211_BSS_USE_FOR, res->use_for))
10589 goto nla_put_failure;
10591 if (res->cannot_use_reasons &&
10592 nla_put_u64_64bit(msg, NL80211_BSS_CANNOT_USE_REASONS,
10593 res->cannot_use_reasons,
10594 NL80211_BSS_PAD))
10595 goto nla_put_failure;
10597 nla_nest_end(msg, bss);
10599 genlmsg_end(msg, hdr);
10600 return 0;
10602 fail_unlock_rcu:
10603 rcu_read_unlock();
10604 nla_put_failure:
10605 genlmsg_cancel(msg, hdr);
10606 return -EMSGSIZE;
10609 static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb)
10611 struct cfg80211_registered_device *rdev;
10612 struct cfg80211_internal_bss *scan;
10613 struct wireless_dev *wdev;
10614 struct nlattr **attrbuf;
10615 int start = cb->args[2], idx = 0;
10616 bool dump_include_use_data;
10617 int err;
10619 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
10620 if (!attrbuf)
10621 return -ENOMEM;
10623 err = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, attrbuf);
10624 if (err) {
10625 kfree(attrbuf);
10626 return err;
10628 /* nl80211_prepare_wdev_dump acquired it in the successful case */
10629 __acquire(&rdev->wiphy.mtx);
10631 dump_include_use_data =
10632 attrbuf[NL80211_ATTR_BSS_DUMP_INCLUDE_USE_DATA];
10633 kfree(attrbuf);
10635 spin_lock_bh(&rdev->bss_lock);
10638 * dump_scan will be called multiple times to break up the scan results
10639 * into multiple messages. It is unlikely that any more bss-es will be
10640 * expired after the first call, so only call only call this on the
10641 * first dump_scan invocation.
10643 if (start == 0)
10644 cfg80211_bss_expire(rdev);
10646 cb->seq = rdev->bss_generation;
10648 list_for_each_entry(scan, &rdev->bss_list, list) {
10649 if (++idx <= start)
10650 continue;
10651 if (!dump_include_use_data &&
10652 !(scan->pub.use_for & NL80211_BSS_USE_FOR_NORMAL))
10653 continue;
10654 if (nl80211_send_bss(skb, cb,
10655 cb->nlh->nlmsg_seq, NLM_F_MULTI,
10656 rdev, wdev, scan) < 0) {
10657 idx--;
10658 break;
10662 spin_unlock_bh(&rdev->bss_lock);
10664 cb->args[2] = idx;
10665 wiphy_unlock(&rdev->wiphy);
10667 return skb->len;
10670 static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq,
10671 int flags, struct net_device *dev,
10672 bool allow_radio_stats,
10673 struct survey_info *survey)
10675 void *hdr;
10676 struct nlattr *infoattr;
10678 /* skip radio stats if userspace didn't request them */
10679 if (!survey->channel && !allow_radio_stats)
10680 return 0;
10682 hdr = nl80211hdr_put(msg, portid, seq, flags,
10683 NL80211_CMD_NEW_SURVEY_RESULTS);
10684 if (!hdr)
10685 return -ENOMEM;
10687 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
10688 goto nla_put_failure;
10690 infoattr = nla_nest_start_noflag(msg, NL80211_ATTR_SURVEY_INFO);
10691 if (!infoattr)
10692 goto nla_put_failure;
10694 if (survey->channel &&
10695 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY,
10696 survey->channel->center_freq))
10697 goto nla_put_failure;
10699 if (survey->channel && survey->channel->freq_offset &&
10700 nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY_OFFSET,
10701 survey->channel->freq_offset))
10702 goto nla_put_failure;
10704 if ((survey->filled & SURVEY_INFO_NOISE_DBM) &&
10705 nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise))
10706 goto nla_put_failure;
10707 if ((survey->filled & SURVEY_INFO_IN_USE) &&
10708 nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE))
10709 goto nla_put_failure;
10710 if ((survey->filled & SURVEY_INFO_TIME) &&
10711 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME,
10712 survey->time, NL80211_SURVEY_INFO_PAD))
10713 goto nla_put_failure;
10714 if ((survey->filled & SURVEY_INFO_TIME_BUSY) &&
10715 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BUSY,
10716 survey->time_busy, NL80211_SURVEY_INFO_PAD))
10717 goto nla_put_failure;
10718 if ((survey->filled & SURVEY_INFO_TIME_EXT_BUSY) &&
10719 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_EXT_BUSY,
10720 survey->time_ext_busy, NL80211_SURVEY_INFO_PAD))
10721 goto nla_put_failure;
10722 if ((survey->filled & SURVEY_INFO_TIME_RX) &&
10723 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_RX,
10724 survey->time_rx, NL80211_SURVEY_INFO_PAD))
10725 goto nla_put_failure;
10726 if ((survey->filled & SURVEY_INFO_TIME_TX) &&
10727 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_TX,
10728 survey->time_tx, NL80211_SURVEY_INFO_PAD))
10729 goto nla_put_failure;
10730 if ((survey->filled & SURVEY_INFO_TIME_SCAN) &&
10731 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN,
10732 survey->time_scan, NL80211_SURVEY_INFO_PAD))
10733 goto nla_put_failure;
10734 if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) &&
10735 nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX,
10736 survey->time_bss_rx, NL80211_SURVEY_INFO_PAD))
10737 goto nla_put_failure;
10739 nla_nest_end(msg, infoattr);
10741 genlmsg_end(msg, hdr);
10742 return 0;
10744 nla_put_failure:
10745 genlmsg_cancel(msg, hdr);
10746 return -EMSGSIZE;
10749 static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
10751 struct nlattr **attrbuf;
10752 struct survey_info survey;
10753 struct cfg80211_registered_device *rdev;
10754 struct wireless_dev *wdev;
10755 int survey_idx = cb->args[2];
10756 int res;
10757 bool radio_stats;
10759 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
10760 if (!attrbuf)
10761 return -ENOMEM;
10763 res = nl80211_prepare_wdev_dump(cb, &rdev, &wdev, attrbuf);
10764 if (res) {
10765 kfree(attrbuf);
10766 return res;
10768 /* nl80211_prepare_wdev_dump acquired it in the successful case */
10769 __acquire(&rdev->wiphy.mtx);
10771 /* prepare_wdev_dump parsed the attributes */
10772 radio_stats = attrbuf[NL80211_ATTR_SURVEY_RADIO_STATS];
10774 if (!wdev->netdev) {
10775 res = -EINVAL;
10776 goto out_err;
10779 if (!rdev->ops->dump_survey) {
10780 res = -EOPNOTSUPP;
10781 goto out_err;
10784 while (1) {
10785 res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
10786 if (res == -ENOENT)
10787 break;
10788 if (res)
10789 goto out_err;
10791 /* don't send disabled channels, but do send non-channel data */
10792 if (survey.channel &&
10793 survey.channel->flags & IEEE80211_CHAN_DISABLED) {
10794 survey_idx++;
10795 continue;
10798 if (nl80211_send_survey(skb,
10799 NETLINK_CB(cb->skb).portid,
10800 cb->nlh->nlmsg_seq, NLM_F_MULTI,
10801 wdev->netdev, radio_stats, &survey) < 0)
10802 goto out;
10803 survey_idx++;
10806 out:
10807 cb->args[2] = survey_idx;
10808 res = skb->len;
10809 out_err:
10810 kfree(attrbuf);
10811 wiphy_unlock(&rdev->wiphy);
10812 return res;
10815 static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
10817 struct cfg80211_registered_device *rdev = info->user_ptr[0];
10818 struct net_device *dev = info->user_ptr[1];
10819 struct ieee80211_channel *chan;
10820 const u8 *bssid, *ssid;
10821 int err, ssid_len;
10822 enum nl80211_auth_type auth_type;
10823 struct key_parse key;
10824 bool local_state_change;
10825 struct cfg80211_auth_request req = {};
10826 u32 freq;
10828 if (!info->attrs[NL80211_ATTR_MAC])
10829 return -EINVAL;
10831 if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
10832 return -EINVAL;
10834 if (!info->attrs[NL80211_ATTR_SSID])
10835 return -EINVAL;
10837 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
10838 return -EINVAL;
10840 err = nl80211_parse_key(info, &key);
10841 if (err)
10842 return err;
10844 if (key.idx >= 0) {
10845 if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP)
10846 return -EINVAL;
10847 if (!key.p.key || !key.p.key_len)
10848 return -EINVAL;
10849 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
10850 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
10851 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
10852 key.p.key_len != WLAN_KEY_LEN_WEP104))
10853 return -EINVAL;
10854 if (key.idx > 3)
10855 return -EINVAL;
10856 } else {
10857 key.p.key_len = 0;
10858 key.p.key = NULL;
10861 if (key.idx >= 0) {
10862 int i;
10863 bool ok = false;
10865 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) {
10866 if (key.p.cipher == rdev->wiphy.cipher_suites[i]) {
10867 ok = true;
10868 break;
10871 if (!ok)
10872 return -EINVAL;
10875 if (!rdev->ops->auth)
10876 return -EOPNOTSUPP;
10878 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
10879 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
10880 return -EOPNOTSUPP;
10882 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
10883 freq = MHZ_TO_KHZ(nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
10884 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
10885 freq +=
10886 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
10888 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
10889 if (!chan)
10890 return -EINVAL;
10892 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
10893 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
10895 if (info->attrs[NL80211_ATTR_IE]) {
10896 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
10897 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
10900 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
10901 if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE))
10902 return -EINVAL;
10904 if ((auth_type == NL80211_AUTHTYPE_SAE ||
10905 auth_type == NL80211_AUTHTYPE_FILS_SK ||
10906 auth_type == NL80211_AUTHTYPE_FILS_SK_PFS ||
10907 auth_type == NL80211_AUTHTYPE_FILS_PK) &&
10908 !info->attrs[NL80211_ATTR_AUTH_DATA])
10909 return -EINVAL;
10911 if (info->attrs[NL80211_ATTR_AUTH_DATA]) {
10912 if (auth_type != NL80211_AUTHTYPE_SAE &&
10913 auth_type != NL80211_AUTHTYPE_FILS_SK &&
10914 auth_type != NL80211_AUTHTYPE_FILS_SK_PFS &&
10915 auth_type != NL80211_AUTHTYPE_FILS_PK)
10916 return -EINVAL;
10917 req.auth_data = nla_data(info->attrs[NL80211_ATTR_AUTH_DATA]);
10918 req.auth_data_len = nla_len(info->attrs[NL80211_ATTR_AUTH_DATA]);
10921 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
10924 * Since we no longer track auth state, ignore
10925 * requests to only change local state.
10927 if (local_state_change)
10928 return 0;
10930 req.auth_type = auth_type;
10931 req.key = key.p.key;
10932 req.key_len = key.p.key_len;
10933 req.key_idx = key.idx;
10934 req.link_id = nl80211_link_id_or_invalid(info->attrs);
10935 if (req.link_id >= 0) {
10936 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_MLO))
10937 return -EINVAL;
10938 if (!info->attrs[NL80211_ATTR_MLD_ADDR])
10939 return -EINVAL;
10940 req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
10941 if (!is_valid_ether_addr(req.ap_mld_addr))
10942 return -EINVAL;
10945 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
10946 IEEE80211_BSS_TYPE_ESS,
10947 IEEE80211_PRIVACY_ANY);
10948 if (!req.bss)
10949 return -ENOENT;
10951 err = cfg80211_mlme_auth(rdev, dev, &req);
10953 cfg80211_put_bss(&rdev->wiphy, req.bss);
10955 return err;
10958 static int validate_pae_over_nl80211(struct cfg80211_registered_device *rdev,
10959 struct genl_info *info)
10961 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
10962 GENL_SET_ERR_MSG(info, "SOCKET_OWNER not set");
10963 return -EINVAL;
10966 if (!rdev->ops->tx_control_port ||
10967 !wiphy_ext_feature_isset(&rdev->wiphy,
10968 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
10969 return -EOPNOTSUPP;
10971 return 0;
10974 static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
10975 struct genl_info *info,
10976 struct cfg80211_crypto_settings *settings,
10977 int cipher_limit)
10979 memset(settings, 0, sizeof(*settings));
10981 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
10983 if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
10984 u16 proto;
10986 proto = nla_get_u16(
10987 info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
10988 settings->control_port_ethertype = cpu_to_be16(proto);
10989 if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) &&
10990 proto != ETH_P_PAE)
10991 return -EINVAL;
10992 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT])
10993 settings->control_port_no_encrypt = true;
10994 } else
10995 settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE);
10997 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
10998 int r = validate_pae_over_nl80211(rdev, info);
11000 if (r < 0)
11001 return r;
11003 settings->control_port_over_nl80211 = true;
11005 if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_PREAUTH])
11006 settings->control_port_no_preauth = true;
11009 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
11010 void *data;
11011 int len, i;
11013 data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
11014 len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]);
11015 settings->n_ciphers_pairwise = len / sizeof(u32);
11017 if (len % sizeof(u32))
11018 return -EINVAL;
11020 if (settings->n_ciphers_pairwise > cipher_limit)
11021 return -EINVAL;
11023 memcpy(settings->ciphers_pairwise, data, len);
11025 for (i = 0; i < settings->n_ciphers_pairwise; i++)
11026 if (!cfg80211_supported_cipher_suite(
11027 &rdev->wiphy,
11028 settings->ciphers_pairwise[i]))
11029 return -EINVAL;
11032 if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) {
11033 settings->cipher_group =
11034 nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]);
11035 if (!cfg80211_supported_cipher_suite(&rdev->wiphy,
11036 settings->cipher_group))
11037 return -EINVAL;
11040 if (info->attrs[NL80211_ATTR_WPA_VERSIONS])
11041 settings->wpa_versions =
11042 nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]);
11044 if (info->attrs[NL80211_ATTR_AKM_SUITES]) {
11045 void *data;
11046 int len;
11048 data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]);
11049 len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]);
11050 settings->n_akm_suites = len / sizeof(u32);
11052 if (len % sizeof(u32))
11053 return -EINVAL;
11055 if (settings->n_akm_suites > rdev->wiphy.max_num_akm_suites)
11056 return -EINVAL;
11058 memcpy(settings->akm_suites, data, len);
11061 if (info->attrs[NL80211_ATTR_PMK]) {
11062 if (nla_len(info->attrs[NL80211_ATTR_PMK]) != WLAN_PMK_LEN)
11063 return -EINVAL;
11064 if (!wiphy_ext_feature_isset(&rdev->wiphy,
11065 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK) &&
11066 !wiphy_ext_feature_isset(&rdev->wiphy,
11067 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK))
11068 return -EINVAL;
11069 settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
11072 if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
11073 if (!wiphy_ext_feature_isset(&rdev->wiphy,
11074 NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
11075 !wiphy_ext_feature_isset(&rdev->wiphy,
11076 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP))
11077 return -EINVAL;
11078 settings->sae_pwd =
11079 nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
11080 settings->sae_pwd_len =
11081 nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
11084 settings->sae_pwe =
11085 nla_get_u8_default(info->attrs[NL80211_ATTR_SAE_PWE],
11086 NL80211_SAE_PWE_UNSPECIFIED);
11088 return 0;
11091 static struct cfg80211_bss *nl80211_assoc_bss(struct cfg80211_registered_device *rdev,
11092 const u8 *ssid, int ssid_len,
11093 struct nlattr **attrs,
11094 int assoc_link_id, int link_id)
11096 struct ieee80211_channel *chan;
11097 struct cfg80211_bss *bss;
11098 const u8 *bssid;
11099 u32 freq, use_for = 0;
11101 if (!attrs[NL80211_ATTR_MAC] || !attrs[NL80211_ATTR_WIPHY_FREQ])
11102 return ERR_PTR(-EINVAL);
11104 bssid = nla_data(attrs[NL80211_ATTR_MAC]);
11106 freq = MHZ_TO_KHZ(nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ]));
11107 if (attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
11108 freq += nla_get_u32(attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
11110 chan = nl80211_get_valid_chan(&rdev->wiphy, freq);
11111 if (!chan)
11112 return ERR_PTR(-EINVAL);
11114 if (assoc_link_id >= 0)
11115 use_for = NL80211_BSS_USE_FOR_MLD_LINK;
11116 if (assoc_link_id == link_id)
11117 use_for |= NL80211_BSS_USE_FOR_NORMAL;
11119 bss = __cfg80211_get_bss(&rdev->wiphy, chan, bssid,
11120 ssid, ssid_len,
11121 IEEE80211_BSS_TYPE_ESS,
11122 IEEE80211_PRIVACY_ANY,
11123 use_for);
11124 if (!bss)
11125 return ERR_PTR(-ENOENT);
11127 return bss;
11130 static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
11132 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11133 struct net_device *dev = info->user_ptr[1];
11134 struct cfg80211_assoc_request req = {};
11135 struct nlattr **attrs = NULL;
11136 const u8 *ap_addr, *ssid;
11137 unsigned int link_id;
11138 int err, ssid_len;
11140 if (dev->ieee80211_ptr->conn_owner_nlportid &&
11141 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
11142 return -EPERM;
11144 if (!info->attrs[NL80211_ATTR_SSID])
11145 return -EINVAL;
11147 if (!rdev->ops->assoc)
11148 return -EOPNOTSUPP;
11150 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
11151 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11152 return -EOPNOTSUPP;
11154 ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
11155 ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
11157 if (info->attrs[NL80211_ATTR_IE]) {
11158 req.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11159 req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11161 if (cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
11162 req.ie, req.ie_len)) {
11163 NL_SET_ERR_MSG_ATTR(info->extack,
11164 info->attrs[NL80211_ATTR_IE],
11165 "non-inheritance makes no sense");
11166 return -EINVAL;
11170 if (info->attrs[NL80211_ATTR_USE_MFP]) {
11171 enum nl80211_mfp mfp =
11172 nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
11173 if (mfp == NL80211_MFP_REQUIRED)
11174 req.use_mfp = true;
11175 else if (mfp != NL80211_MFP_NO)
11176 return -EINVAL;
11179 if (info->attrs[NL80211_ATTR_PREV_BSSID])
11180 req.prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
11182 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
11183 req.flags |= ASSOC_REQ_DISABLE_HT;
11185 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
11186 memcpy(&req.ht_capa_mask,
11187 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
11188 sizeof(req.ht_capa_mask));
11190 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
11191 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
11192 return -EINVAL;
11193 memcpy(&req.ht_capa,
11194 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
11195 sizeof(req.ht_capa));
11198 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
11199 req.flags |= ASSOC_REQ_DISABLE_VHT;
11201 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
11202 req.flags |= ASSOC_REQ_DISABLE_HE;
11204 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_EHT]))
11205 req.flags |= ASSOC_REQ_DISABLE_EHT;
11207 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
11208 memcpy(&req.vht_capa_mask,
11209 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
11210 sizeof(req.vht_capa_mask));
11212 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
11213 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
11214 return -EINVAL;
11215 memcpy(&req.vht_capa,
11216 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
11217 sizeof(req.vht_capa));
11220 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
11221 if (!((rdev->wiphy.features &
11222 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
11223 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
11224 !wiphy_ext_feature_isset(&rdev->wiphy,
11225 NL80211_EXT_FEATURE_RRM))
11226 return -EINVAL;
11227 req.flags |= ASSOC_REQ_USE_RRM;
11230 if (info->attrs[NL80211_ATTR_FILS_KEK]) {
11231 req.fils_kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
11232 req.fils_kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
11233 if (!info->attrs[NL80211_ATTR_FILS_NONCES])
11234 return -EINVAL;
11235 req.fils_nonces =
11236 nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
11239 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]) {
11240 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY])
11241 return -EINVAL;
11242 memcpy(&req.s1g_capa_mask,
11243 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK]),
11244 sizeof(req.s1g_capa_mask));
11247 if (info->attrs[NL80211_ATTR_S1G_CAPABILITY]) {
11248 if (!info->attrs[NL80211_ATTR_S1G_CAPABILITY_MASK])
11249 return -EINVAL;
11250 memcpy(&req.s1g_capa,
11251 nla_data(info->attrs[NL80211_ATTR_S1G_CAPABILITY]),
11252 sizeof(req.s1g_capa));
11255 if (nla_get_flag(info->attrs[NL80211_ATTR_ASSOC_SPP_AMSDU])) {
11256 if (!wiphy_ext_feature_isset(&rdev->wiphy,
11257 NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT)) {
11258 GENL_SET_ERR_MSG(info, "SPP A-MSDUs not supported");
11259 return -EINVAL;
11261 req.flags |= ASSOC_REQ_SPP_AMSDU;
11264 req.link_id = nl80211_link_id_or_invalid(info->attrs);
11266 if (info->attrs[NL80211_ATTR_MLO_LINKS]) {
11267 unsigned int attrsize = NUM_NL80211_ATTR * sizeof(*attrs);
11268 struct nlattr *link;
11269 int rem = 0;
11271 if (req.link_id < 0)
11272 return -EINVAL;
11274 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_MLO))
11275 return -EINVAL;
11277 if (info->attrs[NL80211_ATTR_MAC] ||
11278 info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
11279 !info->attrs[NL80211_ATTR_MLD_ADDR])
11280 return -EINVAL;
11282 req.ap_mld_addr = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
11283 ap_addr = req.ap_mld_addr;
11285 attrs = kzalloc(attrsize, GFP_KERNEL);
11286 if (!attrs)
11287 return -ENOMEM;
11289 nla_for_each_nested(link,
11290 info->attrs[NL80211_ATTR_MLO_LINKS],
11291 rem) {
11292 memset(attrs, 0, attrsize);
11294 nla_parse_nested(attrs, NL80211_ATTR_MAX,
11295 link, NULL, NULL);
11297 if (!attrs[NL80211_ATTR_MLO_LINK_ID]) {
11298 err = -EINVAL;
11299 NL_SET_BAD_ATTR(info->extack, link);
11300 goto free;
11303 link_id = nla_get_u8(attrs[NL80211_ATTR_MLO_LINK_ID]);
11304 /* cannot use the same link ID again */
11305 if (req.links[link_id].bss) {
11306 err = -EINVAL;
11307 NL_SET_BAD_ATTR(info->extack, link);
11308 goto free;
11310 req.links[link_id].bss =
11311 nl80211_assoc_bss(rdev, ssid, ssid_len, attrs,
11312 req.link_id, link_id);
11313 if (IS_ERR(req.links[link_id].bss)) {
11314 err = PTR_ERR(req.links[link_id].bss);
11315 req.links[link_id].bss = NULL;
11316 NL_SET_ERR_MSG_ATTR(info->extack,
11317 link, "Error fetching BSS for link");
11318 goto free;
11321 if (attrs[NL80211_ATTR_IE]) {
11322 req.links[link_id].elems =
11323 nla_data(attrs[NL80211_ATTR_IE]);
11324 req.links[link_id].elems_len =
11325 nla_len(attrs[NL80211_ATTR_IE]);
11327 if (cfg80211_find_elem(WLAN_EID_FRAGMENT,
11328 req.links[link_id].elems,
11329 req.links[link_id].elems_len)) {
11330 NL_SET_ERR_MSG_ATTR(info->extack,
11331 attrs[NL80211_ATTR_IE],
11332 "cannot deal with fragmentation");
11333 err = -EINVAL;
11334 goto free;
11337 if (cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
11338 req.links[link_id].elems,
11339 req.links[link_id].elems_len)) {
11340 NL_SET_ERR_MSG_ATTR(info->extack,
11341 attrs[NL80211_ATTR_IE],
11342 "cannot deal with non-inheritance");
11343 err = -EINVAL;
11344 goto free;
11348 req.links[link_id].disabled =
11349 nla_get_flag(attrs[NL80211_ATTR_MLO_LINK_DISABLED]);
11352 if (!req.links[req.link_id].bss) {
11353 err = -EINVAL;
11354 goto free;
11357 if (req.links[req.link_id].elems_len) {
11358 GENL_SET_ERR_MSG(info,
11359 "cannot have per-link elems on assoc link");
11360 err = -EINVAL;
11361 goto free;
11364 if (req.links[req.link_id].disabled) {
11365 GENL_SET_ERR_MSG(info,
11366 "cannot have assoc link disabled");
11367 err = -EINVAL;
11368 goto free;
11371 kfree(attrs);
11372 attrs = NULL;
11373 } else {
11374 if (req.link_id >= 0)
11375 return -EINVAL;
11377 req.bss = nl80211_assoc_bss(rdev, ssid, ssid_len, info->attrs,
11378 -1, -1);
11379 if (IS_ERR(req.bss))
11380 return PTR_ERR(req.bss);
11381 ap_addr = req.bss->bssid;
11384 err = nl80211_crypto_settings(rdev, info, &req.crypto, 1);
11385 if (!err) {
11386 struct nlattr *link;
11387 int rem = 0;
11389 err = cfg80211_mlme_assoc(rdev, dev, &req,
11390 info->extack);
11392 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
11393 dev->ieee80211_ptr->conn_owner_nlportid =
11394 info->snd_portid;
11395 memcpy(dev->ieee80211_ptr->disconnect_bssid,
11396 ap_addr, ETH_ALEN);
11399 /* Report error from first problematic link */
11400 if (info->attrs[NL80211_ATTR_MLO_LINKS]) {
11401 nla_for_each_nested(link,
11402 info->attrs[NL80211_ATTR_MLO_LINKS],
11403 rem) {
11404 struct nlattr *link_id_attr =
11405 nla_find_nested(link, NL80211_ATTR_MLO_LINK_ID);
11407 if (!link_id_attr)
11408 continue;
11410 link_id = nla_get_u8(link_id_attr);
11412 if (link_id == req.link_id)
11413 continue;
11415 if (!req.links[link_id].error ||
11416 WARN_ON(req.links[link_id].error > 0))
11417 continue;
11419 WARN_ON(err >= 0);
11421 NL_SET_BAD_ATTR(info->extack, link);
11422 err = req.links[link_id].error;
11423 break;
11428 free:
11429 for (link_id = 0; link_id < ARRAY_SIZE(req.links); link_id++)
11430 cfg80211_put_bss(&rdev->wiphy, req.links[link_id].bss);
11431 cfg80211_put_bss(&rdev->wiphy, req.bss);
11432 kfree(attrs);
11434 return err;
11437 static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
11439 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11440 struct net_device *dev = info->user_ptr[1];
11441 const u8 *ie = NULL, *bssid;
11442 int ie_len = 0;
11443 u16 reason_code;
11444 bool local_state_change;
11446 if (dev->ieee80211_ptr->conn_owner_nlportid &&
11447 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
11448 return -EPERM;
11450 if (!info->attrs[NL80211_ATTR_MAC])
11451 return -EINVAL;
11453 if (!info->attrs[NL80211_ATTR_REASON_CODE])
11454 return -EINVAL;
11456 if (!rdev->ops->deauth)
11457 return -EOPNOTSUPP;
11459 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
11460 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11461 return -EOPNOTSUPP;
11463 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
11465 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
11466 if (reason_code == 0) {
11467 /* Reason Code 0 is reserved */
11468 return -EINVAL;
11471 if (info->attrs[NL80211_ATTR_IE]) {
11472 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11473 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11476 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
11478 return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code,
11479 local_state_change);
11482 static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
11484 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11485 struct net_device *dev = info->user_ptr[1];
11486 const u8 *ie = NULL, *bssid;
11487 int ie_len = 0;
11488 u16 reason_code;
11489 bool local_state_change;
11491 if (dev->ieee80211_ptr->conn_owner_nlportid &&
11492 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
11493 return -EPERM;
11495 if (!info->attrs[NL80211_ATTR_MAC])
11496 return -EINVAL;
11498 if (!info->attrs[NL80211_ATTR_REASON_CODE])
11499 return -EINVAL;
11501 if (!rdev->ops->disassoc)
11502 return -EOPNOTSUPP;
11504 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
11505 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
11506 return -EOPNOTSUPP;
11508 bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
11510 reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
11511 if (reason_code == 0) {
11512 /* Reason Code 0 is reserved */
11513 return -EINVAL;
11516 if (info->attrs[NL80211_ATTR_IE]) {
11517 ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11518 ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11521 local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE];
11523 return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code,
11524 local_state_change);
11527 static bool
11528 nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev,
11529 int mcast_rate[NUM_NL80211_BANDS],
11530 int rateval)
11532 struct wiphy *wiphy = &rdev->wiphy;
11533 bool found = false;
11534 int band, i;
11536 for (band = 0; band < NUM_NL80211_BANDS; band++) {
11537 struct ieee80211_supported_band *sband;
11539 sband = wiphy->bands[band];
11540 if (!sband)
11541 continue;
11543 for (i = 0; i < sband->n_bitrates; i++) {
11544 if (sband->bitrates[i].bitrate == rateval) {
11545 mcast_rate[band] = i + 1;
11546 found = true;
11547 break;
11552 return found;
11555 static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
11557 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11558 struct net_device *dev = info->user_ptr[1];
11559 struct cfg80211_ibss_params ibss;
11560 struct wiphy *wiphy;
11561 struct cfg80211_cached_keys *connkeys = NULL;
11562 int err;
11564 memset(&ibss, 0, sizeof(ibss));
11566 if (!info->attrs[NL80211_ATTR_SSID] ||
11567 !nla_len(info->attrs[NL80211_ATTR_SSID]))
11568 return -EINVAL;
11570 ibss.beacon_interval = 100;
11572 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL])
11573 ibss.beacon_interval =
11574 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
11576 err = cfg80211_validate_beacon_int(rdev, NL80211_IFTYPE_ADHOC,
11577 ibss.beacon_interval);
11578 if (err)
11579 return err;
11581 if (!rdev->ops->join_ibss)
11582 return -EOPNOTSUPP;
11584 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
11585 return -EOPNOTSUPP;
11587 wiphy = &rdev->wiphy;
11589 if (info->attrs[NL80211_ATTR_MAC]) {
11590 ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
11592 if (!is_valid_ether_addr(ibss.bssid))
11593 return -EINVAL;
11595 ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
11596 ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
11598 if (info->attrs[NL80211_ATTR_IE]) {
11599 ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
11600 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
11603 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
11604 if (err)
11605 return err;
11607 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef,
11608 NL80211_IFTYPE_ADHOC))
11609 return -EINVAL;
11611 switch (ibss.chandef.width) {
11612 case NL80211_CHAN_WIDTH_5:
11613 case NL80211_CHAN_WIDTH_10:
11614 case NL80211_CHAN_WIDTH_20_NOHT:
11615 break;
11616 case NL80211_CHAN_WIDTH_20:
11617 case NL80211_CHAN_WIDTH_40:
11618 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
11619 return -EINVAL;
11620 break;
11621 case NL80211_CHAN_WIDTH_80:
11622 case NL80211_CHAN_WIDTH_80P80:
11623 case NL80211_CHAN_WIDTH_160:
11624 if (!(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
11625 return -EINVAL;
11626 if (!wiphy_ext_feature_isset(&rdev->wiphy,
11627 NL80211_EXT_FEATURE_VHT_IBSS))
11628 return -EINVAL;
11629 break;
11630 case NL80211_CHAN_WIDTH_320:
11631 return -EINVAL;
11632 default:
11633 return -EINVAL;
11636 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
11637 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
11639 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
11640 u8 *rates =
11641 nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11642 int n_rates =
11643 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
11644 struct ieee80211_supported_band *sband =
11645 wiphy->bands[ibss.chandef.chan->band];
11647 err = ieee80211_get_ratemask(sband, rates, n_rates,
11648 &ibss.basic_rates);
11649 if (err)
11650 return err;
11653 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
11654 memcpy(&ibss.ht_capa_mask,
11655 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
11656 sizeof(ibss.ht_capa_mask));
11658 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
11659 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
11660 return -EINVAL;
11661 memcpy(&ibss.ht_capa,
11662 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
11663 sizeof(ibss.ht_capa));
11666 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
11667 !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate,
11668 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
11669 return -EINVAL;
11671 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
11672 bool no_ht = false;
11674 connkeys = nl80211_parse_connkeys(rdev, info, &no_ht);
11675 if (IS_ERR(connkeys))
11676 return PTR_ERR(connkeys);
11678 if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) &&
11679 no_ht) {
11680 kfree_sensitive(connkeys);
11681 return -EINVAL;
11685 ibss.control_port =
11686 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]);
11688 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
11689 int r = validate_pae_over_nl80211(rdev, info);
11691 if (r < 0) {
11692 kfree_sensitive(connkeys);
11693 return r;
11696 ibss.control_port_over_nl80211 = true;
11699 ibss.userspace_handles_dfs =
11700 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
11702 err = __cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
11703 if (err)
11704 kfree_sensitive(connkeys);
11705 else if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
11706 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
11708 return err;
11711 static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
11713 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11714 struct net_device *dev = info->user_ptr[1];
11716 if (!rdev->ops->leave_ibss)
11717 return -EOPNOTSUPP;
11719 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
11720 return -EOPNOTSUPP;
11722 return cfg80211_leave_ibss(rdev, dev, false);
11725 static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info)
11727 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11728 struct net_device *dev = info->user_ptr[1];
11729 int mcast_rate[NUM_NL80211_BANDS];
11730 u32 nla_rate;
11732 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC &&
11733 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT &&
11734 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_OCB)
11735 return -EOPNOTSUPP;
11737 if (!rdev->ops->set_mcast_rate)
11738 return -EOPNOTSUPP;
11740 memset(mcast_rate, 0, sizeof(mcast_rate));
11742 if (!info->attrs[NL80211_ATTR_MCAST_RATE])
11743 return -EINVAL;
11745 nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]);
11746 if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate))
11747 return -EINVAL;
11749 return rdev_set_mcast_rate(rdev, dev, mcast_rate);
11752 static struct sk_buff *
11753 __cfg80211_alloc_vendor_skb(struct cfg80211_registered_device *rdev,
11754 struct wireless_dev *wdev, int approxlen,
11755 u32 portid, u32 seq, enum nl80211_commands cmd,
11756 enum nl80211_attrs attr,
11757 const struct nl80211_vendor_cmd_info *info,
11758 gfp_t gfp)
11760 struct sk_buff *skb;
11761 void *hdr;
11762 struct nlattr *data;
11764 skb = nlmsg_new(approxlen + 100, gfp);
11765 if (!skb)
11766 return NULL;
11768 hdr = nl80211hdr_put(skb, portid, seq, 0, cmd);
11769 if (!hdr) {
11770 kfree_skb(skb);
11771 return NULL;
11774 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
11775 goto nla_put_failure;
11777 if (info) {
11778 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_ID,
11779 info->vendor_id))
11780 goto nla_put_failure;
11781 if (nla_put_u32(skb, NL80211_ATTR_VENDOR_SUBCMD,
11782 info->subcmd))
11783 goto nla_put_failure;
11786 if (wdev) {
11787 if (nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
11788 wdev_id(wdev), NL80211_ATTR_PAD))
11789 goto nla_put_failure;
11790 if (wdev->netdev &&
11791 nla_put_u32(skb, NL80211_ATTR_IFINDEX,
11792 wdev->netdev->ifindex))
11793 goto nla_put_failure;
11796 data = nla_nest_start_noflag(skb, attr);
11797 if (!data)
11798 goto nla_put_failure;
11800 ((void **)skb->cb)[0] = rdev;
11801 ((void **)skb->cb)[1] = hdr;
11802 ((void **)skb->cb)[2] = data;
11804 return skb;
11806 nla_put_failure:
11807 kfree_skb(skb);
11808 return NULL;
11811 struct sk_buff *__cfg80211_alloc_event_skb(struct wiphy *wiphy,
11812 struct wireless_dev *wdev,
11813 enum nl80211_commands cmd,
11814 enum nl80211_attrs attr,
11815 unsigned int portid,
11816 int vendor_event_idx,
11817 int approxlen, gfp_t gfp)
11819 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
11820 const struct nl80211_vendor_cmd_info *info;
11822 switch (cmd) {
11823 case NL80211_CMD_TESTMODE:
11824 if (WARN_ON(vendor_event_idx != -1))
11825 return NULL;
11826 info = NULL;
11827 break;
11828 case NL80211_CMD_VENDOR:
11829 if (WARN_ON(vendor_event_idx < 0 ||
11830 vendor_event_idx >= wiphy->n_vendor_events))
11831 return NULL;
11832 info = &wiphy->vendor_events[vendor_event_idx];
11833 break;
11834 default:
11835 WARN_ON(1);
11836 return NULL;
11839 return __cfg80211_alloc_vendor_skb(rdev, wdev, approxlen, portid, 0,
11840 cmd, attr, info, gfp);
11842 EXPORT_SYMBOL(__cfg80211_alloc_event_skb);
11844 void __cfg80211_send_event_skb(struct sk_buff *skb, gfp_t gfp)
11846 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
11847 void *hdr = ((void **)skb->cb)[1];
11848 struct nlmsghdr *nlhdr = nlmsg_hdr(skb);
11849 struct nlattr *data = ((void **)skb->cb)[2];
11850 enum nl80211_multicast_groups mcgrp = NL80211_MCGRP_TESTMODE;
11852 /* clear CB data for netlink core to own from now on */
11853 memset(skb->cb, 0, sizeof(skb->cb));
11855 nla_nest_end(skb, data);
11856 genlmsg_end(skb, hdr);
11858 if (nlhdr->nlmsg_pid) {
11859 genlmsg_unicast(wiphy_net(&rdev->wiphy), skb,
11860 nlhdr->nlmsg_pid);
11861 } else {
11862 if (data->nla_type == NL80211_ATTR_VENDOR_DATA)
11863 mcgrp = NL80211_MCGRP_VENDOR;
11865 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
11866 skb, 0, mcgrp, gfp);
11869 EXPORT_SYMBOL(__cfg80211_send_event_skb);
11871 #ifdef CONFIG_NL80211_TESTMODE
11872 static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
11874 struct cfg80211_registered_device *rdev = info->user_ptr[0];
11875 struct wireless_dev *wdev;
11876 int err;
11878 lockdep_assert_held(&rdev->wiphy.mtx);
11880 wdev = __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
11881 info->attrs);
11883 if (!rdev->ops->testmode_cmd)
11884 return -EOPNOTSUPP;
11886 if (IS_ERR(wdev)) {
11887 err = PTR_ERR(wdev);
11888 if (err != -EINVAL)
11889 return err;
11890 wdev = NULL;
11891 } else if (wdev->wiphy != &rdev->wiphy) {
11892 return -EINVAL;
11895 if (!info->attrs[NL80211_ATTR_TESTDATA])
11896 return -EINVAL;
11898 rdev->cur_cmd_info = info;
11899 err = rdev_testmode_cmd(rdev, wdev,
11900 nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
11901 nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
11902 rdev->cur_cmd_info = NULL;
11904 return err;
11907 static int nl80211_testmode_dump(struct sk_buff *skb,
11908 struct netlink_callback *cb)
11910 struct cfg80211_registered_device *rdev;
11911 struct nlattr **attrbuf = NULL;
11912 int err;
11913 long phy_idx;
11914 void *data = NULL;
11915 int data_len = 0;
11917 rtnl_lock();
11919 if (cb->args[0]) {
11921 * 0 is a valid index, but not valid for args[0],
11922 * so we need to offset by 1.
11924 phy_idx = cb->args[0] - 1;
11926 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
11927 if (!rdev) {
11928 err = -ENOENT;
11929 goto out_err;
11931 } else {
11932 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf),
11933 GFP_KERNEL);
11934 if (!attrbuf) {
11935 err = -ENOMEM;
11936 goto out_err;
11939 err = nlmsg_parse_deprecated(cb->nlh,
11940 GENL_HDRLEN + nl80211_fam.hdrsize,
11941 attrbuf, nl80211_fam.maxattr,
11942 nl80211_policy, NULL);
11943 if (err)
11944 goto out_err;
11946 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
11947 if (IS_ERR(rdev)) {
11948 err = PTR_ERR(rdev);
11949 goto out_err;
11951 phy_idx = rdev->wiphy_idx;
11953 if (attrbuf[NL80211_ATTR_TESTDATA])
11954 cb->args[1] = (long)attrbuf[NL80211_ATTR_TESTDATA];
11957 if (cb->args[1]) {
11958 data = nla_data((void *)cb->args[1]);
11959 data_len = nla_len((void *)cb->args[1]);
11962 if (!rdev->ops->testmode_dump) {
11963 err = -EOPNOTSUPP;
11964 goto out_err;
11967 while (1) {
11968 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
11969 cb->nlh->nlmsg_seq, NLM_F_MULTI,
11970 NL80211_CMD_TESTMODE);
11971 struct nlattr *tmdata;
11973 if (!hdr)
11974 break;
11976 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) {
11977 genlmsg_cancel(skb, hdr);
11978 break;
11981 tmdata = nla_nest_start_noflag(skb, NL80211_ATTR_TESTDATA);
11982 if (!tmdata) {
11983 genlmsg_cancel(skb, hdr);
11984 break;
11986 err = rdev_testmode_dump(rdev, skb, cb, data, data_len);
11987 nla_nest_end(skb, tmdata);
11989 if (err == -ENOBUFS || err == -ENOENT) {
11990 genlmsg_cancel(skb, hdr);
11991 break;
11992 } else if (err) {
11993 genlmsg_cancel(skb, hdr);
11994 goto out_err;
11997 genlmsg_end(skb, hdr);
12000 err = skb->len;
12001 /* see above */
12002 cb->args[0] = phy_idx + 1;
12003 out_err:
12004 kfree(attrbuf);
12005 rtnl_unlock();
12006 return err;
12008 #endif
12010 static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
12012 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12013 struct net_device *dev = info->user_ptr[1];
12014 struct cfg80211_connect_params connect;
12015 struct wiphy *wiphy;
12016 struct cfg80211_cached_keys *connkeys = NULL;
12017 u32 freq = 0;
12018 int err;
12020 memset(&connect, 0, sizeof(connect));
12022 if (!info->attrs[NL80211_ATTR_SSID] ||
12023 !nla_len(info->attrs[NL80211_ATTR_SSID]))
12024 return -EINVAL;
12026 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
12027 connect.auth_type =
12028 nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
12029 if (!nl80211_valid_auth_type(rdev, connect.auth_type,
12030 NL80211_CMD_CONNECT))
12031 return -EINVAL;
12032 } else
12033 connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
12035 connect.privacy = info->attrs[NL80211_ATTR_PRIVACY];
12037 if (info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS] &&
12038 !wiphy_ext_feature_isset(&rdev->wiphy,
12039 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
12040 return -EINVAL;
12041 connect.want_1x = info->attrs[NL80211_ATTR_WANT_1X_4WAY_HS];
12043 err = nl80211_crypto_settings(rdev, info, &connect.crypto,
12044 NL80211_MAX_NR_CIPHER_SUITES);
12045 if (err)
12046 return err;
12048 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
12049 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
12050 return -EOPNOTSUPP;
12052 wiphy = &rdev->wiphy;
12054 connect.bg_scan_period = -1;
12055 if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] &&
12056 (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) {
12057 connect.bg_scan_period =
12058 nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]);
12061 if (info->attrs[NL80211_ATTR_MAC])
12062 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
12063 else if (info->attrs[NL80211_ATTR_MAC_HINT])
12064 connect.bssid_hint =
12065 nla_data(info->attrs[NL80211_ATTR_MAC_HINT]);
12066 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
12067 connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
12069 if (info->attrs[NL80211_ATTR_IE]) {
12070 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
12071 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
12074 if (info->attrs[NL80211_ATTR_USE_MFP]) {
12075 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
12076 if (connect.mfp == NL80211_MFP_OPTIONAL &&
12077 !wiphy_ext_feature_isset(&rdev->wiphy,
12078 NL80211_EXT_FEATURE_MFP_OPTIONAL))
12079 return -EOPNOTSUPP;
12080 } else {
12081 connect.mfp = NL80211_MFP_NO;
12084 if (info->attrs[NL80211_ATTR_PREV_BSSID])
12085 connect.prev_bssid =
12086 nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]);
12088 if (info->attrs[NL80211_ATTR_WIPHY_FREQ])
12089 freq = MHZ_TO_KHZ(nla_get_u32(
12090 info->attrs[NL80211_ATTR_WIPHY_FREQ]));
12091 if (info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET])
12092 freq +=
12093 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_OFFSET]);
12095 if (freq) {
12096 connect.channel = nl80211_get_valid_chan(wiphy, freq);
12097 if (!connect.channel)
12098 return -EINVAL;
12099 } else if (info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]) {
12100 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ_HINT]);
12101 freq = MHZ_TO_KHZ(freq);
12102 connect.channel_hint = nl80211_get_valid_chan(wiphy, freq);
12103 if (!connect.channel_hint)
12104 return -EINVAL;
12107 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
12108 connect.edmg.channels =
12109 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
12111 if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
12112 connect.edmg.bw_config =
12113 nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
12116 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
12117 connkeys = nl80211_parse_connkeys(rdev, info, NULL);
12118 if (IS_ERR(connkeys))
12119 return PTR_ERR(connkeys);
12122 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT]))
12123 connect.flags |= ASSOC_REQ_DISABLE_HT;
12125 if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK])
12126 memcpy(&connect.ht_capa_mask,
12127 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]),
12128 sizeof(connect.ht_capa_mask));
12130 if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) {
12131 if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) {
12132 kfree_sensitive(connkeys);
12133 return -EINVAL;
12135 memcpy(&connect.ht_capa,
12136 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]),
12137 sizeof(connect.ht_capa));
12140 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_VHT]))
12141 connect.flags |= ASSOC_REQ_DISABLE_VHT;
12143 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HE]))
12144 connect.flags |= ASSOC_REQ_DISABLE_HE;
12146 if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_EHT]))
12147 connect.flags |= ASSOC_REQ_DISABLE_EHT;
12149 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK])
12150 memcpy(&connect.vht_capa_mask,
12151 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]),
12152 sizeof(connect.vht_capa_mask));
12154 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) {
12155 if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) {
12156 kfree_sensitive(connkeys);
12157 return -EINVAL;
12159 memcpy(&connect.vht_capa,
12160 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]),
12161 sizeof(connect.vht_capa));
12164 if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) {
12165 if (!((rdev->wiphy.features &
12166 NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) &&
12167 (rdev->wiphy.features & NL80211_FEATURE_QUIET)) &&
12168 !wiphy_ext_feature_isset(&rdev->wiphy,
12169 NL80211_EXT_FEATURE_RRM)) {
12170 kfree_sensitive(connkeys);
12171 return -EINVAL;
12173 connect.flags |= ASSOC_REQ_USE_RRM;
12176 connect.pbss = nla_get_flag(info->attrs[NL80211_ATTR_PBSS]);
12177 if (connect.pbss && !rdev->wiphy.bands[NL80211_BAND_60GHZ]) {
12178 kfree_sensitive(connkeys);
12179 return -EOPNOTSUPP;
12182 if (info->attrs[NL80211_ATTR_BSS_SELECT]) {
12183 /* bss selection makes no sense if bssid is set */
12184 if (connect.bssid) {
12185 kfree_sensitive(connkeys);
12186 return -EINVAL;
12189 err = parse_bss_select(info->attrs[NL80211_ATTR_BSS_SELECT],
12190 wiphy, &connect.bss_select);
12191 if (err) {
12192 kfree_sensitive(connkeys);
12193 return err;
12197 if (wiphy_ext_feature_isset(&rdev->wiphy,
12198 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD) &&
12199 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
12200 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
12201 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
12202 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
12203 connect.fils_erp_username =
12204 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
12205 connect.fils_erp_username_len =
12206 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
12207 connect.fils_erp_realm =
12208 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
12209 connect.fils_erp_realm_len =
12210 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
12211 connect.fils_erp_next_seq_num =
12212 nla_get_u16(
12213 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
12214 connect.fils_erp_rrk =
12215 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
12216 connect.fils_erp_rrk_len =
12217 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
12218 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
12219 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
12220 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
12221 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
12222 kfree_sensitive(connkeys);
12223 return -EINVAL;
12226 if (nla_get_flag(info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])) {
12227 if (!info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
12228 kfree_sensitive(connkeys);
12229 GENL_SET_ERR_MSG(info,
12230 "external auth requires connection ownership");
12231 return -EINVAL;
12233 connect.flags |= CONNECT_REQ_EXTERNAL_AUTH_SUPPORT;
12236 if (nla_get_flag(info->attrs[NL80211_ATTR_MLO_SUPPORT]))
12237 connect.flags |= CONNECT_REQ_MLO_SUPPORT;
12239 err = cfg80211_connect(rdev, dev, &connect, connkeys,
12240 connect.prev_bssid);
12241 if (err)
12242 kfree_sensitive(connkeys);
12244 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER]) {
12245 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
12246 if (connect.bssid)
12247 memcpy(dev->ieee80211_ptr->disconnect_bssid,
12248 connect.bssid, ETH_ALEN);
12249 else
12250 eth_zero_addr(dev->ieee80211_ptr->disconnect_bssid);
12253 return err;
12256 static int nl80211_update_connect_params(struct sk_buff *skb,
12257 struct genl_info *info)
12259 struct cfg80211_connect_params connect = {};
12260 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12261 struct net_device *dev = info->user_ptr[1];
12262 struct wireless_dev *wdev = dev->ieee80211_ptr;
12263 bool fils_sk_offload;
12264 u32 auth_type;
12265 u32 changed = 0;
12267 if (!rdev->ops->update_connect_params)
12268 return -EOPNOTSUPP;
12270 if (info->attrs[NL80211_ATTR_IE]) {
12271 connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
12272 connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
12273 changed |= UPDATE_ASSOC_IES;
12276 fils_sk_offload = wiphy_ext_feature_isset(&rdev->wiphy,
12277 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
12280 * when driver supports fils-sk offload all attributes must be
12281 * provided. So the else covers "fils-sk-not-all" and
12282 * "no-fils-sk-any".
12284 if (fils_sk_offload &&
12285 info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] &&
12286 info->attrs[NL80211_ATTR_FILS_ERP_REALM] &&
12287 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] &&
12288 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
12289 connect.fils_erp_username =
12290 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
12291 connect.fils_erp_username_len =
12292 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_USERNAME]);
12293 connect.fils_erp_realm =
12294 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
12295 connect.fils_erp_realm_len =
12296 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_REALM]);
12297 connect.fils_erp_next_seq_num =
12298 nla_get_u16(
12299 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM]);
12300 connect.fils_erp_rrk =
12301 nla_data(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
12302 connect.fils_erp_rrk_len =
12303 nla_len(info->attrs[NL80211_ATTR_FILS_ERP_RRK]);
12304 changed |= UPDATE_FILS_ERP_INFO;
12305 } else if (info->attrs[NL80211_ATTR_FILS_ERP_USERNAME] ||
12306 info->attrs[NL80211_ATTR_FILS_ERP_REALM] ||
12307 info->attrs[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] ||
12308 info->attrs[NL80211_ATTR_FILS_ERP_RRK]) {
12309 return -EINVAL;
12312 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
12313 auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
12314 if (!nl80211_valid_auth_type(rdev, auth_type,
12315 NL80211_CMD_CONNECT))
12316 return -EINVAL;
12318 if (auth_type == NL80211_AUTHTYPE_FILS_SK &&
12319 fils_sk_offload && !(changed & UPDATE_FILS_ERP_INFO))
12320 return -EINVAL;
12322 connect.auth_type = auth_type;
12323 changed |= UPDATE_AUTH_TYPE;
12326 if (!wdev->connected)
12327 return -ENOLINK;
12329 return rdev_update_connect_params(rdev, dev, &connect, changed);
12332 static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
12334 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12335 struct net_device *dev = info->user_ptr[1];
12336 u16 reason;
12338 if (dev->ieee80211_ptr->conn_owner_nlportid &&
12339 dev->ieee80211_ptr->conn_owner_nlportid != info->snd_portid)
12340 return -EPERM;
12342 reason = nla_get_u16_default(info->attrs[NL80211_ATTR_REASON_CODE],
12343 WLAN_REASON_DEAUTH_LEAVING);
12345 if (reason == 0)
12346 return -EINVAL;
12348 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
12349 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
12350 return -EOPNOTSUPP;
12352 return cfg80211_disconnect(rdev, dev, reason, true);
12355 static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
12357 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12358 struct net *net;
12359 int err;
12361 if (info->attrs[NL80211_ATTR_PID]) {
12362 u32 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
12364 net = get_net_ns_by_pid(pid);
12365 } else if (info->attrs[NL80211_ATTR_NETNS_FD]) {
12366 u32 fd = nla_get_u32(info->attrs[NL80211_ATTR_NETNS_FD]);
12368 net = get_net_ns_by_fd(fd);
12369 } else {
12370 return -EINVAL;
12373 if (IS_ERR(net))
12374 return PTR_ERR(net);
12376 err = 0;
12378 /* check if anything to do */
12379 if (!net_eq(wiphy_net(&rdev->wiphy), net))
12380 err = cfg80211_switch_netns(rdev, net);
12382 put_net(net);
12383 return err;
12386 static int nl80211_set_pmksa(struct sk_buff *skb, struct genl_info *info)
12388 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12389 struct net_device *dev = info->user_ptr[1];
12390 struct cfg80211_pmksa pmksa;
12391 bool ap_pmksa_caching_support = false;
12393 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
12395 ap_pmksa_caching_support = wiphy_ext_feature_isset(&rdev->wiphy,
12396 NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
12398 if (!info->attrs[NL80211_ATTR_PMKID])
12399 return -EINVAL;
12401 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
12403 if (info->attrs[NL80211_ATTR_MAC]) {
12404 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
12405 } else if (info->attrs[NL80211_ATTR_SSID] &&
12406 info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
12407 info->attrs[NL80211_ATTR_PMK]) {
12408 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
12409 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
12410 pmksa.cache_id = nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
12411 } else {
12412 return -EINVAL;
12415 if (info->attrs[NL80211_ATTR_PMK]) {
12416 pmksa.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
12417 pmksa.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
12420 if (info->attrs[NL80211_ATTR_PMK_LIFETIME])
12421 pmksa.pmk_lifetime =
12422 nla_get_u32(info->attrs[NL80211_ATTR_PMK_LIFETIME]);
12424 if (info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD])
12425 pmksa.pmk_reauth_threshold =
12426 nla_get_u8(info->attrs[NL80211_ATTR_PMK_REAUTH_THRESHOLD]);
12428 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
12429 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
12430 !((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
12431 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
12432 ap_pmksa_caching_support))
12433 return -EOPNOTSUPP;
12435 if (!rdev->ops->set_pmksa)
12436 return -EOPNOTSUPP;
12438 return rdev_set_pmksa(rdev, dev, &pmksa);
12441 static int nl80211_del_pmksa(struct sk_buff *skb, struct genl_info *info)
12443 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12444 struct net_device *dev = info->user_ptr[1];
12445 struct cfg80211_pmksa pmksa;
12446 bool sae_offload_support = false;
12447 bool owe_offload_support = false;
12448 bool ap_pmksa_caching_support = false;
12450 memset(&pmksa, 0, sizeof(struct cfg80211_pmksa));
12452 sae_offload_support = wiphy_ext_feature_isset(&rdev->wiphy,
12453 NL80211_EXT_FEATURE_SAE_OFFLOAD);
12454 owe_offload_support = wiphy_ext_feature_isset(&rdev->wiphy,
12455 NL80211_EXT_FEATURE_OWE_OFFLOAD);
12456 ap_pmksa_caching_support = wiphy_ext_feature_isset(&rdev->wiphy,
12457 NL80211_EXT_FEATURE_AP_PMKSA_CACHING);
12459 if (info->attrs[NL80211_ATTR_PMKID])
12460 pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
12462 if (info->attrs[NL80211_ATTR_MAC]) {
12463 pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
12464 } else if (info->attrs[NL80211_ATTR_SSID]) {
12465 /* SSID based pmksa flush supported only for FILS,
12466 * OWE/SAE OFFLOAD cases
12468 if (info->attrs[NL80211_ATTR_FILS_CACHE_ID] &&
12469 info->attrs[NL80211_ATTR_PMK]) {
12470 pmksa.cache_id = nla_data(info->attrs[NL80211_ATTR_FILS_CACHE_ID]);
12471 } else if (!sae_offload_support && !owe_offload_support) {
12472 return -EINVAL;
12474 pmksa.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
12475 pmksa.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
12476 } else {
12477 return -EINVAL;
12480 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
12481 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT &&
12482 !((dev->ieee80211_ptr->iftype == NL80211_IFTYPE_AP ||
12483 dev->ieee80211_ptr->iftype == NL80211_IFTYPE_P2P_GO) &&
12484 ap_pmksa_caching_support))
12485 return -EOPNOTSUPP;
12487 if (!rdev->ops->del_pmksa)
12488 return -EOPNOTSUPP;
12490 return rdev_del_pmksa(rdev, dev, &pmksa);
12493 static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
12495 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12496 struct net_device *dev = info->user_ptr[1];
12498 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION &&
12499 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT)
12500 return -EOPNOTSUPP;
12502 if (!rdev->ops->flush_pmksa)
12503 return -EOPNOTSUPP;
12505 return rdev_flush_pmksa(rdev, dev);
12508 static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
12510 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12511 struct net_device *dev = info->user_ptr[1];
12512 u8 action_code, dialog_token;
12513 u32 peer_capability = 0;
12514 u16 status_code;
12515 u8 *peer;
12516 int link_id;
12517 bool initiator;
12519 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
12520 !rdev->ops->tdls_mgmt)
12521 return -EOPNOTSUPP;
12523 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
12524 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
12525 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
12526 !info->attrs[NL80211_ATTR_IE] ||
12527 !info->attrs[NL80211_ATTR_MAC])
12528 return -EINVAL;
12530 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12531 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
12532 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
12533 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
12534 initiator = nla_get_flag(info->attrs[NL80211_ATTR_TDLS_INITIATOR]);
12535 if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
12536 peer_capability =
12537 nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
12538 link_id = nl80211_link_id_or_invalid(info->attrs);
12540 return rdev_tdls_mgmt(rdev, dev, peer, link_id, action_code,
12541 dialog_token, status_code, peer_capability,
12542 initiator,
12543 nla_data(info->attrs[NL80211_ATTR_IE]),
12544 nla_len(info->attrs[NL80211_ATTR_IE]));
12547 static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
12549 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12550 struct net_device *dev = info->user_ptr[1];
12551 enum nl80211_tdls_operation operation;
12552 u8 *peer;
12554 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
12555 !rdev->ops->tdls_oper)
12556 return -EOPNOTSUPP;
12558 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
12559 !info->attrs[NL80211_ATTR_MAC])
12560 return -EINVAL;
12562 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
12563 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
12565 return rdev_tdls_oper(rdev, dev, peer, operation);
12568 static int nl80211_remain_on_channel(struct sk_buff *skb,
12569 struct genl_info *info)
12571 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12572 unsigned int link_id = nl80211_link_id(info->attrs);
12573 struct wireless_dev *wdev = info->user_ptr[1];
12574 struct cfg80211_chan_def chandef;
12575 struct sk_buff *msg;
12576 void *hdr;
12577 u64 cookie;
12578 u32 duration;
12579 int err;
12581 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
12582 !info->attrs[NL80211_ATTR_DURATION])
12583 return -EINVAL;
12585 duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
12587 if (!rdev->ops->remain_on_channel ||
12588 !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL))
12589 return -EOPNOTSUPP;
12592 * We should be on that channel for at least a minimum amount of
12593 * time (10ms) but no longer than the driver supports.
12595 if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
12596 duration > rdev->wiphy.max_remain_on_channel_duration)
12597 return -EINVAL;
12599 err = nl80211_parse_chandef(rdev, info, &chandef);
12600 if (err)
12601 return err;
12603 if (!cfg80211_off_channel_oper_allowed(wdev, chandef.chan)) {
12604 const struct cfg80211_chan_def *oper_chandef, *compat_chandef;
12606 oper_chandef = wdev_chandef(wdev, link_id);
12608 if (WARN_ON(!oper_chandef)) {
12609 /* cannot happen since we must beacon to get here */
12610 WARN_ON(1);
12611 return -EBUSY;
12614 /* note: returns first one if identical chandefs */
12615 compat_chandef = cfg80211_chandef_compatible(&chandef,
12616 oper_chandef);
12618 if (compat_chandef != &chandef)
12619 return -EBUSY;
12622 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12623 if (!msg)
12624 return -ENOMEM;
12626 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12627 NL80211_CMD_REMAIN_ON_CHANNEL);
12628 if (!hdr) {
12629 err = -ENOBUFS;
12630 goto free_msg;
12633 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
12634 duration, &cookie);
12636 if (err)
12637 goto free_msg;
12639 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12640 NL80211_ATTR_PAD))
12641 goto nla_put_failure;
12643 genlmsg_end(msg, hdr);
12645 return genlmsg_reply(msg, info);
12647 nla_put_failure:
12648 err = -ENOBUFS;
12649 free_msg:
12650 nlmsg_free(msg);
12651 return err;
12654 static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
12655 struct genl_info *info)
12657 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12658 struct wireless_dev *wdev = info->user_ptr[1];
12659 u64 cookie;
12661 if (!info->attrs[NL80211_ATTR_COOKIE])
12662 return -EINVAL;
12664 if (!rdev->ops->cancel_remain_on_channel)
12665 return -EOPNOTSUPP;
12667 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
12669 return rdev_cancel_remain_on_channel(rdev, wdev, cookie);
12672 static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
12673 struct genl_info *info)
12675 struct cfg80211_bitrate_mask mask;
12676 unsigned int link_id = nl80211_link_id(info->attrs);
12677 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12678 struct net_device *dev = info->user_ptr[1];
12679 int err;
12681 if (!rdev->ops->set_bitrate_mask)
12682 return -EOPNOTSUPP;
12684 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
12685 NL80211_ATTR_TX_RATES, &mask,
12686 dev, true, link_id);
12687 if (err)
12688 return err;
12690 return rdev_set_bitrate_mask(rdev, dev, link_id, NULL, &mask);
12693 static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info)
12695 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12696 struct wireless_dev *wdev = info->user_ptr[1];
12697 u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION;
12699 if (!info->attrs[NL80211_ATTR_FRAME_MATCH])
12700 return -EINVAL;
12702 if (info->attrs[NL80211_ATTR_FRAME_TYPE])
12703 frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]);
12705 switch (wdev->iftype) {
12706 case NL80211_IFTYPE_STATION:
12707 case NL80211_IFTYPE_ADHOC:
12708 case NL80211_IFTYPE_P2P_CLIENT:
12709 case NL80211_IFTYPE_AP:
12710 case NL80211_IFTYPE_AP_VLAN:
12711 case NL80211_IFTYPE_MESH_POINT:
12712 case NL80211_IFTYPE_P2P_GO:
12713 case NL80211_IFTYPE_P2P_DEVICE:
12714 break;
12715 case NL80211_IFTYPE_NAN:
12716 if (!wiphy_ext_feature_isset(wdev->wiphy,
12717 NL80211_EXT_FEATURE_SECURE_NAN))
12718 return -EOPNOTSUPP;
12719 break;
12720 default:
12721 return -EOPNOTSUPP;
12724 /* not much point in registering if we can't reply */
12725 if (!rdev->ops->mgmt_tx)
12726 return -EOPNOTSUPP;
12728 if (info->attrs[NL80211_ATTR_RECEIVE_MULTICAST] &&
12729 !wiphy_ext_feature_isset(&rdev->wiphy,
12730 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS)) {
12731 GENL_SET_ERR_MSG(info,
12732 "multicast RX registrations are not supported");
12733 return -EOPNOTSUPP;
12736 return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type,
12737 nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]),
12738 nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH]),
12739 info->attrs[NL80211_ATTR_RECEIVE_MULTICAST],
12740 info->extack);
12743 static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
12745 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12746 struct wireless_dev *wdev = info->user_ptr[1];
12747 struct cfg80211_chan_def chandef;
12748 int err;
12749 void *hdr = NULL;
12750 u64 cookie;
12751 struct sk_buff *msg = NULL;
12752 struct cfg80211_mgmt_tx_params params = {
12753 .dont_wait_for_ack =
12754 info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK],
12757 if (!info->attrs[NL80211_ATTR_FRAME])
12758 return -EINVAL;
12760 if (!rdev->ops->mgmt_tx)
12761 return -EOPNOTSUPP;
12763 switch (wdev->iftype) {
12764 case NL80211_IFTYPE_P2P_DEVICE:
12765 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
12766 return -EINVAL;
12767 break;
12768 case NL80211_IFTYPE_STATION:
12769 case NL80211_IFTYPE_ADHOC:
12770 case NL80211_IFTYPE_P2P_CLIENT:
12771 case NL80211_IFTYPE_AP:
12772 case NL80211_IFTYPE_AP_VLAN:
12773 case NL80211_IFTYPE_MESH_POINT:
12774 case NL80211_IFTYPE_P2P_GO:
12775 break;
12776 case NL80211_IFTYPE_NAN:
12777 if (!wiphy_ext_feature_isset(wdev->wiphy,
12778 NL80211_EXT_FEATURE_SECURE_NAN))
12779 return -EOPNOTSUPP;
12780 break;
12781 default:
12782 return -EOPNOTSUPP;
12785 if (info->attrs[NL80211_ATTR_DURATION]) {
12786 if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
12787 return -EINVAL;
12788 params.wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]);
12791 * We should wait on the channel for at least a minimum amount
12792 * of time (10ms) but no longer than the driver supports.
12794 if (params.wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME ||
12795 params.wait > rdev->wiphy.max_remain_on_channel_duration)
12796 return -EINVAL;
12799 params.offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
12801 if (params.offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
12802 return -EINVAL;
12804 params.no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
12806 /* get the channel if any has been specified, otherwise pass NULL to
12807 * the driver. The latter will use the current one
12809 chandef.chan = NULL;
12810 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
12811 err = nl80211_parse_chandef(rdev, info, &chandef);
12812 if (err)
12813 return err;
12816 if (!chandef.chan && params.offchan)
12817 return -EINVAL;
12819 if (params.offchan &&
12820 !cfg80211_off_channel_oper_allowed(wdev, chandef.chan))
12821 return -EBUSY;
12823 params.link_id = nl80211_link_id_or_invalid(info->attrs);
12825 * This now races due to the unlock, but we cannot check
12826 * the valid links for the _station_ anyway, so that's up
12827 * to the driver.
12829 if (params.link_id >= 0 &&
12830 !(wdev->valid_links & BIT(params.link_id)))
12831 return -EINVAL;
12833 params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
12834 params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
12836 err = nl80211_parse_counter_offsets(rdev, NULL, params.len, -1,
12837 info->attrs[NL80211_ATTR_CSA_C_OFFSETS_TX],
12838 &params.csa_offsets,
12839 &params.n_csa_offsets);
12840 if (err)
12841 return err;
12843 if (!params.dont_wait_for_ack) {
12844 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12845 if (!msg)
12846 return -ENOMEM;
12848 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12849 NL80211_CMD_FRAME);
12850 if (!hdr) {
12851 err = -ENOBUFS;
12852 goto free_msg;
12856 params.chan = chandef.chan;
12857 err = cfg80211_mlme_mgmt_tx(rdev, wdev, &params, &cookie);
12858 if (err)
12859 goto free_msg;
12861 if (msg) {
12862 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
12863 NL80211_ATTR_PAD))
12864 goto nla_put_failure;
12866 genlmsg_end(msg, hdr);
12867 return genlmsg_reply(msg, info);
12870 return 0;
12872 nla_put_failure:
12873 err = -ENOBUFS;
12874 free_msg:
12875 nlmsg_free(msg);
12876 return err;
12879 static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info)
12881 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12882 struct wireless_dev *wdev = info->user_ptr[1];
12883 u64 cookie;
12885 if (!info->attrs[NL80211_ATTR_COOKIE])
12886 return -EINVAL;
12888 if (!rdev->ops->mgmt_tx_cancel_wait)
12889 return -EOPNOTSUPP;
12891 switch (wdev->iftype) {
12892 case NL80211_IFTYPE_STATION:
12893 case NL80211_IFTYPE_ADHOC:
12894 case NL80211_IFTYPE_P2P_CLIENT:
12895 case NL80211_IFTYPE_AP:
12896 case NL80211_IFTYPE_AP_VLAN:
12897 case NL80211_IFTYPE_P2P_GO:
12898 case NL80211_IFTYPE_P2P_DEVICE:
12899 break;
12900 case NL80211_IFTYPE_NAN:
12901 if (!wiphy_ext_feature_isset(wdev->wiphy,
12902 NL80211_EXT_FEATURE_SECURE_NAN))
12903 return -EOPNOTSUPP;
12904 break;
12905 default:
12906 return -EOPNOTSUPP;
12909 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
12911 return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie);
12914 static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info)
12916 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12917 struct wireless_dev *wdev;
12918 struct net_device *dev = info->user_ptr[1];
12919 u8 ps_state;
12920 bool state;
12921 int err;
12923 if (!info->attrs[NL80211_ATTR_PS_STATE])
12924 return -EINVAL;
12926 ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]);
12928 wdev = dev->ieee80211_ptr;
12930 if (!rdev->ops->set_power_mgmt)
12931 return -EOPNOTSUPP;
12933 state = (ps_state == NL80211_PS_ENABLED) ? true : false;
12935 if (state == wdev->ps)
12936 return 0;
12938 err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout);
12939 if (!err)
12940 wdev->ps = state;
12941 return err;
12944 static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info)
12946 struct cfg80211_registered_device *rdev = info->user_ptr[0];
12947 enum nl80211_ps_state ps_state;
12948 struct wireless_dev *wdev;
12949 struct net_device *dev = info->user_ptr[1];
12950 struct sk_buff *msg;
12951 void *hdr;
12952 int err;
12954 wdev = dev->ieee80211_ptr;
12956 if (!rdev->ops->set_power_mgmt)
12957 return -EOPNOTSUPP;
12959 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12960 if (!msg)
12961 return -ENOMEM;
12963 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
12964 NL80211_CMD_GET_POWER_SAVE);
12965 if (!hdr) {
12966 err = -ENOBUFS;
12967 goto free_msg;
12970 if (wdev->ps)
12971 ps_state = NL80211_PS_ENABLED;
12972 else
12973 ps_state = NL80211_PS_DISABLED;
12975 if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state))
12976 goto nla_put_failure;
12978 genlmsg_end(msg, hdr);
12979 return genlmsg_reply(msg, info);
12981 nla_put_failure:
12982 err = -ENOBUFS;
12983 free_msg:
12984 nlmsg_free(msg);
12985 return err;
12988 static const struct nla_policy
12989 nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = {
12990 [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_BINARY },
12991 [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 },
12992 [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
12993 [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
12994 [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
12995 [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
12996 [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 },
12999 static int nl80211_set_cqm_txe(struct genl_info *info,
13000 u32 rate, u32 pkts, u32 intvl)
13002 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13003 struct net_device *dev = info->user_ptr[1];
13004 struct wireless_dev *wdev = dev->ieee80211_ptr;
13006 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
13007 return -EINVAL;
13009 if (!rdev->ops->set_cqm_txe_config)
13010 return -EOPNOTSUPP;
13012 if (wdev->iftype != NL80211_IFTYPE_STATION &&
13013 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
13014 return -EOPNOTSUPP;
13016 return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl);
13019 static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev,
13020 struct net_device *dev,
13021 struct cfg80211_cqm_config *cqm_config)
13023 struct wireless_dev *wdev = dev->ieee80211_ptr;
13024 s32 last, low, high;
13025 u32 hyst;
13026 int i, n, low_index;
13027 int err;
13030 * Obtain current RSSI value if possible, if not and no RSSI threshold
13031 * event has been received yet, we should receive an event after a
13032 * connection is established and enough beacons received to calculate
13033 * the average.
13035 if (!cqm_config->last_rssi_event_value &&
13036 wdev->links[0].client.current_bss &&
13037 rdev->ops->get_station) {
13038 struct station_info sinfo = {};
13039 u8 *mac_addr;
13041 mac_addr = wdev->links[0].client.current_bss->pub.bssid;
13043 err = rdev_get_station(rdev, dev, mac_addr, &sinfo);
13044 if (err)
13045 return err;
13047 cfg80211_sinfo_release_content(&sinfo);
13048 if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG))
13049 cqm_config->last_rssi_event_value =
13050 (s8) sinfo.rx_beacon_signal_avg;
13053 last = cqm_config->last_rssi_event_value;
13054 hyst = cqm_config->rssi_hyst;
13055 n = cqm_config->n_rssi_thresholds;
13057 for (i = 0; i < n; i++) {
13058 i = array_index_nospec(i, n);
13059 if (last < cqm_config->rssi_thresholds[i])
13060 break;
13063 low_index = i - 1;
13064 if (low_index >= 0) {
13065 low_index = array_index_nospec(low_index, n);
13066 low = cqm_config->rssi_thresholds[low_index] - hyst;
13067 } else {
13068 low = S32_MIN;
13070 if (i < n) {
13071 i = array_index_nospec(i, n);
13072 high = cqm_config->rssi_thresholds[i] + hyst - 1;
13073 } else {
13074 high = S32_MAX;
13077 return rdev_set_cqm_rssi_range_config(rdev, dev, low, high);
13080 static int nl80211_set_cqm_rssi(struct genl_info *info,
13081 const s32 *thresholds, int n_thresholds,
13082 u32 hysteresis)
13084 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13085 struct cfg80211_cqm_config *cqm_config = NULL, *old;
13086 struct net_device *dev = info->user_ptr[1];
13087 struct wireless_dev *wdev = dev->ieee80211_ptr;
13088 s32 prev = S32_MIN;
13089 int i, err;
13091 /* Check all values negative and sorted */
13092 for (i = 0; i < n_thresholds; i++) {
13093 if (thresholds[i] > 0 || thresholds[i] <= prev)
13094 return -EINVAL;
13096 prev = thresholds[i];
13099 if (wdev->iftype != NL80211_IFTYPE_STATION &&
13100 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
13101 return -EOPNOTSUPP;
13103 if (n_thresholds == 1 && thresholds[0] == 0) /* Disabling */
13104 n_thresholds = 0;
13106 old = wiphy_dereference(wdev->wiphy, wdev->cqm_config);
13108 /* if already disabled just succeed */
13109 if (!n_thresholds && !old)
13110 return 0;
13112 if (n_thresholds > 1) {
13113 if (!wiphy_ext_feature_isset(&rdev->wiphy,
13114 NL80211_EXT_FEATURE_CQM_RSSI_LIST) ||
13115 !rdev->ops->set_cqm_rssi_range_config)
13116 return -EOPNOTSUPP;
13117 } else {
13118 if (!rdev->ops->set_cqm_rssi_config)
13119 return -EOPNOTSUPP;
13122 if (n_thresholds) {
13123 cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds,
13124 n_thresholds),
13125 GFP_KERNEL);
13126 if (!cqm_config)
13127 return -ENOMEM;
13129 cqm_config->rssi_hyst = hysteresis;
13130 cqm_config->n_rssi_thresholds = n_thresholds;
13131 memcpy(cqm_config->rssi_thresholds, thresholds,
13132 flex_array_size(cqm_config, rssi_thresholds,
13133 n_thresholds));
13134 cqm_config->use_range_api = n_thresholds > 1 ||
13135 !rdev->ops->set_cqm_rssi_config;
13137 rcu_assign_pointer(wdev->cqm_config, cqm_config);
13139 if (cqm_config->use_range_api)
13140 err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config);
13141 else
13142 err = rdev_set_cqm_rssi_config(rdev, dev,
13143 thresholds[0],
13144 hysteresis);
13145 } else {
13146 RCU_INIT_POINTER(wdev->cqm_config, NULL);
13147 /* if enabled as range also disable via range */
13148 if (old->use_range_api)
13149 err = rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0);
13150 else
13151 err = rdev_set_cqm_rssi_config(rdev, dev, 0, 0);
13154 if (err) {
13155 rcu_assign_pointer(wdev->cqm_config, old);
13156 kfree_rcu(cqm_config, rcu_head);
13157 } else {
13158 kfree_rcu(old, rcu_head);
13161 return err;
13164 static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
13166 struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1];
13167 struct nlattr *cqm;
13168 int err;
13170 cqm = info->attrs[NL80211_ATTR_CQM];
13171 if (!cqm)
13172 return -EINVAL;
13174 err = nla_parse_nested_deprecated(attrs, NL80211_ATTR_CQM_MAX, cqm,
13175 nl80211_attr_cqm_policy,
13176 info->extack);
13177 if (err)
13178 return err;
13180 if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
13181 attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
13182 const s32 *thresholds =
13183 nla_data(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
13184 int len = nla_len(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
13185 u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
13187 if (len % 4)
13188 return -EINVAL;
13190 return nl80211_set_cqm_rssi(info, thresholds, len / 4,
13191 hysteresis);
13194 if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
13195 attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
13196 attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
13197 u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
13198 u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
13199 u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
13201 return nl80211_set_cqm_txe(info, rate, pkts, intvl);
13204 return -EINVAL;
13207 static int nl80211_join_ocb(struct sk_buff *skb, struct genl_info *info)
13209 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13210 struct net_device *dev = info->user_ptr[1];
13211 struct ocb_setup setup = {};
13212 int err;
13214 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
13215 if (err)
13216 return err;
13218 return cfg80211_join_ocb(rdev, dev, &setup);
13221 static int nl80211_leave_ocb(struct sk_buff *skb, struct genl_info *info)
13223 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13224 struct net_device *dev = info->user_ptr[1];
13226 return cfg80211_leave_ocb(rdev, dev);
13229 static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
13231 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13232 struct net_device *dev = info->user_ptr[1];
13233 struct mesh_config cfg;
13234 struct mesh_setup setup;
13235 int err;
13237 /* start with default */
13238 memcpy(&cfg, &default_mesh_config, sizeof(cfg));
13239 memcpy(&setup, &default_mesh_setup, sizeof(setup));
13241 if (info->attrs[NL80211_ATTR_MESH_CONFIG]) {
13242 /* and parse parameters if given */
13243 err = nl80211_parse_mesh_config(info, &cfg, NULL);
13244 if (err)
13245 return err;
13248 if (!info->attrs[NL80211_ATTR_MESH_ID] ||
13249 !nla_len(info->attrs[NL80211_ATTR_MESH_ID]))
13250 return -EINVAL;
13252 setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
13253 setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
13255 if (info->attrs[NL80211_ATTR_MCAST_RATE] &&
13256 !nl80211_parse_mcast_rate(rdev, setup.mcast_rate,
13257 nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE])))
13258 return -EINVAL;
13260 if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
13261 setup.beacon_interval =
13262 nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
13264 err = cfg80211_validate_beacon_int(rdev,
13265 NL80211_IFTYPE_MESH_POINT,
13266 setup.beacon_interval);
13267 if (err)
13268 return err;
13271 if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) {
13272 setup.dtim_period =
13273 nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]);
13274 if (setup.dtim_period < 1 || setup.dtim_period > 100)
13275 return -EINVAL;
13278 if (info->attrs[NL80211_ATTR_MESH_SETUP]) {
13279 /* parse additional setup parameters if given */
13280 err = nl80211_parse_mesh_setup(info, &setup);
13281 if (err)
13282 return err;
13285 if (setup.user_mpm)
13286 cfg.auto_open_plinks = false;
13288 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
13289 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
13290 if (err)
13291 return err;
13292 } else {
13293 /* __cfg80211_join_mesh() will sort it out */
13294 setup.chandef.chan = NULL;
13297 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
13298 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
13299 int n_rates =
13300 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
13301 struct ieee80211_supported_band *sband;
13303 if (!setup.chandef.chan)
13304 return -EINVAL;
13306 sband = rdev->wiphy.bands[setup.chandef.chan->band];
13308 err = ieee80211_get_ratemask(sband, rates, n_rates,
13309 &setup.basic_rates);
13310 if (err)
13311 return err;
13314 if (info->attrs[NL80211_ATTR_TX_RATES]) {
13315 err = nl80211_parse_tx_bitrate_mask(info, info->attrs,
13316 NL80211_ATTR_TX_RATES,
13317 &setup.beacon_rate,
13318 dev, false, 0);
13319 if (err)
13320 return err;
13322 if (!setup.chandef.chan)
13323 return -EINVAL;
13325 err = validate_beacon_tx_rate(rdev, setup.chandef.chan->band,
13326 &setup.beacon_rate);
13327 if (err)
13328 return err;
13331 setup.userspace_handles_dfs =
13332 nla_get_flag(info->attrs[NL80211_ATTR_HANDLE_DFS]);
13334 if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) {
13335 int r = validate_pae_over_nl80211(rdev, info);
13337 if (r < 0)
13338 return r;
13340 setup.control_port_over_nl80211 = true;
13343 err = __cfg80211_join_mesh(rdev, dev, &setup, &cfg);
13344 if (!err && info->attrs[NL80211_ATTR_SOCKET_OWNER])
13345 dev->ieee80211_ptr->conn_owner_nlportid = info->snd_portid;
13347 return err;
13350 static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info)
13352 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13353 struct net_device *dev = info->user_ptr[1];
13355 return cfg80211_leave_mesh(rdev, dev);
13358 #ifdef CONFIG_PM
13359 static int nl80211_send_wowlan_patterns(struct sk_buff *msg,
13360 struct cfg80211_registered_device *rdev)
13362 struct cfg80211_wowlan *wowlan = rdev->wiphy.wowlan_config;
13363 struct nlattr *nl_pats, *nl_pat;
13364 int i, pat_len;
13366 if (!wowlan->n_patterns)
13367 return 0;
13369 nl_pats = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN);
13370 if (!nl_pats)
13371 return -ENOBUFS;
13373 for (i = 0; i < wowlan->n_patterns; i++) {
13374 nl_pat = nla_nest_start_noflag(msg, i + 1);
13375 if (!nl_pat)
13376 return -ENOBUFS;
13377 pat_len = wowlan->patterns[i].pattern_len;
13378 if (nla_put(msg, NL80211_PKTPAT_MASK, DIV_ROUND_UP(pat_len, 8),
13379 wowlan->patterns[i].mask) ||
13380 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
13381 wowlan->patterns[i].pattern) ||
13382 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
13383 wowlan->patterns[i].pkt_offset))
13384 return -ENOBUFS;
13385 nla_nest_end(msg, nl_pat);
13387 nla_nest_end(msg, nl_pats);
13389 return 0;
13392 static int nl80211_send_wowlan_tcp(struct sk_buff *msg,
13393 struct cfg80211_wowlan_tcp *tcp)
13395 struct nlattr *nl_tcp;
13397 if (!tcp)
13398 return 0;
13400 nl_tcp = nla_nest_start_noflag(msg,
13401 NL80211_WOWLAN_TRIG_TCP_CONNECTION);
13402 if (!nl_tcp)
13403 return -ENOBUFS;
13405 if (nla_put_in_addr(msg, NL80211_WOWLAN_TCP_SRC_IPV4, tcp->src) ||
13406 nla_put_in_addr(msg, NL80211_WOWLAN_TCP_DST_IPV4, tcp->dst) ||
13407 nla_put(msg, NL80211_WOWLAN_TCP_DST_MAC, ETH_ALEN, tcp->dst_mac) ||
13408 nla_put_u16(msg, NL80211_WOWLAN_TCP_SRC_PORT, tcp->src_port) ||
13409 nla_put_u16(msg, NL80211_WOWLAN_TCP_DST_PORT, tcp->dst_port) ||
13410 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
13411 tcp->payload_len, tcp->payload) ||
13412 nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
13413 tcp->data_interval) ||
13414 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
13415 tcp->wake_len, tcp->wake_data) ||
13416 nla_put(msg, NL80211_WOWLAN_TCP_WAKE_MASK,
13417 DIV_ROUND_UP(tcp->wake_len, 8), tcp->wake_mask))
13418 return -ENOBUFS;
13420 if (tcp->payload_seq.len &&
13421 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ,
13422 sizeof(tcp->payload_seq), &tcp->payload_seq))
13423 return -ENOBUFS;
13425 if (tcp->payload_tok.len &&
13426 nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
13427 sizeof(tcp->payload_tok) + tcp->tokens_size,
13428 &tcp->payload_tok))
13429 return -ENOBUFS;
13431 nla_nest_end(msg, nl_tcp);
13433 return 0;
13436 static int nl80211_send_wowlan_nd(struct sk_buff *msg,
13437 struct cfg80211_sched_scan_request *req)
13439 struct nlattr *nd, *freqs, *matches, *match, *scan_plans, *scan_plan;
13440 int i;
13442 if (!req)
13443 return 0;
13445 nd = nla_nest_start_noflag(msg, NL80211_WOWLAN_TRIG_NET_DETECT);
13446 if (!nd)
13447 return -ENOBUFS;
13449 if (req->n_scan_plans == 1 &&
13450 nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL,
13451 req->scan_plans[0].interval * 1000))
13452 return -ENOBUFS;
13454 if (nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_DELAY, req->delay))
13455 return -ENOBUFS;
13457 if (req->relative_rssi_set) {
13458 struct nl80211_bss_select_rssi_adjust rssi_adjust;
13460 if (nla_put_s8(msg, NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI,
13461 req->relative_rssi))
13462 return -ENOBUFS;
13464 rssi_adjust.band = req->rssi_adjust.band;
13465 rssi_adjust.delta = req->rssi_adjust.delta;
13466 if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST,
13467 sizeof(rssi_adjust), &rssi_adjust))
13468 return -ENOBUFS;
13471 freqs = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_FREQUENCIES);
13472 if (!freqs)
13473 return -ENOBUFS;
13475 for (i = 0; i < req->n_channels; i++) {
13476 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
13477 return -ENOBUFS;
13480 nla_nest_end(msg, freqs);
13482 if (req->n_match_sets) {
13483 matches = nla_nest_start_noflag(msg,
13484 NL80211_ATTR_SCHED_SCAN_MATCH);
13485 if (!matches)
13486 return -ENOBUFS;
13488 for (i = 0; i < req->n_match_sets; i++) {
13489 match = nla_nest_start_noflag(msg, i);
13490 if (!match)
13491 return -ENOBUFS;
13493 if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID,
13494 req->match_sets[i].ssid.ssid_len,
13495 req->match_sets[i].ssid.ssid))
13496 return -ENOBUFS;
13497 nla_nest_end(msg, match);
13499 nla_nest_end(msg, matches);
13502 scan_plans = nla_nest_start_noflag(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
13503 if (!scan_plans)
13504 return -ENOBUFS;
13506 for (i = 0; i < req->n_scan_plans; i++) {
13507 scan_plan = nla_nest_start_noflag(msg, i + 1);
13508 if (!scan_plan)
13509 return -ENOBUFS;
13511 if (nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL,
13512 req->scan_plans[i].interval) ||
13513 (req->scan_plans[i].iterations &&
13514 nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS,
13515 req->scan_plans[i].iterations)))
13516 return -ENOBUFS;
13517 nla_nest_end(msg, scan_plan);
13519 nla_nest_end(msg, scan_plans);
13521 nla_nest_end(msg, nd);
13523 return 0;
13526 static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
13528 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13529 struct sk_buff *msg;
13530 void *hdr;
13531 u32 size = NLMSG_DEFAULT_SIZE;
13533 if (!rdev->wiphy.wowlan)
13534 return -EOPNOTSUPP;
13536 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
13537 /* adjust size to have room for all the data */
13538 size += rdev->wiphy.wowlan_config->tcp->tokens_size +
13539 rdev->wiphy.wowlan_config->tcp->payload_len +
13540 rdev->wiphy.wowlan_config->tcp->wake_len +
13541 rdev->wiphy.wowlan_config->tcp->wake_len / 8;
13544 msg = nlmsg_new(size, GFP_KERNEL);
13545 if (!msg)
13546 return -ENOMEM;
13548 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
13549 NL80211_CMD_GET_WOWLAN);
13550 if (!hdr)
13551 goto nla_put_failure;
13553 if (rdev->wiphy.wowlan_config) {
13554 struct nlattr *nl_wowlan;
13556 nl_wowlan = nla_nest_start_noflag(msg,
13557 NL80211_ATTR_WOWLAN_TRIGGERS);
13558 if (!nl_wowlan)
13559 goto nla_put_failure;
13561 if ((rdev->wiphy.wowlan_config->any &&
13562 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
13563 (rdev->wiphy.wowlan_config->disconnect &&
13564 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
13565 (rdev->wiphy.wowlan_config->magic_pkt &&
13566 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
13567 (rdev->wiphy.wowlan_config->gtk_rekey_failure &&
13568 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
13569 (rdev->wiphy.wowlan_config->eap_identity_req &&
13570 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
13571 (rdev->wiphy.wowlan_config->four_way_handshake &&
13572 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
13573 (rdev->wiphy.wowlan_config->rfkill_release &&
13574 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
13575 goto nla_put_failure;
13577 if (nl80211_send_wowlan_patterns(msg, rdev))
13578 goto nla_put_failure;
13580 if (nl80211_send_wowlan_tcp(msg,
13581 rdev->wiphy.wowlan_config->tcp))
13582 goto nla_put_failure;
13584 if (nl80211_send_wowlan_nd(
13585 msg,
13586 rdev->wiphy.wowlan_config->nd_config))
13587 goto nla_put_failure;
13589 nla_nest_end(msg, nl_wowlan);
13592 genlmsg_end(msg, hdr);
13593 return genlmsg_reply(msg, info);
13595 nla_put_failure:
13596 nlmsg_free(msg);
13597 return -ENOBUFS;
13600 static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
13601 struct nlattr *attr,
13602 struct cfg80211_wowlan *trig)
13604 struct nlattr *tb[NUM_NL80211_WOWLAN_TCP];
13605 struct cfg80211_wowlan_tcp *cfg;
13606 struct nl80211_wowlan_tcp_data_token *tok = NULL;
13607 struct nl80211_wowlan_tcp_data_seq *seq = NULL;
13608 u32 size;
13609 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
13610 int err, port;
13612 if (!rdev->wiphy.wowlan->tcp)
13613 return -EINVAL;
13615 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TCP, attr,
13616 nl80211_wowlan_tcp_policy, NULL);
13617 if (err)
13618 return err;
13620 if (!tb[NL80211_WOWLAN_TCP_SRC_IPV4] ||
13621 !tb[NL80211_WOWLAN_TCP_DST_IPV4] ||
13622 !tb[NL80211_WOWLAN_TCP_DST_MAC] ||
13623 !tb[NL80211_WOWLAN_TCP_DST_PORT] ||
13624 !tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD] ||
13625 !tb[NL80211_WOWLAN_TCP_DATA_INTERVAL] ||
13626 !tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] ||
13627 !tb[NL80211_WOWLAN_TCP_WAKE_MASK])
13628 return -EINVAL;
13630 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
13631 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
13632 return -EINVAL;
13634 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
13635 rdev->wiphy.wowlan->tcp->data_interval_max ||
13636 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
13637 return -EINVAL;
13639 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
13640 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
13641 return -EINVAL;
13643 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
13644 if (wake_mask_size != DIV_ROUND_UP(wake_size, 8))
13645 return -EINVAL;
13647 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]) {
13648 u32 tokln = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
13650 tok = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN]);
13651 tokens_size = tokln - sizeof(*tok);
13653 if (!tok->len || tokens_size % tok->len)
13654 return -EINVAL;
13655 if (!rdev->wiphy.wowlan->tcp->tok)
13656 return -EINVAL;
13657 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
13658 return -EINVAL;
13659 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
13660 return -EINVAL;
13661 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
13662 return -EINVAL;
13663 if (tok->offset + tok->len > data_size)
13664 return -EINVAL;
13667 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
13668 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
13669 if (!rdev->wiphy.wowlan->tcp->seq)
13670 return -EINVAL;
13671 if (seq->len == 0 || seq->len > 4)
13672 return -EINVAL;
13673 if (seq->len + seq->offset > data_size)
13674 return -EINVAL;
13677 size = sizeof(*cfg);
13678 size += data_size;
13679 size += wake_size + wake_mask_size;
13680 size += tokens_size;
13682 cfg = kzalloc(size, GFP_KERNEL);
13683 if (!cfg)
13684 return -ENOMEM;
13685 cfg->src = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_SRC_IPV4]);
13686 cfg->dst = nla_get_in_addr(tb[NL80211_WOWLAN_TCP_DST_IPV4]);
13687 memcpy(cfg->dst_mac, nla_data(tb[NL80211_WOWLAN_TCP_DST_MAC]),
13688 ETH_ALEN);
13689 port = nla_get_u16_default(tb[NL80211_WOWLAN_TCP_SRC_PORT], 0);
13690 #ifdef CONFIG_INET
13691 /* allocate a socket and port for it and use it */
13692 err = __sock_create(wiphy_net(&rdev->wiphy), PF_INET, SOCK_STREAM,
13693 IPPROTO_TCP, &cfg->sock, 1);
13694 if (err) {
13695 kfree(cfg);
13696 return err;
13698 if (inet_csk_get_port(cfg->sock->sk, port)) {
13699 sock_release(cfg->sock);
13700 kfree(cfg);
13701 return -EADDRINUSE;
13703 cfg->src_port = inet_sk(cfg->sock->sk)->inet_num;
13704 #else
13705 if (!port) {
13706 kfree(cfg);
13707 return -EINVAL;
13709 cfg->src_port = port;
13710 #endif
13712 cfg->dst_port = nla_get_u16(tb[NL80211_WOWLAN_TCP_DST_PORT]);
13713 cfg->payload_len = data_size;
13714 cfg->payload = (u8 *)cfg + sizeof(*cfg) + tokens_size;
13715 memcpy((void *)cfg->payload,
13716 nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]),
13717 data_size);
13718 if (seq)
13719 cfg->payload_seq = *seq;
13720 cfg->data_interval = nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]);
13721 cfg->wake_len = wake_size;
13722 cfg->wake_data = (u8 *)cfg + sizeof(*cfg) + tokens_size + data_size;
13723 memcpy((void *)cfg->wake_data,
13724 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]),
13725 wake_size);
13726 cfg->wake_mask = (u8 *)cfg + sizeof(*cfg) + tokens_size +
13727 data_size + wake_size;
13728 memcpy((void *)cfg->wake_mask,
13729 nla_data(tb[NL80211_WOWLAN_TCP_WAKE_MASK]),
13730 wake_mask_size);
13731 if (tok) {
13732 cfg->tokens_size = tokens_size;
13733 cfg->payload_tok = *tok;
13734 memcpy(cfg->payload_tok.token_stream, tok->token_stream,
13735 tokens_size);
13738 trig->tcp = cfg;
13740 return 0;
13743 static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev,
13744 const struct wiphy_wowlan_support *wowlan,
13745 struct nlattr *attr,
13746 struct cfg80211_wowlan *trig)
13748 struct nlattr **tb;
13749 int err;
13751 tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL);
13752 if (!tb)
13753 return -ENOMEM;
13755 if (!(wowlan->flags & WIPHY_WOWLAN_NET_DETECT)) {
13756 err = -EOPNOTSUPP;
13757 goto out;
13760 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_MAX, attr,
13761 nl80211_policy, NULL);
13762 if (err)
13763 goto out;
13765 trig->nd_config = nl80211_parse_sched_scan(&rdev->wiphy, NULL, tb,
13766 wowlan->max_nd_match_sets);
13767 err = PTR_ERR_OR_ZERO(trig->nd_config);
13768 if (err)
13769 trig->nd_config = NULL;
13771 out:
13772 kfree(tb);
13773 return err;
13776 static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
13778 struct cfg80211_registered_device *rdev = info->user_ptr[0];
13779 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
13780 struct cfg80211_wowlan new_triggers = {};
13781 struct cfg80211_wowlan *ntrig;
13782 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
13783 int err, i;
13784 bool prev_enabled = rdev->wiphy.wowlan_config;
13785 bool regular = false;
13787 if (!wowlan)
13788 return -EOPNOTSUPP;
13790 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
13791 cfg80211_rdev_free_wowlan(rdev);
13792 rdev->wiphy.wowlan_config = NULL;
13793 goto set_wakeup;
13796 err = nla_parse_nested_deprecated(tb, MAX_NL80211_WOWLAN_TRIG,
13797 info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS],
13798 nl80211_wowlan_policy, info->extack);
13799 if (err)
13800 return err;
13802 if (tb[NL80211_WOWLAN_TRIG_ANY]) {
13803 if (!(wowlan->flags & WIPHY_WOWLAN_ANY))
13804 return -EINVAL;
13805 new_triggers.any = true;
13808 if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) {
13809 if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT))
13810 return -EINVAL;
13811 new_triggers.disconnect = true;
13812 regular = true;
13815 if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) {
13816 if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT))
13817 return -EINVAL;
13818 new_triggers.magic_pkt = true;
13819 regular = true;
13822 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
13823 return -EINVAL;
13825 if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
13826 if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
13827 return -EINVAL;
13828 new_triggers.gtk_rekey_failure = true;
13829 regular = true;
13832 if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
13833 if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
13834 return -EINVAL;
13835 new_triggers.eap_identity_req = true;
13836 regular = true;
13839 if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
13840 if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
13841 return -EINVAL;
13842 new_triggers.four_way_handshake = true;
13843 regular = true;
13846 if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
13847 if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
13848 return -EINVAL;
13849 new_triggers.rfkill_release = true;
13850 regular = true;
13853 if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
13854 struct nlattr *pat;
13855 int n_patterns = 0;
13856 int rem, pat_len, mask_len, pkt_offset;
13857 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
13859 regular = true;
13861 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
13862 rem)
13863 n_patterns++;
13864 if (n_patterns > wowlan->n_patterns)
13865 return -EINVAL;
13867 new_triggers.patterns = kcalloc(n_patterns,
13868 sizeof(new_triggers.patterns[0]),
13869 GFP_KERNEL);
13870 if (!new_triggers.patterns)
13871 return -ENOMEM;
13873 new_triggers.n_patterns = n_patterns;
13874 i = 0;
13876 nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN],
13877 rem) {
13878 u8 *mask_pat;
13880 err = nla_parse_nested_deprecated(pat_tb,
13881 MAX_NL80211_PKTPAT,
13882 pat,
13883 nl80211_packet_pattern_policy,
13884 info->extack);
13885 if (err)
13886 goto error;
13888 err = -EINVAL;
13889 if (!pat_tb[NL80211_PKTPAT_MASK] ||
13890 !pat_tb[NL80211_PKTPAT_PATTERN])
13891 goto error;
13892 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
13893 mask_len = DIV_ROUND_UP(pat_len, 8);
13894 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
13895 goto error;
13896 if (pat_len > wowlan->pattern_max_len ||
13897 pat_len < wowlan->pattern_min_len)
13898 goto error;
13900 pkt_offset =
13901 nla_get_u32_default(pat_tb[NL80211_PKTPAT_OFFSET],
13903 if (pkt_offset > wowlan->max_pkt_offset)
13904 goto error;
13905 new_triggers.patterns[i].pkt_offset = pkt_offset;
13907 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
13908 if (!mask_pat) {
13909 err = -ENOMEM;
13910 goto error;
13912 new_triggers.patterns[i].mask = mask_pat;
13913 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
13914 mask_len);
13915 mask_pat += mask_len;
13916 new_triggers.patterns[i].pattern = mask_pat;
13917 new_triggers.patterns[i].pattern_len = pat_len;
13918 memcpy(mask_pat,
13919 nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
13920 pat_len);
13921 i++;
13925 if (tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) {
13926 regular = true;
13927 err = nl80211_parse_wowlan_tcp(
13928 rdev, tb[NL80211_WOWLAN_TRIG_TCP_CONNECTION],
13929 &new_triggers);
13930 if (err)
13931 goto error;
13934 if (tb[NL80211_WOWLAN_TRIG_NET_DETECT]) {
13935 regular = true;
13936 err = nl80211_parse_wowlan_nd(
13937 rdev, wowlan, tb[NL80211_WOWLAN_TRIG_NET_DETECT],
13938 &new_triggers);
13939 if (err)
13940 goto error;
13943 /* The 'any' trigger means the device continues operating more or less
13944 * as in its normal operation mode and wakes up the host on most of the
13945 * normal interrupts (like packet RX, ...)
13946 * It therefore makes little sense to combine with the more constrained
13947 * wakeup trigger modes.
13949 if (new_triggers.any && regular) {
13950 err = -EINVAL;
13951 goto error;
13954 ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL);
13955 if (!ntrig) {
13956 err = -ENOMEM;
13957 goto error;
13959 cfg80211_rdev_free_wowlan(rdev);
13960 rdev->wiphy.wowlan_config = ntrig;
13962 set_wakeup:
13963 if (rdev->ops->set_wakeup &&
13964 prev_enabled != !!rdev->wiphy.wowlan_config)
13965 rdev_set_wakeup(rdev, rdev->wiphy.wowlan_config);
13967 return 0;
13968 error:
13969 for (i = 0; i < new_triggers.n_patterns; i++)
13970 kfree(new_triggers.patterns[i].mask);
13971 kfree(new_triggers.patterns);
13972 if (new_triggers.tcp && new_triggers.tcp->sock)
13973 sock_release(new_triggers.tcp->sock);
13974 kfree(new_triggers.tcp);
13975 kfree(new_triggers.nd_config);
13976 return err;
13978 #endif
13980 static int nl80211_send_coalesce_rules(struct sk_buff *msg,
13981 struct cfg80211_registered_device *rdev)
13983 struct nlattr *nl_pats, *nl_pat, *nl_rule, *nl_rules;
13984 int i, j, pat_len;
13985 struct cfg80211_coalesce_rules *rule;
13987 if (!rdev->coalesce->n_rules)
13988 return 0;
13990 nl_rules = nla_nest_start_noflag(msg, NL80211_ATTR_COALESCE_RULE);
13991 if (!nl_rules)
13992 return -ENOBUFS;
13994 for (i = 0; i < rdev->coalesce->n_rules; i++) {
13995 nl_rule = nla_nest_start_noflag(msg, i + 1);
13996 if (!nl_rule)
13997 return -ENOBUFS;
13999 rule = &rdev->coalesce->rules[i];
14000 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_DELAY,
14001 rule->delay))
14002 return -ENOBUFS;
14004 if (nla_put_u32(msg, NL80211_ATTR_COALESCE_RULE_CONDITION,
14005 rule->condition))
14006 return -ENOBUFS;
14008 nl_pats = nla_nest_start_noflag(msg,
14009 NL80211_ATTR_COALESCE_RULE_PKT_PATTERN);
14010 if (!nl_pats)
14011 return -ENOBUFS;
14013 for (j = 0; j < rule->n_patterns; j++) {
14014 nl_pat = nla_nest_start_noflag(msg, j + 1);
14015 if (!nl_pat)
14016 return -ENOBUFS;
14017 pat_len = rule->patterns[j].pattern_len;
14018 if (nla_put(msg, NL80211_PKTPAT_MASK,
14019 DIV_ROUND_UP(pat_len, 8),
14020 rule->patterns[j].mask) ||
14021 nla_put(msg, NL80211_PKTPAT_PATTERN, pat_len,
14022 rule->patterns[j].pattern) ||
14023 nla_put_u32(msg, NL80211_PKTPAT_OFFSET,
14024 rule->patterns[j].pkt_offset))
14025 return -ENOBUFS;
14026 nla_nest_end(msg, nl_pat);
14028 nla_nest_end(msg, nl_pats);
14029 nla_nest_end(msg, nl_rule);
14031 nla_nest_end(msg, nl_rules);
14033 return 0;
14036 static int nl80211_get_coalesce(struct sk_buff *skb, struct genl_info *info)
14038 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14039 struct sk_buff *msg;
14040 void *hdr;
14042 if (!rdev->wiphy.coalesce)
14043 return -EOPNOTSUPP;
14045 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14046 if (!msg)
14047 return -ENOMEM;
14049 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
14050 NL80211_CMD_GET_COALESCE);
14051 if (!hdr)
14052 goto nla_put_failure;
14054 if (rdev->coalesce && nl80211_send_coalesce_rules(msg, rdev))
14055 goto nla_put_failure;
14057 genlmsg_end(msg, hdr);
14058 return genlmsg_reply(msg, info);
14060 nla_put_failure:
14061 nlmsg_free(msg);
14062 return -ENOBUFS;
14065 void cfg80211_free_coalesce(struct cfg80211_coalesce *coalesce)
14067 int i, j;
14068 struct cfg80211_coalesce_rules *rule;
14070 if (!coalesce)
14071 return;
14073 for (i = 0; i < coalesce->n_rules; i++) {
14074 rule = &coalesce->rules[i];
14075 for (j = 0; j < rule->n_patterns; j++)
14076 kfree(rule->patterns[j].mask);
14077 kfree(rule->patterns);
14079 kfree(coalesce);
14082 static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev,
14083 struct nlattr *rule,
14084 struct cfg80211_coalesce_rules *new_rule)
14086 int err, i;
14087 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
14088 struct nlattr *tb[NUM_NL80211_ATTR_COALESCE_RULE], *pat;
14089 int rem, pat_len, mask_len, pkt_offset, n_patterns = 0;
14090 struct nlattr *pat_tb[NUM_NL80211_PKTPAT];
14092 err = nla_parse_nested_deprecated(tb, NL80211_ATTR_COALESCE_RULE_MAX,
14093 rule, nl80211_coalesce_policy, NULL);
14094 if (err)
14095 return err;
14097 if (tb[NL80211_ATTR_COALESCE_RULE_DELAY])
14098 new_rule->delay =
14099 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_DELAY]);
14100 if (new_rule->delay > coalesce->max_delay)
14101 return -EINVAL;
14103 if (tb[NL80211_ATTR_COALESCE_RULE_CONDITION])
14104 new_rule->condition =
14105 nla_get_u32(tb[NL80211_ATTR_COALESCE_RULE_CONDITION]);
14107 if (!tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN])
14108 return -EINVAL;
14110 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
14111 rem)
14112 n_patterns++;
14113 if (n_patterns > coalesce->n_patterns)
14114 return -EINVAL;
14116 new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]),
14117 GFP_KERNEL);
14118 if (!new_rule->patterns)
14119 return -ENOMEM;
14121 new_rule->n_patterns = n_patterns;
14122 i = 0;
14124 nla_for_each_nested(pat, tb[NL80211_ATTR_COALESCE_RULE_PKT_PATTERN],
14125 rem) {
14126 u8 *mask_pat;
14128 err = nla_parse_nested_deprecated(pat_tb, MAX_NL80211_PKTPAT,
14129 pat,
14130 nl80211_packet_pattern_policy,
14131 NULL);
14132 if (err)
14133 return err;
14135 if (!pat_tb[NL80211_PKTPAT_MASK] ||
14136 !pat_tb[NL80211_PKTPAT_PATTERN])
14137 return -EINVAL;
14138 pat_len = nla_len(pat_tb[NL80211_PKTPAT_PATTERN]);
14139 mask_len = DIV_ROUND_UP(pat_len, 8);
14140 if (nla_len(pat_tb[NL80211_PKTPAT_MASK]) != mask_len)
14141 return -EINVAL;
14142 if (pat_len > coalesce->pattern_max_len ||
14143 pat_len < coalesce->pattern_min_len)
14144 return -EINVAL;
14146 pkt_offset = nla_get_u32_default(pat_tb[NL80211_PKTPAT_OFFSET],
14148 if (pkt_offset > coalesce->max_pkt_offset)
14149 return -EINVAL;
14150 new_rule->patterns[i].pkt_offset = pkt_offset;
14152 mask_pat = kmalloc(mask_len + pat_len, GFP_KERNEL);
14153 if (!mask_pat)
14154 return -ENOMEM;
14156 new_rule->patterns[i].mask = mask_pat;
14157 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_MASK]),
14158 mask_len);
14160 mask_pat += mask_len;
14161 new_rule->patterns[i].pattern = mask_pat;
14162 new_rule->patterns[i].pattern_len = pat_len;
14163 memcpy(mask_pat, nla_data(pat_tb[NL80211_PKTPAT_PATTERN]),
14164 pat_len);
14165 i++;
14168 return 0;
14171 static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info)
14173 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14174 const struct wiphy_coalesce_support *coalesce = rdev->wiphy.coalesce;
14175 struct cfg80211_coalesce *new_coalesce;
14176 int err, rem_rule, n_rules = 0, i;
14177 struct nlattr *rule;
14179 if (!rdev->wiphy.coalesce || !rdev->ops->set_coalesce)
14180 return -EOPNOTSUPP;
14182 if (!info->attrs[NL80211_ATTR_COALESCE_RULE]) {
14183 cfg80211_free_coalesce(rdev->coalesce);
14184 rdev->coalesce = NULL;
14185 rdev_set_coalesce(rdev, NULL);
14186 return 0;
14189 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
14190 rem_rule)
14191 n_rules++;
14192 if (n_rules > coalesce->n_rules)
14193 return -EINVAL;
14195 new_coalesce = kzalloc(struct_size(new_coalesce, rules, n_rules),
14196 GFP_KERNEL);
14197 if (!new_coalesce)
14198 return -ENOMEM;
14200 new_coalesce->n_rules = n_rules;
14201 i = 0;
14203 nla_for_each_nested(rule, info->attrs[NL80211_ATTR_COALESCE_RULE],
14204 rem_rule) {
14205 err = nl80211_parse_coalesce_rule(rdev, rule,
14206 &new_coalesce->rules[i]);
14207 if (err)
14208 goto error;
14210 i++;
14213 err = rdev_set_coalesce(rdev, new_coalesce);
14214 if (err)
14215 goto error;
14217 cfg80211_free_coalesce(rdev->coalesce);
14218 rdev->coalesce = new_coalesce;
14220 return 0;
14221 error:
14222 cfg80211_free_coalesce(new_coalesce);
14224 return err;
14227 static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info)
14229 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14230 struct net_device *dev = info->user_ptr[1];
14231 struct wireless_dev *wdev = dev->ieee80211_ptr;
14232 struct nlattr *tb[NUM_NL80211_REKEY_DATA];
14233 struct cfg80211_gtk_rekey_data rekey_data = {};
14234 int err;
14236 if (!info->attrs[NL80211_ATTR_REKEY_DATA])
14237 return -EINVAL;
14239 err = nla_parse_nested_deprecated(tb, MAX_NL80211_REKEY_DATA,
14240 info->attrs[NL80211_ATTR_REKEY_DATA],
14241 nl80211_rekey_policy, info->extack);
14242 if (err)
14243 return err;
14245 if (!tb[NL80211_REKEY_DATA_REPLAY_CTR] || !tb[NL80211_REKEY_DATA_KEK] ||
14246 !tb[NL80211_REKEY_DATA_KCK])
14247 return -EINVAL;
14248 if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN &&
14249 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
14250 nla_len(tb[NL80211_REKEY_DATA_KEK]) == NL80211_KEK_EXT_LEN))
14251 return -ERANGE;
14252 if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN &&
14253 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK &&
14254 nla_len(tb[NL80211_REKEY_DATA_KCK]) == NL80211_KCK_EXT_LEN) &&
14255 !(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_EXT_KCK_32 &&
14256 nla_len(tb[NL80211_REKEY_DATA_KCK]) == NL80211_KCK_EXT_LEN_32))
14257 return -ERANGE;
14259 rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]);
14260 rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]);
14261 rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]);
14262 rekey_data.kek_len = nla_len(tb[NL80211_REKEY_DATA_KEK]);
14263 rekey_data.kck_len = nla_len(tb[NL80211_REKEY_DATA_KCK]);
14264 if (tb[NL80211_REKEY_DATA_AKM])
14265 rekey_data.akm = nla_get_u32(tb[NL80211_REKEY_DATA_AKM]);
14267 if (!wdev->connected)
14268 return -ENOTCONN;
14270 if (!rdev->ops->set_rekey_data)
14271 return -EOPNOTSUPP;
14273 return rdev_set_rekey_data(rdev, dev, &rekey_data);
14276 static int nl80211_register_unexpected_frame(struct sk_buff *skb,
14277 struct genl_info *info)
14279 struct net_device *dev = info->user_ptr[1];
14280 struct wireless_dev *wdev = dev->ieee80211_ptr;
14282 if (wdev->iftype != NL80211_IFTYPE_AP &&
14283 wdev->iftype != NL80211_IFTYPE_P2P_GO)
14284 return -EINVAL;
14286 if (wdev->ap_unexpected_nlportid)
14287 return -EBUSY;
14289 wdev->ap_unexpected_nlportid = info->snd_portid;
14290 return 0;
14293 static int nl80211_probe_client(struct sk_buff *skb,
14294 struct genl_info *info)
14296 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14297 struct net_device *dev = info->user_ptr[1];
14298 struct wireless_dev *wdev = dev->ieee80211_ptr;
14299 struct sk_buff *msg;
14300 void *hdr;
14301 const u8 *addr;
14302 u64 cookie;
14303 int err;
14305 if (wdev->iftype != NL80211_IFTYPE_AP &&
14306 wdev->iftype != NL80211_IFTYPE_P2P_GO)
14307 return -EOPNOTSUPP;
14309 if (!info->attrs[NL80211_ATTR_MAC])
14310 return -EINVAL;
14312 if (!rdev->ops->probe_client)
14313 return -EOPNOTSUPP;
14315 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14316 if (!msg)
14317 return -ENOMEM;
14319 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
14320 NL80211_CMD_PROBE_CLIENT);
14321 if (!hdr) {
14322 err = -ENOBUFS;
14323 goto free_msg;
14326 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
14328 err = rdev_probe_client(rdev, dev, addr, &cookie);
14329 if (err)
14330 goto free_msg;
14332 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14333 NL80211_ATTR_PAD))
14334 goto nla_put_failure;
14336 genlmsg_end(msg, hdr);
14338 return genlmsg_reply(msg, info);
14340 nla_put_failure:
14341 err = -ENOBUFS;
14342 free_msg:
14343 nlmsg_free(msg);
14344 return err;
14347 static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
14349 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14350 struct cfg80211_beacon_registration *reg, *nreg;
14351 int rv;
14353 if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
14354 return -EOPNOTSUPP;
14356 nreg = kzalloc(sizeof(*nreg), GFP_KERNEL);
14357 if (!nreg)
14358 return -ENOMEM;
14360 /* First, check if already registered. */
14361 spin_lock_bh(&rdev->beacon_registrations_lock);
14362 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
14363 if (reg->nlportid == info->snd_portid) {
14364 rv = -EALREADY;
14365 goto out_err;
14368 /* Add it to the list */
14369 nreg->nlportid = info->snd_portid;
14370 list_add(&nreg->list, &rdev->beacon_registrations);
14372 spin_unlock_bh(&rdev->beacon_registrations_lock);
14374 return 0;
14375 out_err:
14376 spin_unlock_bh(&rdev->beacon_registrations_lock);
14377 kfree(nreg);
14378 return rv;
14381 static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
14383 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14384 struct wireless_dev *wdev = info->user_ptr[1];
14385 int err;
14387 if (!rdev->ops->start_p2p_device)
14388 return -EOPNOTSUPP;
14390 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
14391 return -EOPNOTSUPP;
14393 if (wdev_running(wdev))
14394 return 0;
14396 if (rfkill_blocked(rdev->wiphy.rfkill))
14397 return -ERFKILL;
14399 err = rdev_start_p2p_device(rdev, wdev);
14400 if (err)
14401 return err;
14403 wdev->is_running = true;
14404 rdev->opencount++;
14406 return 0;
14409 static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
14411 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14412 struct wireless_dev *wdev = info->user_ptr[1];
14414 if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE)
14415 return -EOPNOTSUPP;
14417 if (!rdev->ops->stop_p2p_device)
14418 return -EOPNOTSUPP;
14420 cfg80211_stop_p2p_device(rdev, wdev);
14422 return 0;
14425 static int nl80211_start_nan(struct sk_buff *skb, struct genl_info *info)
14427 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14428 struct wireless_dev *wdev = info->user_ptr[1];
14429 struct cfg80211_nan_conf conf = {};
14430 int err;
14432 if (wdev->iftype != NL80211_IFTYPE_NAN)
14433 return -EOPNOTSUPP;
14435 if (wdev_running(wdev))
14436 return -EEXIST;
14438 if (rfkill_blocked(rdev->wiphy.rfkill))
14439 return -ERFKILL;
14441 if (!info->attrs[NL80211_ATTR_NAN_MASTER_PREF])
14442 return -EINVAL;
14444 conf.master_pref =
14445 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
14447 if (info->attrs[NL80211_ATTR_BANDS]) {
14448 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
14450 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
14451 return -EOPNOTSUPP;
14453 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
14454 return -EINVAL;
14456 conf.bands = bands;
14459 err = rdev_start_nan(rdev, wdev, &conf);
14460 if (err)
14461 return err;
14463 wdev->is_running = true;
14464 rdev->opencount++;
14466 return 0;
14469 static int nl80211_stop_nan(struct sk_buff *skb, struct genl_info *info)
14471 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14472 struct wireless_dev *wdev = info->user_ptr[1];
14474 if (wdev->iftype != NL80211_IFTYPE_NAN)
14475 return -EOPNOTSUPP;
14477 cfg80211_stop_nan(rdev, wdev);
14479 return 0;
14482 static int validate_nan_filter(struct nlattr *filter_attr)
14484 struct nlattr *attr;
14485 int len = 0, n_entries = 0, rem;
14487 nla_for_each_nested(attr, filter_attr, rem) {
14488 len += nla_len(attr);
14489 n_entries++;
14492 if (len >= U8_MAX)
14493 return -EINVAL;
14495 return n_entries;
14498 static int handle_nan_filter(struct nlattr *attr_filter,
14499 struct cfg80211_nan_func *func,
14500 bool tx)
14502 struct nlattr *attr;
14503 int n_entries, rem, i;
14504 struct cfg80211_nan_func_filter *filter;
14506 n_entries = validate_nan_filter(attr_filter);
14507 if (n_entries < 0)
14508 return n_entries;
14510 BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters));
14512 filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL);
14513 if (!filter)
14514 return -ENOMEM;
14516 i = 0;
14517 nla_for_each_nested(attr, attr_filter, rem) {
14518 filter[i].filter = nla_memdup(attr, GFP_KERNEL);
14519 if (!filter[i].filter)
14520 goto err;
14522 filter[i].len = nla_len(attr);
14523 i++;
14525 if (tx) {
14526 func->num_tx_filters = n_entries;
14527 func->tx_filters = filter;
14528 } else {
14529 func->num_rx_filters = n_entries;
14530 func->rx_filters = filter;
14533 return 0;
14535 err:
14536 i = 0;
14537 nla_for_each_nested(attr, attr_filter, rem) {
14538 kfree(filter[i].filter);
14539 i++;
14541 kfree(filter);
14542 return -ENOMEM;
14545 static int nl80211_nan_add_func(struct sk_buff *skb,
14546 struct genl_info *info)
14548 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14549 struct wireless_dev *wdev = info->user_ptr[1];
14550 struct nlattr *tb[NUM_NL80211_NAN_FUNC_ATTR], *func_attr;
14551 struct cfg80211_nan_func *func;
14552 struct sk_buff *msg = NULL;
14553 void *hdr = NULL;
14554 int err = 0;
14556 if (wdev->iftype != NL80211_IFTYPE_NAN)
14557 return -EOPNOTSUPP;
14559 if (!wdev_running(wdev))
14560 return -ENOTCONN;
14562 if (!info->attrs[NL80211_ATTR_NAN_FUNC])
14563 return -EINVAL;
14565 err = nla_parse_nested_deprecated(tb, NL80211_NAN_FUNC_ATTR_MAX,
14566 info->attrs[NL80211_ATTR_NAN_FUNC],
14567 nl80211_nan_func_policy,
14568 info->extack);
14569 if (err)
14570 return err;
14572 func = kzalloc(sizeof(*func), GFP_KERNEL);
14573 if (!func)
14574 return -ENOMEM;
14576 func->cookie = cfg80211_assign_cookie(rdev);
14578 if (!tb[NL80211_NAN_FUNC_TYPE]) {
14579 err = -EINVAL;
14580 goto out;
14584 func->type = nla_get_u8(tb[NL80211_NAN_FUNC_TYPE]);
14586 if (!tb[NL80211_NAN_FUNC_SERVICE_ID]) {
14587 err = -EINVAL;
14588 goto out;
14591 memcpy(func->service_id, nla_data(tb[NL80211_NAN_FUNC_SERVICE_ID]),
14592 sizeof(func->service_id));
14594 func->close_range =
14595 nla_get_flag(tb[NL80211_NAN_FUNC_CLOSE_RANGE]);
14597 if (tb[NL80211_NAN_FUNC_SERVICE_INFO]) {
14598 func->serv_spec_info_len =
14599 nla_len(tb[NL80211_NAN_FUNC_SERVICE_INFO]);
14600 func->serv_spec_info =
14601 kmemdup(nla_data(tb[NL80211_NAN_FUNC_SERVICE_INFO]),
14602 func->serv_spec_info_len,
14603 GFP_KERNEL);
14604 if (!func->serv_spec_info) {
14605 err = -ENOMEM;
14606 goto out;
14610 if (tb[NL80211_NAN_FUNC_TTL])
14611 func->ttl = nla_get_u32(tb[NL80211_NAN_FUNC_TTL]);
14613 switch (func->type) {
14614 case NL80211_NAN_FUNC_PUBLISH:
14615 if (!tb[NL80211_NAN_FUNC_PUBLISH_TYPE]) {
14616 err = -EINVAL;
14617 goto out;
14620 func->publish_type =
14621 nla_get_u8(tb[NL80211_NAN_FUNC_PUBLISH_TYPE]);
14622 func->publish_bcast =
14623 nla_get_flag(tb[NL80211_NAN_FUNC_PUBLISH_BCAST]);
14625 if ((!(func->publish_type & NL80211_NAN_SOLICITED_PUBLISH)) &&
14626 func->publish_bcast) {
14627 err = -EINVAL;
14628 goto out;
14630 break;
14631 case NL80211_NAN_FUNC_SUBSCRIBE:
14632 func->subscribe_active =
14633 nla_get_flag(tb[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE]);
14634 break;
14635 case NL80211_NAN_FUNC_FOLLOW_UP:
14636 if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] ||
14637 !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] ||
14638 !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) {
14639 err = -EINVAL;
14640 goto out;
14643 func->followup_id =
14644 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_ID]);
14645 func->followup_reqid =
14646 nla_get_u8(tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]);
14647 memcpy(func->followup_dest.addr,
14648 nla_data(tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]),
14649 sizeof(func->followup_dest.addr));
14650 if (func->ttl) {
14651 err = -EINVAL;
14652 goto out;
14654 break;
14655 default:
14656 err = -EINVAL;
14657 goto out;
14660 if (tb[NL80211_NAN_FUNC_SRF]) {
14661 struct nlattr *srf_tb[NUM_NL80211_NAN_SRF_ATTR];
14663 err = nla_parse_nested_deprecated(srf_tb,
14664 NL80211_NAN_SRF_ATTR_MAX,
14665 tb[NL80211_NAN_FUNC_SRF],
14666 nl80211_nan_srf_policy,
14667 info->extack);
14668 if (err)
14669 goto out;
14671 func->srf_include =
14672 nla_get_flag(srf_tb[NL80211_NAN_SRF_INCLUDE]);
14674 if (srf_tb[NL80211_NAN_SRF_BF]) {
14675 if (srf_tb[NL80211_NAN_SRF_MAC_ADDRS] ||
14676 !srf_tb[NL80211_NAN_SRF_BF_IDX]) {
14677 err = -EINVAL;
14678 goto out;
14681 func->srf_bf_len =
14682 nla_len(srf_tb[NL80211_NAN_SRF_BF]);
14683 func->srf_bf =
14684 kmemdup(nla_data(srf_tb[NL80211_NAN_SRF_BF]),
14685 func->srf_bf_len, GFP_KERNEL);
14686 if (!func->srf_bf) {
14687 err = -ENOMEM;
14688 goto out;
14691 func->srf_bf_idx =
14692 nla_get_u8(srf_tb[NL80211_NAN_SRF_BF_IDX]);
14693 } else {
14694 struct nlattr *attr, *mac_attr =
14695 srf_tb[NL80211_NAN_SRF_MAC_ADDRS];
14696 int n_entries, rem, i = 0;
14698 if (!mac_attr) {
14699 err = -EINVAL;
14700 goto out;
14703 n_entries = validate_acl_mac_addrs(mac_attr);
14704 if (n_entries <= 0) {
14705 err = -EINVAL;
14706 goto out;
14709 func->srf_num_macs = n_entries;
14710 func->srf_macs =
14711 kcalloc(n_entries, sizeof(*func->srf_macs),
14712 GFP_KERNEL);
14713 if (!func->srf_macs) {
14714 err = -ENOMEM;
14715 goto out;
14718 nla_for_each_nested(attr, mac_attr, rem)
14719 memcpy(func->srf_macs[i++].addr, nla_data(attr),
14720 sizeof(*func->srf_macs));
14724 if (tb[NL80211_NAN_FUNC_TX_MATCH_FILTER]) {
14725 err = handle_nan_filter(tb[NL80211_NAN_FUNC_TX_MATCH_FILTER],
14726 func, true);
14727 if (err)
14728 goto out;
14731 if (tb[NL80211_NAN_FUNC_RX_MATCH_FILTER]) {
14732 err = handle_nan_filter(tb[NL80211_NAN_FUNC_RX_MATCH_FILTER],
14733 func, false);
14734 if (err)
14735 goto out;
14738 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14739 if (!msg) {
14740 err = -ENOMEM;
14741 goto out;
14744 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
14745 NL80211_CMD_ADD_NAN_FUNCTION);
14746 /* This can't really happen - we just allocated 4KB */
14747 if (WARN_ON(!hdr)) {
14748 err = -ENOMEM;
14749 goto out;
14752 err = rdev_add_nan_func(rdev, wdev, func);
14753 out:
14754 if (err < 0) {
14755 cfg80211_free_nan_func(func);
14756 nlmsg_free(msg);
14757 return err;
14760 /* propagate the instance id and cookie to userspace */
14761 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, func->cookie,
14762 NL80211_ATTR_PAD))
14763 goto nla_put_failure;
14765 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
14766 if (!func_attr)
14767 goto nla_put_failure;
14769 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID,
14770 func->instance_id))
14771 goto nla_put_failure;
14773 nla_nest_end(msg, func_attr);
14775 genlmsg_end(msg, hdr);
14776 return genlmsg_reply(msg, info);
14778 nla_put_failure:
14779 nlmsg_free(msg);
14780 return -ENOBUFS;
14783 static int nl80211_nan_del_func(struct sk_buff *skb,
14784 struct genl_info *info)
14786 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14787 struct wireless_dev *wdev = info->user_ptr[1];
14788 u64 cookie;
14790 if (wdev->iftype != NL80211_IFTYPE_NAN)
14791 return -EOPNOTSUPP;
14793 if (!wdev_running(wdev))
14794 return -ENOTCONN;
14796 if (!info->attrs[NL80211_ATTR_COOKIE])
14797 return -EINVAL;
14799 cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
14801 rdev_del_nan_func(rdev, wdev, cookie);
14803 return 0;
14806 static int nl80211_nan_change_config(struct sk_buff *skb,
14807 struct genl_info *info)
14809 struct cfg80211_registered_device *rdev = info->user_ptr[0];
14810 struct wireless_dev *wdev = info->user_ptr[1];
14811 struct cfg80211_nan_conf conf = {};
14812 u32 changed = 0;
14814 if (wdev->iftype != NL80211_IFTYPE_NAN)
14815 return -EOPNOTSUPP;
14817 if (!wdev_running(wdev))
14818 return -ENOTCONN;
14820 if (info->attrs[NL80211_ATTR_NAN_MASTER_PREF]) {
14821 conf.master_pref =
14822 nla_get_u8(info->attrs[NL80211_ATTR_NAN_MASTER_PREF]);
14823 if (conf.master_pref <= 1 || conf.master_pref == 255)
14824 return -EINVAL;
14826 changed |= CFG80211_NAN_CONF_CHANGED_PREF;
14829 if (info->attrs[NL80211_ATTR_BANDS]) {
14830 u32 bands = nla_get_u32(info->attrs[NL80211_ATTR_BANDS]);
14832 if (bands & ~(u32)wdev->wiphy->nan_supported_bands)
14833 return -EOPNOTSUPP;
14835 if (bands && !(bands & BIT(NL80211_BAND_2GHZ)))
14836 return -EINVAL;
14838 conf.bands = bands;
14839 changed |= CFG80211_NAN_CONF_CHANGED_BANDS;
14842 if (!changed)
14843 return -EINVAL;
14845 return rdev_nan_change_conf(rdev, wdev, &conf, changed);
14848 void cfg80211_nan_match(struct wireless_dev *wdev,
14849 struct cfg80211_nan_match_params *match, gfp_t gfp)
14851 struct wiphy *wiphy = wdev->wiphy;
14852 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14853 struct nlattr *match_attr, *local_func_attr, *peer_func_attr;
14854 struct sk_buff *msg;
14855 void *hdr;
14857 if (WARN_ON(!match->inst_id || !match->peer_inst_id || !match->addr))
14858 return;
14860 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14861 if (!msg)
14862 return;
14864 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NAN_MATCH);
14865 if (!hdr) {
14866 nlmsg_free(msg);
14867 return;
14870 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14871 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14872 wdev->netdev->ifindex)) ||
14873 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14874 NL80211_ATTR_PAD))
14875 goto nla_put_failure;
14877 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, match->cookie,
14878 NL80211_ATTR_PAD) ||
14879 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, match->addr))
14880 goto nla_put_failure;
14882 match_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_MATCH);
14883 if (!match_attr)
14884 goto nla_put_failure;
14886 local_func_attr = nla_nest_start_noflag(msg,
14887 NL80211_NAN_MATCH_FUNC_LOCAL);
14888 if (!local_func_attr)
14889 goto nla_put_failure;
14891 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->inst_id))
14892 goto nla_put_failure;
14894 nla_nest_end(msg, local_func_attr);
14896 peer_func_attr = nla_nest_start_noflag(msg,
14897 NL80211_NAN_MATCH_FUNC_PEER);
14898 if (!peer_func_attr)
14899 goto nla_put_failure;
14901 if (nla_put_u8(msg, NL80211_NAN_FUNC_TYPE, match->type) ||
14902 nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, match->peer_inst_id))
14903 goto nla_put_failure;
14905 if (match->info && match->info_len &&
14906 nla_put(msg, NL80211_NAN_FUNC_SERVICE_INFO, match->info_len,
14907 match->info))
14908 goto nla_put_failure;
14910 nla_nest_end(msg, peer_func_attr);
14911 nla_nest_end(msg, match_attr);
14912 genlmsg_end(msg, hdr);
14914 if (!wdev->owner_nlportid)
14915 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
14916 msg, 0, NL80211_MCGRP_NAN, gfp);
14917 else
14918 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
14919 wdev->owner_nlportid);
14921 return;
14923 nla_put_failure:
14924 nlmsg_free(msg);
14926 EXPORT_SYMBOL(cfg80211_nan_match);
14928 void cfg80211_nan_func_terminated(struct wireless_dev *wdev,
14929 u8 inst_id,
14930 enum nl80211_nan_func_term_reason reason,
14931 u64 cookie, gfp_t gfp)
14933 struct wiphy *wiphy = wdev->wiphy;
14934 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
14935 struct sk_buff *msg;
14936 struct nlattr *func_attr;
14937 void *hdr;
14939 if (WARN_ON(!inst_id))
14940 return;
14942 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
14943 if (!msg)
14944 return;
14946 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_NAN_FUNCTION);
14947 if (!hdr) {
14948 nlmsg_free(msg);
14949 return;
14952 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
14953 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
14954 wdev->netdev->ifindex)) ||
14955 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
14956 NL80211_ATTR_PAD))
14957 goto nla_put_failure;
14959 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
14960 NL80211_ATTR_PAD))
14961 goto nla_put_failure;
14963 func_attr = nla_nest_start_noflag(msg, NL80211_ATTR_NAN_FUNC);
14964 if (!func_attr)
14965 goto nla_put_failure;
14967 if (nla_put_u8(msg, NL80211_NAN_FUNC_INSTANCE_ID, inst_id) ||
14968 nla_put_u8(msg, NL80211_NAN_FUNC_TERM_REASON, reason))
14969 goto nla_put_failure;
14971 nla_nest_end(msg, func_attr);
14972 genlmsg_end(msg, hdr);
14974 if (!wdev->owner_nlportid)
14975 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
14976 msg, 0, NL80211_MCGRP_NAN, gfp);
14977 else
14978 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
14979 wdev->owner_nlportid);
14981 return;
14983 nla_put_failure:
14984 nlmsg_free(msg);
14986 EXPORT_SYMBOL(cfg80211_nan_func_terminated);
14988 static int nl80211_get_protocol_features(struct sk_buff *skb,
14989 struct genl_info *info)
14991 void *hdr;
14992 struct sk_buff *msg;
14994 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
14995 if (!msg)
14996 return -ENOMEM;
14998 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
14999 NL80211_CMD_GET_PROTOCOL_FEATURES);
15000 if (!hdr)
15001 goto nla_put_failure;
15003 if (nla_put_u32(msg, NL80211_ATTR_PROTOCOL_FEATURES,
15004 NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP))
15005 goto nla_put_failure;
15007 genlmsg_end(msg, hdr);
15008 return genlmsg_reply(msg, info);
15010 nla_put_failure:
15011 kfree_skb(msg);
15012 return -ENOBUFS;
15015 static int nl80211_update_ft_ies(struct sk_buff *skb, struct genl_info *info)
15017 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15018 struct cfg80211_update_ft_ies_params ft_params;
15019 struct net_device *dev = info->user_ptr[1];
15021 if (!rdev->ops->update_ft_ies)
15022 return -EOPNOTSUPP;
15024 if (!info->attrs[NL80211_ATTR_MDID] ||
15025 !info->attrs[NL80211_ATTR_IE])
15026 return -EINVAL;
15028 memset(&ft_params, 0, sizeof(ft_params));
15029 ft_params.md = nla_get_u16(info->attrs[NL80211_ATTR_MDID]);
15030 ft_params.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
15031 ft_params.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
15033 return rdev_update_ft_ies(rdev, dev, &ft_params);
15036 static int nl80211_crit_protocol_start(struct sk_buff *skb,
15037 struct genl_info *info)
15039 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15040 struct wireless_dev *wdev = info->user_ptr[1];
15041 enum nl80211_crit_proto_id proto = NL80211_CRIT_PROTO_UNSPEC;
15042 u16 duration;
15043 int ret;
15045 if (!rdev->ops->crit_proto_start)
15046 return -EOPNOTSUPP;
15048 if (WARN_ON(!rdev->ops->crit_proto_stop))
15049 return -EINVAL;
15051 if (rdev->crit_proto_nlportid)
15052 return -EBUSY;
15054 /* determine protocol if provided */
15055 if (info->attrs[NL80211_ATTR_CRIT_PROT_ID])
15056 proto = nla_get_u16(info->attrs[NL80211_ATTR_CRIT_PROT_ID]);
15058 if (proto >= NUM_NL80211_CRIT_PROTO)
15059 return -EINVAL;
15061 /* timeout must be provided */
15062 if (!info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION])
15063 return -EINVAL;
15065 duration =
15066 nla_get_u16(info->attrs[NL80211_ATTR_MAX_CRIT_PROT_DURATION]);
15068 ret = rdev_crit_proto_start(rdev, wdev, proto, duration);
15069 if (!ret)
15070 rdev->crit_proto_nlportid = info->snd_portid;
15072 return ret;
15075 static int nl80211_crit_protocol_stop(struct sk_buff *skb,
15076 struct genl_info *info)
15078 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15079 struct wireless_dev *wdev = info->user_ptr[1];
15081 if (!rdev->ops->crit_proto_stop)
15082 return -EOPNOTSUPP;
15084 if (rdev->crit_proto_nlportid) {
15085 rdev->crit_proto_nlportid = 0;
15086 rdev_crit_proto_stop(rdev, wdev);
15088 return 0;
15091 static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
15092 struct nlattr *attr,
15093 struct netlink_ext_ack *extack)
15095 if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
15096 if (attr->nla_type & NLA_F_NESTED) {
15097 NL_SET_ERR_MSG_ATTR(extack, attr,
15098 "unexpected nested data");
15099 return -EINVAL;
15102 return 0;
15105 if (!(attr->nla_type & NLA_F_NESTED)) {
15106 NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
15107 return -EINVAL;
15110 return nla_validate_nested(attr, vcmd->maxattr, vcmd->policy, extack);
15113 static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
15115 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15116 struct wireless_dev *wdev =
15117 __cfg80211_wdev_from_attrs(rdev, genl_info_net(info),
15118 info->attrs);
15119 int i, err;
15120 u32 vid, subcmd;
15122 if (!rdev->wiphy.vendor_commands)
15123 return -EOPNOTSUPP;
15125 if (IS_ERR(wdev)) {
15126 err = PTR_ERR(wdev);
15127 if (err != -EINVAL)
15128 return err;
15129 wdev = NULL;
15130 } else if (wdev->wiphy != &rdev->wiphy) {
15131 return -EINVAL;
15134 if (!info->attrs[NL80211_ATTR_VENDOR_ID] ||
15135 !info->attrs[NL80211_ATTR_VENDOR_SUBCMD])
15136 return -EINVAL;
15138 vid = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_ID]);
15139 subcmd = nla_get_u32(info->attrs[NL80211_ATTR_VENDOR_SUBCMD]);
15140 for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
15141 const struct wiphy_vendor_command *vcmd;
15142 void *data = NULL;
15143 int len = 0;
15145 vcmd = &rdev->wiphy.vendor_commands[i];
15147 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
15148 continue;
15150 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
15151 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
15152 if (!wdev)
15153 return -EINVAL;
15154 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
15155 !wdev->netdev)
15156 return -EINVAL;
15158 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
15159 if (!wdev_running(wdev))
15160 return -ENETDOWN;
15162 } else {
15163 wdev = NULL;
15166 if (!vcmd->doit)
15167 return -EOPNOTSUPP;
15169 if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
15170 data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
15171 len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
15173 err = nl80211_vendor_check_policy(vcmd,
15174 info->attrs[NL80211_ATTR_VENDOR_DATA],
15175 info->extack);
15176 if (err)
15177 return err;
15180 rdev->cur_cmd_info = info;
15181 err = vcmd->doit(&rdev->wiphy, wdev, data, len);
15182 rdev->cur_cmd_info = NULL;
15183 return err;
15186 return -EOPNOTSUPP;
15189 static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
15190 struct netlink_callback *cb,
15191 struct cfg80211_registered_device **rdev,
15192 struct wireless_dev **wdev)
15194 struct nlattr **attrbuf;
15195 u32 vid, subcmd;
15196 unsigned int i;
15197 int vcmd_idx = -1;
15198 int err;
15199 void *data = NULL;
15200 unsigned int data_len = 0;
15202 if (cb->args[0]) {
15203 /* subtract the 1 again here */
15204 struct wiphy *wiphy = wiphy_idx_to_wiphy(cb->args[0] - 1);
15205 struct wireless_dev *tmp;
15207 if (!wiphy)
15208 return -ENODEV;
15209 *rdev = wiphy_to_rdev(wiphy);
15210 *wdev = NULL;
15212 if (cb->args[1]) {
15213 list_for_each_entry(tmp, &wiphy->wdev_list, list) {
15214 if (tmp->identifier == cb->args[1] - 1) {
15215 *wdev = tmp;
15216 break;
15221 /* keep rtnl locked in successful case */
15222 return 0;
15225 attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL);
15226 if (!attrbuf)
15227 return -ENOMEM;
15229 err = nlmsg_parse_deprecated(cb->nlh,
15230 GENL_HDRLEN + nl80211_fam.hdrsize,
15231 attrbuf, nl80211_fam.maxattr,
15232 nl80211_policy, NULL);
15233 if (err)
15234 goto out;
15236 if (!attrbuf[NL80211_ATTR_VENDOR_ID] ||
15237 !attrbuf[NL80211_ATTR_VENDOR_SUBCMD]) {
15238 err = -EINVAL;
15239 goto out;
15242 *wdev = __cfg80211_wdev_from_attrs(NULL, sock_net(skb->sk), attrbuf);
15243 if (IS_ERR(*wdev))
15244 *wdev = NULL;
15246 *rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), attrbuf);
15247 if (IS_ERR(*rdev)) {
15248 err = PTR_ERR(*rdev);
15249 goto out;
15252 vid = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_ID]);
15253 subcmd = nla_get_u32(attrbuf[NL80211_ATTR_VENDOR_SUBCMD]);
15255 for (i = 0; i < (*rdev)->wiphy.n_vendor_commands; i++) {
15256 const struct wiphy_vendor_command *vcmd;
15258 vcmd = &(*rdev)->wiphy.vendor_commands[i];
15260 if (vcmd->info.vendor_id != vid || vcmd->info.subcmd != subcmd)
15261 continue;
15263 if (!vcmd->dumpit) {
15264 err = -EOPNOTSUPP;
15265 goto out;
15268 vcmd_idx = i;
15269 break;
15272 if (vcmd_idx < 0) {
15273 err = -EOPNOTSUPP;
15274 goto out;
15277 if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
15278 data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
15279 data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
15281 err = nl80211_vendor_check_policy(
15282 &(*rdev)->wiphy.vendor_commands[vcmd_idx],
15283 attrbuf[NL80211_ATTR_VENDOR_DATA],
15284 cb->extack);
15285 if (err)
15286 goto out;
15289 /* 0 is the first index - add 1 to parse only once */
15290 cb->args[0] = (*rdev)->wiphy_idx + 1;
15291 /* add 1 to know if it was NULL */
15292 cb->args[1] = *wdev ? (*wdev)->identifier + 1 : 0;
15293 cb->args[2] = vcmd_idx;
15294 cb->args[3] = (unsigned long)data;
15295 cb->args[4] = data_len;
15297 /* keep rtnl locked in successful case */
15298 err = 0;
15299 out:
15300 kfree(attrbuf);
15301 return err;
15304 static int nl80211_vendor_cmd_dump(struct sk_buff *skb,
15305 struct netlink_callback *cb)
15307 struct cfg80211_registered_device *rdev;
15308 struct wireless_dev *wdev;
15309 unsigned int vcmd_idx;
15310 const struct wiphy_vendor_command *vcmd;
15311 void *data;
15312 int data_len;
15313 int err;
15314 struct nlattr *vendor_data;
15316 rtnl_lock();
15317 err = nl80211_prepare_vendor_dump(skb, cb, &rdev, &wdev);
15318 if (err)
15319 goto out;
15321 vcmd_idx = cb->args[2];
15322 data = (void *)cb->args[3];
15323 data_len = cb->args[4];
15324 vcmd = &rdev->wiphy.vendor_commands[vcmd_idx];
15326 if (vcmd->flags & (WIPHY_VENDOR_CMD_NEED_WDEV |
15327 WIPHY_VENDOR_CMD_NEED_NETDEV)) {
15328 if (!wdev) {
15329 err = -EINVAL;
15330 goto out;
15332 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_NETDEV &&
15333 !wdev->netdev) {
15334 err = -EINVAL;
15335 goto out;
15338 if (vcmd->flags & WIPHY_VENDOR_CMD_NEED_RUNNING) {
15339 if (!wdev_running(wdev)) {
15340 err = -ENETDOWN;
15341 goto out;
15346 while (1) {
15347 void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid,
15348 cb->nlh->nlmsg_seq, NLM_F_MULTI,
15349 NL80211_CMD_VENDOR);
15350 if (!hdr)
15351 break;
15353 if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
15354 (wdev && nla_put_u64_64bit(skb, NL80211_ATTR_WDEV,
15355 wdev_id(wdev),
15356 NL80211_ATTR_PAD))) {
15357 genlmsg_cancel(skb, hdr);
15358 break;
15361 vendor_data = nla_nest_start_noflag(skb,
15362 NL80211_ATTR_VENDOR_DATA);
15363 if (!vendor_data) {
15364 genlmsg_cancel(skb, hdr);
15365 break;
15368 err = vcmd->dumpit(&rdev->wiphy, wdev, skb, data, data_len,
15369 (unsigned long *)&cb->args[5]);
15370 nla_nest_end(skb, vendor_data);
15372 if (err == -ENOBUFS || err == -ENOENT) {
15373 genlmsg_cancel(skb, hdr);
15374 break;
15375 } else if (err <= 0) {
15376 genlmsg_cancel(skb, hdr);
15377 goto out;
15380 genlmsg_end(skb, hdr);
15383 err = skb->len;
15384 out:
15385 rtnl_unlock();
15386 return err;
15389 struct sk_buff *__cfg80211_alloc_reply_skb(struct wiphy *wiphy,
15390 enum nl80211_commands cmd,
15391 enum nl80211_attrs attr,
15392 int approxlen)
15394 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
15396 if (WARN_ON(!rdev->cur_cmd_info))
15397 return NULL;
15399 return __cfg80211_alloc_vendor_skb(rdev, NULL, approxlen,
15400 rdev->cur_cmd_info->snd_portid,
15401 rdev->cur_cmd_info->snd_seq,
15402 cmd, attr, NULL, GFP_KERNEL);
15404 EXPORT_SYMBOL(__cfg80211_alloc_reply_skb);
15406 int cfg80211_vendor_cmd_reply(struct sk_buff *skb)
15408 struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0];
15409 void *hdr = ((void **)skb->cb)[1];
15410 struct nlattr *data = ((void **)skb->cb)[2];
15412 /* clear CB data for netlink core to own from now on */
15413 memset(skb->cb, 0, sizeof(skb->cb));
15415 if (WARN_ON(!rdev->cur_cmd_info)) {
15416 kfree_skb(skb);
15417 return -EINVAL;
15420 nla_nest_end(skb, data);
15421 genlmsg_end(skb, hdr);
15422 return genlmsg_reply(skb, rdev->cur_cmd_info);
15424 EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_reply);
15426 unsigned int cfg80211_vendor_cmd_get_sender(struct wiphy *wiphy)
15428 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
15430 if (WARN_ON(!rdev->cur_cmd_info))
15431 return 0;
15433 return rdev->cur_cmd_info->snd_portid;
15435 EXPORT_SYMBOL_GPL(cfg80211_vendor_cmd_get_sender);
15437 static int nl80211_set_qos_map(struct sk_buff *skb,
15438 struct genl_info *info)
15440 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15441 struct cfg80211_qos_map *qos_map = NULL;
15442 struct net_device *dev = info->user_ptr[1];
15443 u8 *pos, len, num_des, des_len, des;
15444 int ret;
15446 if (!rdev->ops->set_qos_map)
15447 return -EOPNOTSUPP;
15449 if (info->attrs[NL80211_ATTR_QOS_MAP]) {
15450 pos = nla_data(info->attrs[NL80211_ATTR_QOS_MAP]);
15451 len = nla_len(info->attrs[NL80211_ATTR_QOS_MAP]);
15453 if (len % 2)
15454 return -EINVAL;
15456 qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL);
15457 if (!qos_map)
15458 return -ENOMEM;
15460 num_des = (len - IEEE80211_QOS_MAP_LEN_MIN) >> 1;
15461 if (num_des) {
15462 des_len = num_des *
15463 sizeof(struct cfg80211_dscp_exception);
15464 memcpy(qos_map->dscp_exception, pos, des_len);
15465 qos_map->num_des = num_des;
15466 for (des = 0; des < num_des; des++) {
15467 if (qos_map->dscp_exception[des].up > 7) {
15468 kfree(qos_map);
15469 return -EINVAL;
15472 pos += des_len;
15474 memcpy(qos_map->up, pos, IEEE80211_QOS_MAP_LEN_MIN);
15477 ret = nl80211_key_allowed(dev->ieee80211_ptr);
15478 if (!ret)
15479 ret = rdev_set_qos_map(rdev, dev, qos_map);
15481 kfree(qos_map);
15482 return ret;
15485 static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info)
15487 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15488 struct net_device *dev = info->user_ptr[1];
15489 struct wireless_dev *wdev = dev->ieee80211_ptr;
15490 const u8 *peer;
15491 u8 tsid, up;
15492 u16 admitted_time = 0;
15494 if (!(rdev->wiphy.features & NL80211_FEATURE_SUPPORTS_WMM_ADMISSION))
15495 return -EOPNOTSUPP;
15497 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] ||
15498 !info->attrs[NL80211_ATTR_USER_PRIO])
15499 return -EINVAL;
15501 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
15502 up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]);
15504 /* WMM uses TIDs 0-7 even for TSPEC */
15505 if (tsid >= IEEE80211_FIRST_TSPEC_TSID) {
15506 /* TODO: handle 802.11 TSPEC/admission control
15507 * need more attributes for that (e.g. BA session requirement);
15508 * change the WMM admission test above to allow both then
15510 return -EINVAL;
15513 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
15515 if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) {
15516 admitted_time =
15517 nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]);
15518 if (!admitted_time)
15519 return -EINVAL;
15522 switch (wdev->iftype) {
15523 case NL80211_IFTYPE_STATION:
15524 case NL80211_IFTYPE_P2P_CLIENT:
15525 if (wdev->connected)
15526 break;
15527 return -ENOTCONN;
15528 default:
15529 return -EOPNOTSUPP;
15532 return rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time);
15535 static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info)
15537 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15538 struct net_device *dev = info->user_ptr[1];
15539 const u8 *peer;
15540 u8 tsid;
15542 if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC])
15543 return -EINVAL;
15545 tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]);
15546 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
15548 return rdev_del_tx_ts(rdev, dev, tsid, peer);
15551 static int nl80211_tdls_channel_switch(struct sk_buff *skb,
15552 struct genl_info *info)
15554 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15555 struct net_device *dev = info->user_ptr[1];
15556 struct wireless_dev *wdev = dev->ieee80211_ptr;
15557 struct cfg80211_chan_def chandef = {};
15558 const u8 *addr;
15559 u8 oper_class;
15560 int err;
15562 if (!rdev->ops->tdls_channel_switch ||
15563 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
15564 return -EOPNOTSUPP;
15566 switch (dev->ieee80211_ptr->iftype) {
15567 case NL80211_IFTYPE_STATION:
15568 case NL80211_IFTYPE_P2P_CLIENT:
15569 break;
15570 default:
15571 return -EOPNOTSUPP;
15574 if (!info->attrs[NL80211_ATTR_MAC] ||
15575 !info->attrs[NL80211_ATTR_OPER_CLASS])
15576 return -EINVAL;
15578 err = nl80211_parse_chandef(rdev, info, &chandef);
15579 if (err)
15580 return err;
15583 * Don't allow wide channels on the 2.4Ghz band, as per IEEE802.11-2012
15584 * section 10.22.6.2.1. Disallow 5/10Mhz channels as well for now, the
15585 * specification is not defined for them.
15587 if (chandef.chan->band == NL80211_BAND_2GHZ &&
15588 chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
15589 chandef.width != NL80211_CHAN_WIDTH_20)
15590 return -EINVAL;
15592 /* we will be active on the TDLS link */
15593 if (!cfg80211_reg_can_beacon_relax(&rdev->wiphy, &chandef,
15594 wdev->iftype))
15595 return -EINVAL;
15597 /* don't allow switching to DFS channels */
15598 if (cfg80211_chandef_dfs_required(wdev->wiphy, &chandef, wdev->iftype))
15599 return -EINVAL;
15601 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
15602 oper_class = nla_get_u8(info->attrs[NL80211_ATTR_OPER_CLASS]);
15604 return rdev_tdls_channel_switch(rdev, dev, addr, oper_class, &chandef);
15607 static int nl80211_tdls_cancel_channel_switch(struct sk_buff *skb,
15608 struct genl_info *info)
15610 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15611 struct net_device *dev = info->user_ptr[1];
15612 const u8 *addr;
15614 if (!rdev->ops->tdls_channel_switch ||
15615 !rdev->ops->tdls_cancel_channel_switch ||
15616 !(rdev->wiphy.features & NL80211_FEATURE_TDLS_CHANNEL_SWITCH))
15617 return -EOPNOTSUPP;
15619 switch (dev->ieee80211_ptr->iftype) {
15620 case NL80211_IFTYPE_STATION:
15621 case NL80211_IFTYPE_P2P_CLIENT:
15622 break;
15623 default:
15624 return -EOPNOTSUPP;
15627 if (!info->attrs[NL80211_ATTR_MAC])
15628 return -EINVAL;
15630 addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
15632 rdev_tdls_cancel_channel_switch(rdev, dev, addr);
15634 return 0;
15637 static int nl80211_set_multicast_to_unicast(struct sk_buff *skb,
15638 struct genl_info *info)
15640 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15641 struct net_device *dev = info->user_ptr[1];
15642 struct wireless_dev *wdev = dev->ieee80211_ptr;
15643 const struct nlattr *nla;
15644 bool enabled;
15646 if (!rdev->ops->set_multicast_to_unicast)
15647 return -EOPNOTSUPP;
15649 if (wdev->iftype != NL80211_IFTYPE_AP &&
15650 wdev->iftype != NL80211_IFTYPE_P2P_GO)
15651 return -EOPNOTSUPP;
15653 nla = info->attrs[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED];
15654 enabled = nla_get_flag(nla);
15656 return rdev_set_multicast_to_unicast(rdev, dev, enabled);
15659 static int nl80211_set_pmk(struct sk_buff *skb, struct genl_info *info)
15661 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15662 struct net_device *dev = info->user_ptr[1];
15663 struct wireless_dev *wdev = dev->ieee80211_ptr;
15664 struct cfg80211_pmk_conf pmk_conf = {};
15666 if (wdev->iftype != NL80211_IFTYPE_STATION &&
15667 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
15668 return -EOPNOTSUPP;
15670 if (!wiphy_ext_feature_isset(&rdev->wiphy,
15671 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
15672 return -EOPNOTSUPP;
15674 if (!info->attrs[NL80211_ATTR_MAC] || !info->attrs[NL80211_ATTR_PMK])
15675 return -EINVAL;
15677 if (!wdev->connected)
15678 return -ENOTCONN;
15680 pmk_conf.aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
15681 if (memcmp(pmk_conf.aa, wdev->u.client.connected_addr, ETH_ALEN))
15682 return -EINVAL;
15684 pmk_conf.pmk = nla_data(info->attrs[NL80211_ATTR_PMK]);
15685 pmk_conf.pmk_len = nla_len(info->attrs[NL80211_ATTR_PMK]);
15686 if (pmk_conf.pmk_len != WLAN_PMK_LEN &&
15687 pmk_conf.pmk_len != WLAN_PMK_LEN_SUITE_B_192)
15688 return -EINVAL;
15690 if (info->attrs[NL80211_ATTR_PMKR0_NAME])
15691 pmk_conf.pmk_r0_name =
15692 nla_data(info->attrs[NL80211_ATTR_PMKR0_NAME]);
15694 return rdev_set_pmk(rdev, dev, &pmk_conf);
15697 static int nl80211_del_pmk(struct sk_buff *skb, struct genl_info *info)
15699 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15700 struct net_device *dev = info->user_ptr[1];
15701 struct wireless_dev *wdev = dev->ieee80211_ptr;
15702 const u8 *aa;
15704 if (wdev->iftype != NL80211_IFTYPE_STATION &&
15705 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
15706 return -EOPNOTSUPP;
15708 if (!wiphy_ext_feature_isset(&rdev->wiphy,
15709 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X))
15710 return -EOPNOTSUPP;
15712 if (!info->attrs[NL80211_ATTR_MAC])
15713 return -EINVAL;
15715 aa = nla_data(info->attrs[NL80211_ATTR_MAC]);
15716 return rdev_del_pmk(rdev, dev, aa);
15719 static int nl80211_external_auth(struct sk_buff *skb, struct genl_info *info)
15721 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15722 struct net_device *dev = info->user_ptr[1];
15723 struct cfg80211_external_auth_params params;
15725 if (!rdev->ops->external_auth)
15726 return -EOPNOTSUPP;
15728 if (!info->attrs[NL80211_ATTR_SSID] &&
15729 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
15730 dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
15731 return -EINVAL;
15733 if (!info->attrs[NL80211_ATTR_BSSID])
15734 return -EINVAL;
15736 if (!info->attrs[NL80211_ATTR_STATUS_CODE])
15737 return -EINVAL;
15739 memset(&params, 0, sizeof(params));
15741 if (info->attrs[NL80211_ATTR_SSID]) {
15742 params.ssid.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
15743 if (params.ssid.ssid_len == 0)
15744 return -EINVAL;
15745 memcpy(params.ssid.ssid,
15746 nla_data(info->attrs[NL80211_ATTR_SSID]),
15747 params.ssid.ssid_len);
15750 memcpy(params.bssid, nla_data(info->attrs[NL80211_ATTR_BSSID]),
15751 ETH_ALEN);
15753 params.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
15755 if (info->attrs[NL80211_ATTR_PMKID])
15756 params.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]);
15758 return rdev_external_auth(rdev, dev, &params);
15761 static int nl80211_tx_control_port(struct sk_buff *skb, struct genl_info *info)
15763 bool dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
15764 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15765 struct net_device *dev = info->user_ptr[1];
15766 struct wireless_dev *wdev = dev->ieee80211_ptr;
15767 const u8 *buf;
15768 size_t len;
15769 u8 *dest;
15770 u16 proto;
15771 bool noencrypt;
15772 u64 cookie = 0;
15773 int link_id;
15774 int err;
15776 if (!wiphy_ext_feature_isset(&rdev->wiphy,
15777 NL80211_EXT_FEATURE_CONTROL_PORT_OVER_NL80211))
15778 return -EOPNOTSUPP;
15780 if (!rdev->ops->tx_control_port)
15781 return -EOPNOTSUPP;
15783 if (!info->attrs[NL80211_ATTR_FRAME] ||
15784 !info->attrs[NL80211_ATTR_MAC] ||
15785 !info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) {
15786 GENL_SET_ERR_MSG(info, "Frame, MAC or ethertype missing");
15787 return -EINVAL;
15790 switch (wdev->iftype) {
15791 case NL80211_IFTYPE_AP:
15792 case NL80211_IFTYPE_P2P_GO:
15793 case NL80211_IFTYPE_MESH_POINT:
15794 break;
15795 case NL80211_IFTYPE_ADHOC:
15796 if (wdev->u.ibss.current_bss)
15797 break;
15798 return -ENOTCONN;
15799 case NL80211_IFTYPE_STATION:
15800 case NL80211_IFTYPE_P2P_CLIENT:
15801 if (wdev->connected)
15802 break;
15803 return -ENOTCONN;
15804 default:
15805 return -EOPNOTSUPP;
15808 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
15809 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
15810 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
15811 proto = nla_get_u16(info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]);
15812 noencrypt =
15813 nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]);
15815 link_id = nl80211_link_id_or_invalid(info->attrs);
15817 err = rdev_tx_control_port(rdev, dev, buf, len,
15818 dest, cpu_to_be16(proto), noencrypt, link_id,
15819 dont_wait_for_ack ? NULL : &cookie);
15820 if (!err && !dont_wait_for_ack)
15821 nl_set_extack_cookie_u64(info->extack, cookie);
15822 return err;
15825 static int nl80211_get_ftm_responder_stats(struct sk_buff *skb,
15826 struct genl_info *info)
15828 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15829 struct net_device *dev = info->user_ptr[1];
15830 struct wireless_dev *wdev = dev->ieee80211_ptr;
15831 struct cfg80211_ftm_responder_stats ftm_stats = {};
15832 unsigned int link_id = nl80211_link_id(info->attrs);
15833 struct sk_buff *msg;
15834 void *hdr;
15835 struct nlattr *ftm_stats_attr;
15836 int err;
15838 if (wdev->iftype != NL80211_IFTYPE_AP ||
15839 !wdev->links[link_id].ap.beacon_interval)
15840 return -EOPNOTSUPP;
15842 err = rdev_get_ftm_responder_stats(rdev, dev, &ftm_stats);
15843 if (err)
15844 return err;
15846 if (!ftm_stats.filled)
15847 return -ENODATA;
15849 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
15850 if (!msg)
15851 return -ENOMEM;
15853 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
15854 NL80211_CMD_GET_FTM_RESPONDER_STATS);
15855 if (!hdr)
15856 goto nla_put_failure;
15858 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
15859 goto nla_put_failure;
15861 ftm_stats_attr = nla_nest_start_noflag(msg,
15862 NL80211_ATTR_FTM_RESPONDER_STATS);
15863 if (!ftm_stats_attr)
15864 goto nla_put_failure;
15866 #define SET_FTM(field, name, type) \
15867 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
15868 nla_put_ ## type(msg, NL80211_FTM_STATS_ ## name, \
15869 ftm_stats.field)) \
15870 goto nla_put_failure; } while (0)
15871 #define SET_FTM_U64(field, name) \
15872 do { if ((ftm_stats.filled & BIT(NL80211_FTM_STATS_ ## name)) && \
15873 nla_put_u64_64bit(msg, NL80211_FTM_STATS_ ## name, \
15874 ftm_stats.field, NL80211_FTM_STATS_PAD)) \
15875 goto nla_put_failure; } while (0)
15877 SET_FTM(success_num, SUCCESS_NUM, u32);
15878 SET_FTM(partial_num, PARTIAL_NUM, u32);
15879 SET_FTM(failed_num, FAILED_NUM, u32);
15880 SET_FTM(asap_num, ASAP_NUM, u32);
15881 SET_FTM(non_asap_num, NON_ASAP_NUM, u32);
15882 SET_FTM_U64(total_duration_ms, TOTAL_DURATION_MSEC);
15883 SET_FTM(unknown_triggers_num, UNKNOWN_TRIGGERS_NUM, u32);
15884 SET_FTM(reschedule_requests_num, RESCHEDULE_REQUESTS_NUM, u32);
15885 SET_FTM(out_of_window_triggers_num, OUT_OF_WINDOW_TRIGGERS_NUM, u32);
15886 #undef SET_FTM
15888 nla_nest_end(msg, ftm_stats_attr);
15890 genlmsg_end(msg, hdr);
15891 return genlmsg_reply(msg, info);
15893 nla_put_failure:
15894 nlmsg_free(msg);
15895 return -ENOBUFS;
15898 static int nl80211_update_owe_info(struct sk_buff *skb, struct genl_info *info)
15900 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15901 struct cfg80211_update_owe_info owe_info;
15902 struct net_device *dev = info->user_ptr[1];
15904 if (!rdev->ops->update_owe_info)
15905 return -EOPNOTSUPP;
15907 if (!info->attrs[NL80211_ATTR_STATUS_CODE] ||
15908 !info->attrs[NL80211_ATTR_MAC])
15909 return -EINVAL;
15911 memset(&owe_info, 0, sizeof(owe_info));
15912 owe_info.status = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
15913 nla_memcpy(owe_info.peer, info->attrs[NL80211_ATTR_MAC], ETH_ALEN);
15915 if (info->attrs[NL80211_ATTR_IE]) {
15916 owe_info.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
15917 owe_info.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
15920 return rdev_update_owe_info(rdev, dev, &owe_info);
15923 static int nl80211_probe_mesh_link(struct sk_buff *skb, struct genl_info *info)
15925 struct cfg80211_registered_device *rdev = info->user_ptr[0];
15926 struct net_device *dev = info->user_ptr[1];
15927 struct wireless_dev *wdev = dev->ieee80211_ptr;
15928 struct station_info sinfo = {};
15929 const u8 *buf;
15930 size_t len;
15931 u8 *dest;
15932 int err;
15934 if (!rdev->ops->probe_mesh_link || !rdev->ops->get_station)
15935 return -EOPNOTSUPP;
15937 if (!info->attrs[NL80211_ATTR_MAC] ||
15938 !info->attrs[NL80211_ATTR_FRAME]) {
15939 GENL_SET_ERR_MSG(info, "Frame or MAC missing");
15940 return -EINVAL;
15943 if (wdev->iftype != NL80211_IFTYPE_MESH_POINT)
15944 return -EOPNOTSUPP;
15946 dest = nla_data(info->attrs[NL80211_ATTR_MAC]);
15947 buf = nla_data(info->attrs[NL80211_ATTR_FRAME]);
15948 len = nla_len(info->attrs[NL80211_ATTR_FRAME]);
15950 if (len < sizeof(struct ethhdr))
15951 return -EINVAL;
15953 if (!ether_addr_equal(buf, dest) || is_multicast_ether_addr(buf) ||
15954 !ether_addr_equal(buf + ETH_ALEN, dev->dev_addr))
15955 return -EINVAL;
15957 err = rdev_get_station(rdev, dev, dest, &sinfo);
15958 if (err)
15959 return err;
15961 cfg80211_sinfo_release_content(&sinfo);
15963 return rdev_probe_mesh_link(rdev, dev, dest, buf, len);
15966 static int parse_tid_conf(struct cfg80211_registered_device *rdev,
15967 struct nlattr *attrs[], struct net_device *dev,
15968 struct cfg80211_tid_cfg *tid_conf,
15969 struct genl_info *info, const u8 *peer,
15970 unsigned int link_id)
15972 struct netlink_ext_ack *extack = info->extack;
15973 u64 mask;
15974 int err;
15976 if (!attrs[NL80211_TID_CONFIG_ATTR_TIDS])
15977 return -EINVAL;
15979 tid_conf->config_override =
15980 nla_get_flag(attrs[NL80211_TID_CONFIG_ATTR_OVERRIDE]);
15981 tid_conf->tids = nla_get_u16(attrs[NL80211_TID_CONFIG_ATTR_TIDS]);
15983 if (tid_conf->config_override) {
15984 if (rdev->ops->reset_tid_config) {
15985 err = rdev_reset_tid_config(rdev, dev, peer,
15986 tid_conf->tids);
15987 if (err)
15988 return err;
15989 } else {
15990 return -EINVAL;
15994 if (attrs[NL80211_TID_CONFIG_ATTR_NOACK]) {
15995 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_NOACK);
15996 tid_conf->noack =
15997 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_NOACK]);
16000 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]) {
16001 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_SHORT);
16002 tid_conf->retry_short =
16003 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_SHORT]);
16005 if (tid_conf->retry_short > rdev->wiphy.max_data_retry_count)
16006 return -EINVAL;
16009 if (attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]) {
16010 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RETRY_LONG);
16011 tid_conf->retry_long =
16012 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RETRY_LONG]);
16014 if (tid_conf->retry_long > rdev->wiphy.max_data_retry_count)
16015 return -EINVAL;
16018 if (attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]) {
16019 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMPDU_CTRL);
16020 tid_conf->ampdu =
16021 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMPDU_CTRL]);
16024 if (attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]) {
16025 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL);
16026 tid_conf->rtscts =
16027 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL]);
16030 if (attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]) {
16031 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_AMSDU_CTRL);
16032 tid_conf->amsdu =
16033 nla_get_u8(attrs[NL80211_TID_CONFIG_ATTR_AMSDU_CTRL]);
16036 if (attrs[NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE]) {
16037 u32 idx = NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE, attr;
16039 tid_conf->txrate_type = nla_get_u8(attrs[idx]);
16041 if (tid_conf->txrate_type != NL80211_TX_RATE_AUTOMATIC) {
16042 attr = NL80211_TID_CONFIG_ATTR_TX_RATE;
16043 err = nl80211_parse_tx_bitrate_mask(info, attrs, attr,
16044 &tid_conf->txrate_mask, dev,
16045 true, link_id);
16046 if (err)
16047 return err;
16049 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE);
16051 tid_conf->mask |= BIT(NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE);
16054 if (peer)
16055 mask = rdev->wiphy.tid_config_support.peer;
16056 else
16057 mask = rdev->wiphy.tid_config_support.vif;
16059 if (tid_conf->mask & ~mask) {
16060 NL_SET_ERR_MSG(extack, "unsupported TID configuration");
16061 return -EOPNOTSUPP;
16064 return 0;
16067 static int nl80211_set_tid_config(struct sk_buff *skb,
16068 struct genl_info *info)
16070 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16071 struct nlattr *attrs[NL80211_TID_CONFIG_ATTR_MAX + 1];
16072 unsigned int link_id = nl80211_link_id(info->attrs);
16073 struct net_device *dev = info->user_ptr[1];
16074 struct cfg80211_tid_config *tid_config;
16075 struct nlattr *tid;
16076 int conf_idx = 0, rem_conf;
16077 int ret = -EINVAL;
16078 u32 num_conf = 0;
16080 if (!info->attrs[NL80211_ATTR_TID_CONFIG])
16081 return -EINVAL;
16083 if (!rdev->ops->set_tid_config)
16084 return -EOPNOTSUPP;
16086 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
16087 rem_conf)
16088 num_conf++;
16090 tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf),
16091 GFP_KERNEL);
16092 if (!tid_config)
16093 return -ENOMEM;
16095 tid_config->n_tid_conf = num_conf;
16097 if (info->attrs[NL80211_ATTR_MAC])
16098 tid_config->peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
16100 nla_for_each_nested(tid, info->attrs[NL80211_ATTR_TID_CONFIG],
16101 rem_conf) {
16102 ret = nla_parse_nested(attrs, NL80211_TID_CONFIG_ATTR_MAX,
16103 tid, NULL, NULL);
16105 if (ret)
16106 goto bad_tid_conf;
16108 ret = parse_tid_conf(rdev, attrs, dev,
16109 &tid_config->tid_conf[conf_idx],
16110 info, tid_config->peer, link_id);
16111 if (ret)
16112 goto bad_tid_conf;
16114 conf_idx++;
16117 ret = rdev_set_tid_config(rdev, dev, tid_config);
16119 bad_tid_conf:
16120 kfree(tid_config);
16121 return ret;
16124 static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info)
16126 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16127 struct cfg80211_color_change_settings params = {};
16128 struct net_device *dev = info->user_ptr[1];
16129 struct wireless_dev *wdev = dev->ieee80211_ptr;
16130 struct nlattr **tb;
16131 u16 offset;
16132 int err;
16134 if (!rdev->ops->color_change)
16135 return -EOPNOTSUPP;
16137 if (!wiphy_ext_feature_isset(&rdev->wiphy,
16138 NL80211_EXT_FEATURE_BSS_COLOR))
16139 return -EOPNOTSUPP;
16141 if (wdev->iftype != NL80211_IFTYPE_AP)
16142 return -EOPNOTSUPP;
16144 if (!info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT] ||
16145 !info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR] ||
16146 !info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS])
16147 return -EINVAL;
16149 params.count = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COUNT]);
16150 params.color = nla_get_u8(info->attrs[NL80211_ATTR_COLOR_CHANGE_COLOR]);
16152 err = nl80211_parse_beacon(rdev, info->attrs, &params.beacon_next,
16153 info->extack);
16154 if (err)
16155 return err;
16157 tb = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*tb), GFP_KERNEL);
16158 if (!tb)
16159 return -ENOMEM;
16161 err = nla_parse_nested(tb, NL80211_ATTR_MAX,
16162 info->attrs[NL80211_ATTR_COLOR_CHANGE_ELEMS],
16163 nl80211_policy, info->extack);
16164 if (err)
16165 goto out;
16167 err = nl80211_parse_beacon(rdev, tb, &params.beacon_color_change,
16168 info->extack);
16169 if (err)
16170 goto out;
16172 if (!tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) {
16173 err = -EINVAL;
16174 goto out;
16177 if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]) != sizeof(u16)) {
16178 err = -EINVAL;
16179 goto out;
16182 offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_BEACON]);
16183 if (offset >= params.beacon_color_change.tail_len) {
16184 err = -EINVAL;
16185 goto out;
16188 if (params.beacon_color_change.tail[offset] != params.count) {
16189 err = -EINVAL;
16190 goto out;
16193 params.counter_offset_beacon = offset;
16195 if (tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) {
16196 if (nla_len(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]) !=
16197 sizeof(u16)) {
16198 err = -EINVAL;
16199 goto out;
16202 offset = nla_get_u16(tb[NL80211_ATTR_CNTDWN_OFFS_PRESP]);
16203 if (offset >= params.beacon_color_change.probe_resp_len) {
16204 err = -EINVAL;
16205 goto out;
16208 if (params.beacon_color_change.probe_resp[offset] !=
16209 params.count) {
16210 err = -EINVAL;
16211 goto out;
16214 params.counter_offset_presp = offset;
16217 params.link_id = nl80211_link_id(info->attrs);
16218 err = rdev_color_change(rdev, dev, &params);
16220 out:
16221 kfree(params.beacon_next.mbssid_ies);
16222 kfree(params.beacon_color_change.mbssid_ies);
16223 kfree(params.beacon_next.rnr_ies);
16224 kfree(params.beacon_color_change.rnr_ies);
16225 kfree(tb);
16226 return err;
16229 static int nl80211_set_fils_aad(struct sk_buff *skb,
16230 struct genl_info *info)
16232 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16233 struct net_device *dev = info->user_ptr[1];
16234 struct cfg80211_fils_aad fils_aad = {};
16235 u8 *nonces;
16237 if (!info->attrs[NL80211_ATTR_MAC] ||
16238 !info->attrs[NL80211_ATTR_FILS_KEK] ||
16239 !info->attrs[NL80211_ATTR_FILS_NONCES])
16240 return -EINVAL;
16242 fils_aad.macaddr = nla_data(info->attrs[NL80211_ATTR_MAC]);
16243 fils_aad.kek_len = nla_len(info->attrs[NL80211_ATTR_FILS_KEK]);
16244 fils_aad.kek = nla_data(info->attrs[NL80211_ATTR_FILS_KEK]);
16245 nonces = nla_data(info->attrs[NL80211_ATTR_FILS_NONCES]);
16246 fils_aad.snonce = nonces;
16247 fils_aad.anonce = nonces + FILS_NONCE_LEN;
16249 return rdev_set_fils_aad(rdev, dev, &fils_aad);
16252 static int nl80211_add_link(struct sk_buff *skb, struct genl_info *info)
16254 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16255 unsigned int link_id = nl80211_link_id(info->attrs);
16256 struct net_device *dev = info->user_ptr[1];
16257 struct wireless_dev *wdev = dev->ieee80211_ptr;
16258 int ret;
16260 if (!(wdev->wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO))
16261 return -EINVAL;
16263 switch (wdev->iftype) {
16264 case NL80211_IFTYPE_AP:
16265 break;
16266 default:
16267 return -EINVAL;
16270 if (!info->attrs[NL80211_ATTR_MAC] ||
16271 !is_valid_ether_addr(nla_data(info->attrs[NL80211_ATTR_MAC])))
16272 return -EINVAL;
16274 wdev->valid_links |= BIT(link_id);
16275 ether_addr_copy(wdev->links[link_id].addr,
16276 nla_data(info->attrs[NL80211_ATTR_MAC]));
16278 ret = rdev_add_intf_link(rdev, wdev, link_id);
16279 if (ret) {
16280 wdev->valid_links &= ~BIT(link_id);
16281 eth_zero_addr(wdev->links[link_id].addr);
16284 return ret;
16287 static int nl80211_remove_link(struct sk_buff *skb, struct genl_info *info)
16289 unsigned int link_id = nl80211_link_id(info->attrs);
16290 struct net_device *dev = info->user_ptr[1];
16291 struct wireless_dev *wdev = dev->ieee80211_ptr;
16293 /* cannot remove if there's no link */
16294 if (!info->attrs[NL80211_ATTR_MLO_LINK_ID])
16295 return -EINVAL;
16297 switch (wdev->iftype) {
16298 case NL80211_IFTYPE_AP:
16299 break;
16300 default:
16301 return -EINVAL;
16304 cfg80211_remove_link(wdev, link_id);
16306 return 0;
16309 static int
16310 nl80211_add_mod_link_station(struct sk_buff *skb, struct genl_info *info,
16311 bool add)
16313 struct link_station_parameters params = {};
16314 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16315 struct net_device *dev = info->user_ptr[1];
16316 int err;
16318 if ((add && !rdev->ops->add_link_station) ||
16319 (!add && !rdev->ops->mod_link_station))
16320 return -EOPNOTSUPP;
16322 if (add && !info->attrs[NL80211_ATTR_MAC])
16323 return -EINVAL;
16325 if (!info->attrs[NL80211_ATTR_MLD_ADDR])
16326 return -EINVAL;
16328 if (add && !info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES])
16329 return -EINVAL;
16331 params.mld_mac = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
16333 if (info->attrs[NL80211_ATTR_MAC]) {
16334 params.link_mac = nla_data(info->attrs[NL80211_ATTR_MAC]);
16335 if (!is_valid_ether_addr(params.link_mac))
16336 return -EINVAL;
16339 if (!info->attrs[NL80211_ATTR_MLO_LINK_ID])
16340 return -EINVAL;
16342 params.link_id = nla_get_u8(info->attrs[NL80211_ATTR_MLO_LINK_ID]);
16344 if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) {
16345 params.supported_rates =
16346 nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
16347 params.supported_rates_len =
16348 nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
16351 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
16352 params.ht_capa =
16353 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
16355 if (info->attrs[NL80211_ATTR_VHT_CAPABILITY])
16356 params.vht_capa =
16357 nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]);
16359 if (info->attrs[NL80211_ATTR_HE_CAPABILITY]) {
16360 params.he_capa =
16361 nla_data(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
16362 params.he_capa_len =
16363 nla_len(info->attrs[NL80211_ATTR_HE_CAPABILITY]);
16365 if (info->attrs[NL80211_ATTR_EHT_CAPABILITY]) {
16366 params.eht_capa =
16367 nla_data(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
16368 params.eht_capa_len =
16369 nla_len(info->attrs[NL80211_ATTR_EHT_CAPABILITY]);
16371 if (!ieee80211_eht_capa_size_ok((const u8 *)params.he_capa,
16372 (const u8 *)params.eht_capa,
16373 params.eht_capa_len,
16374 false))
16375 return -EINVAL;
16379 if (info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY])
16380 params.he_6ghz_capa =
16381 nla_data(info->attrs[NL80211_ATTR_HE_6GHZ_CAPABILITY]);
16383 if (info->attrs[NL80211_ATTR_OPMODE_NOTIF]) {
16384 params.opmode_notif_used = true;
16385 params.opmode_notif =
16386 nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]);
16389 err = nl80211_parse_sta_txpower_setting(info, &params.txpwr,
16390 &params.txpwr_set);
16391 if (err)
16392 return err;
16394 if (add)
16395 return rdev_add_link_station(rdev, dev, &params);
16397 return rdev_mod_link_station(rdev, dev, &params);
16400 static int
16401 nl80211_add_link_station(struct sk_buff *skb, struct genl_info *info)
16403 return nl80211_add_mod_link_station(skb, info, true);
16406 static int
16407 nl80211_modify_link_station(struct sk_buff *skb, struct genl_info *info)
16409 return nl80211_add_mod_link_station(skb, info, false);
16412 static int
16413 nl80211_remove_link_station(struct sk_buff *skb, struct genl_info *info)
16415 struct link_station_del_parameters params = {};
16416 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16417 struct net_device *dev = info->user_ptr[1];
16419 if (!rdev->ops->del_link_station)
16420 return -EOPNOTSUPP;
16422 if (!info->attrs[NL80211_ATTR_MLD_ADDR] ||
16423 !info->attrs[NL80211_ATTR_MLO_LINK_ID])
16424 return -EINVAL;
16426 params.mld_mac = nla_data(info->attrs[NL80211_ATTR_MLD_ADDR]);
16427 params.link_id = nla_get_u8(info->attrs[NL80211_ATTR_MLO_LINK_ID]);
16429 return rdev_del_link_station(rdev, dev, &params);
16432 static int nl80211_set_hw_timestamp(struct sk_buff *skb,
16433 struct genl_info *info)
16435 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16436 struct net_device *dev = info->user_ptr[1];
16437 struct cfg80211_set_hw_timestamp hwts = {};
16439 if (!rdev->wiphy.hw_timestamp_max_peers)
16440 return -EOPNOTSUPP;
16442 if (!info->attrs[NL80211_ATTR_MAC] &&
16443 rdev->wiphy.hw_timestamp_max_peers != CFG80211_HW_TIMESTAMP_ALL_PEERS)
16444 return -EOPNOTSUPP;
16446 if (info->attrs[NL80211_ATTR_MAC])
16447 hwts.macaddr = nla_data(info->attrs[NL80211_ATTR_MAC]);
16449 hwts.enable =
16450 nla_get_flag(info->attrs[NL80211_ATTR_HW_TIMESTAMP_ENABLED]);
16452 return rdev_set_hw_timestamp(rdev, dev, &hwts);
16455 static int
16456 nl80211_set_ttlm(struct sk_buff *skb, struct genl_info *info)
16458 struct cfg80211_ttlm_params params = {};
16459 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16460 struct net_device *dev = info->user_ptr[1];
16461 struct wireless_dev *wdev = dev->ieee80211_ptr;
16463 if (wdev->iftype != NL80211_IFTYPE_STATION &&
16464 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
16465 return -EOPNOTSUPP;
16467 if (!wdev->connected)
16468 return -ENOLINK;
16470 if (!info->attrs[NL80211_ATTR_MLO_TTLM_DLINK] ||
16471 !info->attrs[NL80211_ATTR_MLO_TTLM_ULINK])
16472 return -EINVAL;
16474 nla_memcpy(params.dlink,
16475 info->attrs[NL80211_ATTR_MLO_TTLM_DLINK],
16476 sizeof(params.dlink));
16477 nla_memcpy(params.ulink,
16478 info->attrs[NL80211_ATTR_MLO_TTLM_ULINK],
16479 sizeof(params.ulink));
16481 return rdev_set_ttlm(rdev, dev, &params);
16484 #define NL80211_FLAG_NEED_WIPHY 0x01
16485 #define NL80211_FLAG_NEED_NETDEV 0x02
16486 #define NL80211_FLAG_NEED_RTNL 0x04
16487 #define NL80211_FLAG_CHECK_NETDEV_UP 0x08
16488 #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\
16489 NL80211_FLAG_CHECK_NETDEV_UP)
16490 #define NL80211_FLAG_NEED_WDEV 0x10
16491 /* If a netdev is associated, it must be UP, P2P must be started */
16492 #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\
16493 NL80211_FLAG_CHECK_NETDEV_UP)
16494 #define NL80211_FLAG_CLEAR_SKB 0x20
16495 #define NL80211_FLAG_NO_WIPHY_MTX 0x40
16496 #define NL80211_FLAG_MLO_VALID_LINK_ID 0x80
16497 #define NL80211_FLAG_MLO_UNSUPPORTED 0x100
16499 #define INTERNAL_FLAG_SELECTORS(__sel) \
16500 SELECTOR(__sel, NONE, 0) /* must be first */ \
16501 SELECTOR(__sel, WIPHY, \
16502 NL80211_FLAG_NEED_WIPHY) \
16503 SELECTOR(__sel, WDEV, \
16504 NL80211_FLAG_NEED_WDEV) \
16505 SELECTOR(__sel, NETDEV, \
16506 NL80211_FLAG_NEED_NETDEV) \
16507 SELECTOR(__sel, NETDEV_LINK, \
16508 NL80211_FLAG_NEED_NETDEV | \
16509 NL80211_FLAG_MLO_VALID_LINK_ID) \
16510 SELECTOR(__sel, NETDEV_NO_MLO, \
16511 NL80211_FLAG_NEED_NETDEV | \
16512 NL80211_FLAG_MLO_UNSUPPORTED) \
16513 SELECTOR(__sel, WIPHY_RTNL, \
16514 NL80211_FLAG_NEED_WIPHY | \
16515 NL80211_FLAG_NEED_RTNL) \
16516 SELECTOR(__sel, WIPHY_RTNL_NOMTX, \
16517 NL80211_FLAG_NEED_WIPHY | \
16518 NL80211_FLAG_NEED_RTNL | \
16519 NL80211_FLAG_NO_WIPHY_MTX) \
16520 SELECTOR(__sel, WDEV_RTNL, \
16521 NL80211_FLAG_NEED_WDEV | \
16522 NL80211_FLAG_NEED_RTNL) \
16523 SELECTOR(__sel, NETDEV_RTNL, \
16524 NL80211_FLAG_NEED_NETDEV | \
16525 NL80211_FLAG_NEED_RTNL) \
16526 SELECTOR(__sel, NETDEV_UP, \
16527 NL80211_FLAG_NEED_NETDEV_UP) \
16528 SELECTOR(__sel, NETDEV_UP_LINK, \
16529 NL80211_FLAG_NEED_NETDEV_UP | \
16530 NL80211_FLAG_MLO_VALID_LINK_ID) \
16531 SELECTOR(__sel, NETDEV_UP_NO_MLO, \
16532 NL80211_FLAG_NEED_NETDEV_UP | \
16533 NL80211_FLAG_MLO_UNSUPPORTED) \
16534 SELECTOR(__sel, NETDEV_UP_NO_MLO_CLEAR, \
16535 NL80211_FLAG_NEED_NETDEV_UP | \
16536 NL80211_FLAG_CLEAR_SKB | \
16537 NL80211_FLAG_MLO_UNSUPPORTED) \
16538 SELECTOR(__sel, NETDEV_UP_NOTMX, \
16539 NL80211_FLAG_NEED_NETDEV_UP | \
16540 NL80211_FLAG_NO_WIPHY_MTX) \
16541 SELECTOR(__sel, NETDEV_UP_NOTMX_MLO, \
16542 NL80211_FLAG_NEED_NETDEV_UP | \
16543 NL80211_FLAG_NO_WIPHY_MTX | \
16544 NL80211_FLAG_MLO_VALID_LINK_ID) \
16545 SELECTOR(__sel, NETDEV_UP_CLEAR, \
16546 NL80211_FLAG_NEED_NETDEV_UP | \
16547 NL80211_FLAG_CLEAR_SKB) \
16548 SELECTOR(__sel, WDEV_UP, \
16549 NL80211_FLAG_NEED_WDEV_UP) \
16550 SELECTOR(__sel, WDEV_UP_LINK, \
16551 NL80211_FLAG_NEED_WDEV_UP | \
16552 NL80211_FLAG_MLO_VALID_LINK_ID) \
16553 SELECTOR(__sel, WDEV_UP_RTNL, \
16554 NL80211_FLAG_NEED_WDEV_UP | \
16555 NL80211_FLAG_NEED_RTNL) \
16556 SELECTOR(__sel, WIPHY_CLEAR, \
16557 NL80211_FLAG_NEED_WIPHY | \
16558 NL80211_FLAG_CLEAR_SKB)
16560 enum nl80211_internal_flags_selector {
16561 #define SELECTOR(_, name, value) NL80211_IFL_SEL_##name,
16562 INTERNAL_FLAG_SELECTORS(_)
16563 #undef SELECTOR
16566 static u32 nl80211_internal_flags[] = {
16567 #define SELECTOR(_, name, value) [NL80211_IFL_SEL_##name] = value,
16568 INTERNAL_FLAG_SELECTORS(_)
16569 #undef SELECTOR
16572 static int nl80211_pre_doit(const struct genl_split_ops *ops,
16573 struct sk_buff *skb,
16574 struct genl_info *info)
16576 struct cfg80211_registered_device *rdev = NULL;
16577 struct wireless_dev *wdev = NULL;
16578 struct net_device *dev = NULL;
16579 u32 internal_flags;
16580 int err;
16582 if (WARN_ON(ops->internal_flags >= ARRAY_SIZE(nl80211_internal_flags)))
16583 return -EINVAL;
16585 internal_flags = nl80211_internal_flags[ops->internal_flags];
16587 rtnl_lock();
16588 if (internal_flags & NL80211_FLAG_NEED_WIPHY) {
16589 rdev = cfg80211_get_dev_from_info(genl_info_net(info), info);
16590 if (IS_ERR(rdev)) {
16591 err = PTR_ERR(rdev);
16592 goto out_unlock;
16594 info->user_ptr[0] = rdev;
16595 } else if (internal_flags & NL80211_FLAG_NEED_NETDEV ||
16596 internal_flags & NL80211_FLAG_NEED_WDEV) {
16597 wdev = __cfg80211_wdev_from_attrs(NULL, genl_info_net(info),
16598 info->attrs);
16599 if (IS_ERR(wdev)) {
16600 err = PTR_ERR(wdev);
16601 goto out_unlock;
16604 dev = wdev->netdev;
16605 dev_hold(dev);
16606 rdev = wiphy_to_rdev(wdev->wiphy);
16608 if (internal_flags & NL80211_FLAG_NEED_NETDEV) {
16609 if (!dev) {
16610 err = -EINVAL;
16611 goto out_unlock;
16614 info->user_ptr[1] = dev;
16615 } else {
16616 info->user_ptr[1] = wdev;
16619 if (internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
16620 !wdev_running(wdev)) {
16621 err = -ENETDOWN;
16622 goto out_unlock;
16625 info->user_ptr[0] = rdev;
16628 if (internal_flags & NL80211_FLAG_MLO_VALID_LINK_ID) {
16629 struct nlattr *link_id = info->attrs[NL80211_ATTR_MLO_LINK_ID];
16631 if (!wdev) {
16632 err = -EINVAL;
16633 goto out_unlock;
16636 /* MLO -> require valid link ID */
16637 if (wdev->valid_links &&
16638 (!link_id ||
16639 !(wdev->valid_links & BIT(nla_get_u8(link_id))))) {
16640 err = -EINVAL;
16641 goto out_unlock;
16644 /* non-MLO -> no link ID attribute accepted */
16645 if (!wdev->valid_links && link_id) {
16646 err = -EINVAL;
16647 goto out_unlock;
16651 if (internal_flags & NL80211_FLAG_MLO_UNSUPPORTED) {
16652 if (info->attrs[NL80211_ATTR_MLO_LINK_ID] ||
16653 (wdev && wdev->valid_links)) {
16654 err = -EINVAL;
16655 goto out_unlock;
16659 if (rdev && !(internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
16660 wiphy_lock(&rdev->wiphy);
16661 /* we keep the mutex locked until post_doit */
16662 __release(&rdev->wiphy.mtx);
16664 if (!(internal_flags & NL80211_FLAG_NEED_RTNL))
16665 rtnl_unlock();
16667 return 0;
16668 out_unlock:
16669 rtnl_unlock();
16670 dev_put(dev);
16671 return err;
16674 static void nl80211_post_doit(const struct genl_split_ops *ops,
16675 struct sk_buff *skb,
16676 struct genl_info *info)
16678 u32 internal_flags = nl80211_internal_flags[ops->internal_flags];
16680 if (info->user_ptr[1]) {
16681 if (internal_flags & NL80211_FLAG_NEED_WDEV) {
16682 struct wireless_dev *wdev = info->user_ptr[1];
16684 dev_put(wdev->netdev);
16685 } else {
16686 dev_put(info->user_ptr[1]);
16690 if (info->user_ptr[0] &&
16691 !(internal_flags & NL80211_FLAG_NO_WIPHY_MTX)) {
16692 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16694 /* we kept the mutex locked since pre_doit */
16695 __acquire(&rdev->wiphy.mtx);
16696 wiphy_unlock(&rdev->wiphy);
16699 if (internal_flags & NL80211_FLAG_NEED_RTNL)
16700 rtnl_unlock();
16702 /* If needed, clear the netlink message payload from the SKB
16703 * as it might contain key data that shouldn't stick around on
16704 * the heap after the SKB is freed. The netlink message header
16705 * is still needed for further processing, so leave it intact.
16707 if (internal_flags & NL80211_FLAG_CLEAR_SKB) {
16708 struct nlmsghdr *nlh = nlmsg_hdr(skb);
16710 memset(nlmsg_data(nlh), 0, nlmsg_len(nlh));
16714 static int nl80211_set_sar_sub_specs(struct cfg80211_registered_device *rdev,
16715 struct cfg80211_sar_specs *sar_specs,
16716 struct nlattr *spec[], int index)
16718 u32 range_index, i;
16720 if (!sar_specs || !spec)
16721 return -EINVAL;
16723 if (!spec[NL80211_SAR_ATTR_SPECS_POWER] ||
16724 !spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX])
16725 return -EINVAL;
16727 range_index = nla_get_u32(spec[NL80211_SAR_ATTR_SPECS_RANGE_INDEX]);
16729 /* check if range_index exceeds num_freq_ranges */
16730 if (range_index >= rdev->wiphy.sar_capa->num_freq_ranges)
16731 return -EINVAL;
16733 /* check if range_index duplicates */
16734 for (i = 0; i < index; i++) {
16735 if (sar_specs->sub_specs[i].freq_range_index == range_index)
16736 return -EINVAL;
16739 sar_specs->sub_specs[index].power =
16740 nla_get_s32(spec[NL80211_SAR_ATTR_SPECS_POWER]);
16742 sar_specs->sub_specs[index].freq_range_index = range_index;
16744 return 0;
16747 static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info)
16749 struct cfg80211_registered_device *rdev = info->user_ptr[0];
16750 struct nlattr *spec[NL80211_SAR_ATTR_SPECS_MAX + 1];
16751 struct nlattr *tb[NL80211_SAR_ATTR_MAX + 1];
16752 struct cfg80211_sar_specs *sar_spec;
16753 enum nl80211_sar_type type;
16754 struct nlattr *spec_list;
16755 u32 specs;
16756 int rem, err;
16758 if (!rdev->wiphy.sar_capa || !rdev->ops->set_sar_specs)
16759 return -EOPNOTSUPP;
16761 if (!info->attrs[NL80211_ATTR_SAR_SPEC])
16762 return -EINVAL;
16764 nla_parse_nested(tb, NL80211_SAR_ATTR_MAX,
16765 info->attrs[NL80211_ATTR_SAR_SPEC],
16766 NULL, NULL);
16768 if (!tb[NL80211_SAR_ATTR_TYPE] || !tb[NL80211_SAR_ATTR_SPECS])
16769 return -EINVAL;
16771 type = nla_get_u32(tb[NL80211_SAR_ATTR_TYPE]);
16772 if (type != rdev->wiphy.sar_capa->type)
16773 return -EINVAL;
16775 specs = 0;
16776 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem)
16777 specs++;
16779 if (specs > rdev->wiphy.sar_capa->num_freq_ranges)
16780 return -EINVAL;
16782 sar_spec = kzalloc(struct_size(sar_spec, sub_specs, specs), GFP_KERNEL);
16783 if (!sar_spec)
16784 return -ENOMEM;
16786 sar_spec->type = type;
16787 specs = 0;
16788 nla_for_each_nested(spec_list, tb[NL80211_SAR_ATTR_SPECS], rem) {
16789 nla_parse_nested(spec, NL80211_SAR_ATTR_SPECS_MAX,
16790 spec_list, NULL, NULL);
16792 switch (type) {
16793 case NL80211_SAR_TYPE_POWER:
16794 if (nl80211_set_sar_sub_specs(rdev, sar_spec,
16795 spec, specs)) {
16796 err = -EINVAL;
16797 goto error;
16799 break;
16800 default:
16801 err = -EINVAL;
16802 goto error;
16804 specs++;
16807 sar_spec->num_sub_specs = specs;
16809 rdev->cur_cmd_info = info;
16810 err = rdev_set_sar_specs(rdev, sar_spec);
16811 rdev->cur_cmd_info = NULL;
16812 error:
16813 kfree(sar_spec);
16814 return err;
16817 #define SELECTOR(__sel, name, value) \
16818 ((__sel) == (value)) ? NL80211_IFL_SEL_##name :
16819 int __missing_selector(void);
16820 #define IFLAGS(__val) INTERNAL_FLAG_SELECTORS(__val) __missing_selector()
16822 static const struct genl_ops nl80211_ops[] = {
16824 .cmd = NL80211_CMD_GET_WIPHY,
16825 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16826 .doit = nl80211_get_wiphy,
16827 .dumpit = nl80211_dump_wiphy,
16828 .done = nl80211_dump_wiphy_done,
16829 /* can be retrieved by unprivileged users */
16830 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
16834 static const struct genl_small_ops nl80211_small_ops[] = {
16836 .cmd = NL80211_CMD_SET_WIPHY,
16837 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16838 .doit = nl80211_set_wiphy,
16839 .flags = GENL_UNS_ADMIN_PERM,
16842 .cmd = NL80211_CMD_GET_INTERFACE,
16843 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16844 .doit = nl80211_get_interface,
16845 .dumpit = nl80211_dump_interface,
16846 /* can be retrieved by unprivileged users */
16847 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV),
16850 .cmd = NL80211_CMD_SET_INTERFACE,
16851 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16852 .doit = nl80211_set_interface,
16853 .flags = GENL_UNS_ADMIN_PERM,
16854 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
16855 NL80211_FLAG_NEED_RTNL),
16858 .cmd = NL80211_CMD_NEW_INTERFACE,
16859 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16860 .doit = nl80211_new_interface,
16861 .flags = GENL_UNS_ADMIN_PERM,
16862 .internal_flags =
16863 IFLAGS(NL80211_FLAG_NEED_WIPHY |
16864 NL80211_FLAG_NEED_RTNL |
16865 /* we take the wiphy mutex later ourselves */
16866 NL80211_FLAG_NO_WIPHY_MTX),
16869 .cmd = NL80211_CMD_DEL_INTERFACE,
16870 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16871 .doit = nl80211_del_interface,
16872 .flags = GENL_UNS_ADMIN_PERM,
16873 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV |
16874 NL80211_FLAG_NEED_RTNL),
16877 .cmd = NL80211_CMD_GET_KEY,
16878 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16879 .doit = nl80211_get_key,
16880 .flags = GENL_UNS_ADMIN_PERM,
16881 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16884 .cmd = NL80211_CMD_SET_KEY,
16885 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16886 .doit = nl80211_set_key,
16887 .flags = GENL_UNS_ADMIN_PERM,
16888 /* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on key */
16889 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
16890 NL80211_FLAG_CLEAR_SKB),
16893 .cmd = NL80211_CMD_NEW_KEY,
16894 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16895 .doit = nl80211_new_key,
16896 .flags = GENL_UNS_ADMIN_PERM,
16897 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
16898 NL80211_FLAG_CLEAR_SKB),
16901 .cmd = NL80211_CMD_DEL_KEY,
16902 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16903 .doit = nl80211_del_key,
16904 .flags = GENL_UNS_ADMIN_PERM,
16905 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16908 .cmd = NL80211_CMD_SET_BEACON,
16909 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16910 .flags = GENL_UNS_ADMIN_PERM,
16911 .doit = nl80211_set_beacon,
16912 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
16913 NL80211_FLAG_MLO_VALID_LINK_ID),
16916 .cmd = NL80211_CMD_START_AP,
16917 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16918 .flags = GENL_UNS_ADMIN_PERM,
16919 .doit = nl80211_start_ap,
16920 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
16921 NL80211_FLAG_MLO_VALID_LINK_ID),
16924 .cmd = NL80211_CMD_STOP_AP,
16925 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16926 .flags = GENL_UNS_ADMIN_PERM,
16927 .doit = nl80211_stop_ap,
16928 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
16929 NL80211_FLAG_MLO_VALID_LINK_ID),
16932 .cmd = NL80211_CMD_GET_STATION,
16933 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16934 .doit = nl80211_get_station,
16935 .dumpit = nl80211_dump_station,
16936 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
16939 .cmd = NL80211_CMD_SET_STATION,
16940 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16941 .doit = nl80211_set_station,
16942 .flags = GENL_UNS_ADMIN_PERM,
16943 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16946 .cmd = NL80211_CMD_NEW_STATION,
16947 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16948 .doit = nl80211_new_station,
16949 .flags = GENL_UNS_ADMIN_PERM,
16950 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16953 .cmd = NL80211_CMD_DEL_STATION,
16954 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16955 .doit = nl80211_del_station,
16956 .flags = GENL_UNS_ADMIN_PERM,
16957 /* cannot use NL80211_FLAG_MLO_VALID_LINK_ID, depends on
16958 * whether MAC address is passed or not. If MAC address is
16959 * passed, then even during MLO, link ID is not required.
16961 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16964 .cmd = NL80211_CMD_GET_MPATH,
16965 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16966 .doit = nl80211_get_mpath,
16967 .dumpit = nl80211_dump_mpath,
16968 .flags = GENL_UNS_ADMIN_PERM,
16969 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16972 .cmd = NL80211_CMD_GET_MPP,
16973 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16974 .doit = nl80211_get_mpp,
16975 .dumpit = nl80211_dump_mpp,
16976 .flags = GENL_UNS_ADMIN_PERM,
16977 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16980 .cmd = NL80211_CMD_SET_MPATH,
16981 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16982 .doit = nl80211_set_mpath,
16983 .flags = GENL_UNS_ADMIN_PERM,
16984 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16987 .cmd = NL80211_CMD_NEW_MPATH,
16988 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16989 .doit = nl80211_new_mpath,
16990 .flags = GENL_UNS_ADMIN_PERM,
16991 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
16994 .cmd = NL80211_CMD_DEL_MPATH,
16995 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
16996 .doit = nl80211_del_mpath,
16997 .flags = GENL_UNS_ADMIN_PERM,
16998 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17001 .cmd = NL80211_CMD_SET_BSS,
17002 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17003 .doit = nl80211_set_bss,
17004 .flags = GENL_UNS_ADMIN_PERM,
17005 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17006 NL80211_FLAG_MLO_VALID_LINK_ID),
17009 .cmd = NL80211_CMD_GET_REG,
17010 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17011 .doit = nl80211_get_reg_do,
17012 .dumpit = nl80211_get_reg_dump,
17013 /* can be retrieved by unprivileged users */
17015 #ifdef CONFIG_CFG80211_CRDA_SUPPORT
17017 .cmd = NL80211_CMD_SET_REG,
17018 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17019 .doit = nl80211_set_reg,
17020 .flags = GENL_ADMIN_PERM,
17022 #endif
17024 .cmd = NL80211_CMD_REQ_SET_REG,
17025 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17026 .doit = nl80211_req_set_reg,
17027 .flags = GENL_ADMIN_PERM,
17030 .cmd = NL80211_CMD_RELOAD_REGDB,
17031 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17032 .doit = nl80211_reload_regdb,
17033 .flags = GENL_ADMIN_PERM,
17036 .cmd = NL80211_CMD_GET_MESH_CONFIG,
17037 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17038 .doit = nl80211_get_mesh_config,
17039 /* can be retrieved by unprivileged users */
17040 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17043 .cmd = NL80211_CMD_SET_MESH_CONFIG,
17044 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17045 .doit = nl80211_update_mesh_config,
17046 .flags = GENL_UNS_ADMIN_PERM,
17047 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17050 .cmd = NL80211_CMD_TRIGGER_SCAN,
17051 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17052 .doit = nl80211_trigger_scan,
17053 .flags = GENL_UNS_ADMIN_PERM,
17054 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17057 .cmd = NL80211_CMD_ABORT_SCAN,
17058 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17059 .doit = nl80211_abort_scan,
17060 .flags = GENL_UNS_ADMIN_PERM,
17061 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17064 .cmd = NL80211_CMD_GET_SCAN,
17065 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17066 .dumpit = nl80211_dump_scan,
17069 .cmd = NL80211_CMD_START_SCHED_SCAN,
17070 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17071 .doit = nl80211_start_sched_scan,
17072 .flags = GENL_UNS_ADMIN_PERM,
17073 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17076 .cmd = NL80211_CMD_STOP_SCHED_SCAN,
17077 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17078 .doit = nl80211_stop_sched_scan,
17079 .flags = GENL_UNS_ADMIN_PERM,
17080 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17083 .cmd = NL80211_CMD_AUTHENTICATE,
17084 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17085 .doit = nl80211_authenticate,
17086 .flags = GENL_UNS_ADMIN_PERM,
17087 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17088 NL80211_FLAG_CLEAR_SKB),
17091 .cmd = NL80211_CMD_ASSOCIATE,
17092 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17093 .doit = nl80211_associate,
17094 .flags = GENL_UNS_ADMIN_PERM,
17095 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17096 NL80211_FLAG_CLEAR_SKB),
17099 .cmd = NL80211_CMD_DEAUTHENTICATE,
17100 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17101 .doit = nl80211_deauthenticate,
17102 .flags = GENL_UNS_ADMIN_PERM,
17103 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17106 .cmd = NL80211_CMD_DISASSOCIATE,
17107 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17108 .doit = nl80211_disassociate,
17109 .flags = GENL_UNS_ADMIN_PERM,
17110 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17113 .cmd = NL80211_CMD_JOIN_IBSS,
17114 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17115 .doit = nl80211_join_ibss,
17116 .flags = GENL_UNS_ADMIN_PERM,
17117 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17120 .cmd = NL80211_CMD_LEAVE_IBSS,
17121 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17122 .doit = nl80211_leave_ibss,
17123 .flags = GENL_UNS_ADMIN_PERM,
17124 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17126 #ifdef CONFIG_NL80211_TESTMODE
17128 .cmd = NL80211_CMD_TESTMODE,
17129 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17130 .doit = nl80211_testmode_do,
17131 .dumpit = nl80211_testmode_dump,
17132 .flags = GENL_UNS_ADMIN_PERM,
17133 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
17135 #endif
17137 .cmd = NL80211_CMD_CONNECT,
17138 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17139 .doit = nl80211_connect,
17140 .flags = GENL_UNS_ADMIN_PERM,
17141 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17142 NL80211_FLAG_CLEAR_SKB),
17145 .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS,
17146 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17147 .doit = nl80211_update_connect_params,
17148 .flags = GENL_ADMIN_PERM,
17149 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17150 NL80211_FLAG_CLEAR_SKB),
17153 .cmd = NL80211_CMD_DISCONNECT,
17154 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17155 .doit = nl80211_disconnect,
17156 .flags = GENL_UNS_ADMIN_PERM,
17157 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17160 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
17161 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17162 .doit = nl80211_wiphy_netns,
17163 .flags = GENL_UNS_ADMIN_PERM,
17164 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY |
17165 NL80211_FLAG_NEED_RTNL |
17166 NL80211_FLAG_NO_WIPHY_MTX),
17169 .cmd = NL80211_CMD_GET_SURVEY,
17170 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17171 .dumpit = nl80211_dump_survey,
17174 .cmd = NL80211_CMD_SET_PMKSA,
17175 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17176 .doit = nl80211_set_pmksa,
17177 .flags = GENL_UNS_ADMIN_PERM,
17178 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17179 NL80211_FLAG_CLEAR_SKB),
17182 .cmd = NL80211_CMD_DEL_PMKSA,
17183 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17184 .doit = nl80211_del_pmksa,
17185 .flags = GENL_UNS_ADMIN_PERM,
17186 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17189 .cmd = NL80211_CMD_FLUSH_PMKSA,
17190 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17191 .doit = nl80211_flush_pmksa,
17192 .flags = GENL_UNS_ADMIN_PERM,
17193 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17196 .cmd = NL80211_CMD_REMAIN_ON_CHANNEL,
17197 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17198 .doit = nl80211_remain_on_channel,
17199 .flags = GENL_UNS_ADMIN_PERM,
17200 /* FIXME: requiring a link ID here is probably not good */
17201 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
17202 NL80211_FLAG_MLO_VALID_LINK_ID),
17205 .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
17206 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17207 .doit = nl80211_cancel_remain_on_channel,
17208 .flags = GENL_UNS_ADMIN_PERM,
17209 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17212 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
17213 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17214 .doit = nl80211_set_tx_bitrate_mask,
17215 .flags = GENL_UNS_ADMIN_PERM,
17216 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
17217 NL80211_FLAG_MLO_VALID_LINK_ID),
17220 .cmd = NL80211_CMD_REGISTER_FRAME,
17221 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17222 .doit = nl80211_register_mgmt,
17223 .flags = GENL_UNS_ADMIN_PERM,
17224 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV),
17227 .cmd = NL80211_CMD_FRAME,
17228 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17229 .doit = nl80211_tx_mgmt,
17230 .flags = GENL_UNS_ADMIN_PERM,
17231 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17234 .cmd = NL80211_CMD_FRAME_WAIT_CANCEL,
17235 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17236 .doit = nl80211_tx_mgmt_cancel_wait,
17237 .flags = GENL_UNS_ADMIN_PERM,
17238 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17241 .cmd = NL80211_CMD_SET_POWER_SAVE,
17242 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17243 .doit = nl80211_set_power_save,
17244 .flags = GENL_UNS_ADMIN_PERM,
17245 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
17248 .cmd = NL80211_CMD_GET_POWER_SAVE,
17249 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17250 .doit = nl80211_get_power_save,
17251 /* can be retrieved by unprivileged users */
17252 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
17255 .cmd = NL80211_CMD_SET_CQM,
17256 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17257 .doit = nl80211_set_cqm,
17258 .flags = GENL_UNS_ADMIN_PERM,
17259 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
17262 .cmd = NL80211_CMD_SET_CHANNEL,
17263 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17264 .doit = nl80211_set_channel,
17265 .flags = GENL_UNS_ADMIN_PERM,
17266 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
17267 NL80211_FLAG_MLO_VALID_LINK_ID),
17270 .cmd = NL80211_CMD_JOIN_MESH,
17271 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17272 .doit = nl80211_join_mesh,
17273 .flags = GENL_UNS_ADMIN_PERM,
17274 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17277 .cmd = NL80211_CMD_LEAVE_MESH,
17278 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17279 .doit = nl80211_leave_mesh,
17280 .flags = GENL_UNS_ADMIN_PERM,
17281 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17284 .cmd = NL80211_CMD_JOIN_OCB,
17285 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17286 .doit = nl80211_join_ocb,
17287 .flags = GENL_UNS_ADMIN_PERM,
17288 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17291 .cmd = NL80211_CMD_LEAVE_OCB,
17292 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17293 .doit = nl80211_leave_ocb,
17294 .flags = GENL_UNS_ADMIN_PERM,
17295 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17297 #ifdef CONFIG_PM
17299 .cmd = NL80211_CMD_GET_WOWLAN,
17300 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17301 .doit = nl80211_get_wowlan,
17302 /* can be retrieved by unprivileged users */
17303 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
17306 .cmd = NL80211_CMD_SET_WOWLAN,
17307 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17308 .doit = nl80211_set_wowlan,
17309 .flags = GENL_UNS_ADMIN_PERM,
17310 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
17312 #endif
17314 .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
17315 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17316 .doit = nl80211_set_rekey_data,
17317 .flags = GENL_UNS_ADMIN_PERM,
17318 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17319 NL80211_FLAG_CLEAR_SKB),
17322 .cmd = NL80211_CMD_TDLS_MGMT,
17323 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17324 .doit = nl80211_tdls_mgmt,
17325 .flags = GENL_UNS_ADMIN_PERM,
17326 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17327 NL80211_FLAG_MLO_VALID_LINK_ID),
17330 .cmd = NL80211_CMD_TDLS_OPER,
17331 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17332 .doit = nl80211_tdls_oper,
17333 .flags = GENL_UNS_ADMIN_PERM,
17334 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17337 .cmd = NL80211_CMD_UNEXPECTED_FRAME,
17338 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17339 .doit = nl80211_register_unexpected_frame,
17340 .flags = GENL_UNS_ADMIN_PERM,
17341 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
17344 .cmd = NL80211_CMD_PROBE_CLIENT,
17345 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17346 .doit = nl80211_probe_client,
17347 .flags = GENL_UNS_ADMIN_PERM,
17348 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17351 .cmd = NL80211_CMD_REGISTER_BEACONS,
17352 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17353 .doit = nl80211_register_beacons,
17354 .flags = GENL_UNS_ADMIN_PERM,
17355 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
17358 .cmd = NL80211_CMD_SET_NOACK_MAP,
17359 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17360 .doit = nl80211_set_noack_map,
17361 .flags = GENL_UNS_ADMIN_PERM,
17362 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
17365 .cmd = NL80211_CMD_START_P2P_DEVICE,
17366 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17367 .doit = nl80211_start_p2p_device,
17368 .flags = GENL_UNS_ADMIN_PERM,
17369 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV |
17370 NL80211_FLAG_NEED_RTNL),
17373 .cmd = NL80211_CMD_STOP_P2P_DEVICE,
17374 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17375 .doit = nl80211_stop_p2p_device,
17376 .flags = GENL_UNS_ADMIN_PERM,
17377 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
17378 NL80211_FLAG_NEED_RTNL),
17381 .cmd = NL80211_CMD_START_NAN,
17382 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17383 .doit = nl80211_start_nan,
17384 .flags = GENL_ADMIN_PERM,
17385 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV |
17386 NL80211_FLAG_NEED_RTNL),
17389 .cmd = NL80211_CMD_STOP_NAN,
17390 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17391 .doit = nl80211_stop_nan,
17392 .flags = GENL_ADMIN_PERM,
17393 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP |
17394 NL80211_FLAG_NEED_RTNL),
17397 .cmd = NL80211_CMD_ADD_NAN_FUNCTION,
17398 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17399 .doit = nl80211_nan_add_func,
17400 .flags = GENL_ADMIN_PERM,
17401 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17404 .cmd = NL80211_CMD_DEL_NAN_FUNCTION,
17405 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17406 .doit = nl80211_nan_del_func,
17407 .flags = GENL_ADMIN_PERM,
17408 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17411 .cmd = NL80211_CMD_CHANGE_NAN_CONFIG,
17412 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17413 .doit = nl80211_nan_change_config,
17414 .flags = GENL_ADMIN_PERM,
17415 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17418 .cmd = NL80211_CMD_SET_MCAST_RATE,
17419 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17420 .doit = nl80211_set_mcast_rate,
17421 .flags = GENL_UNS_ADMIN_PERM,
17422 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
17425 .cmd = NL80211_CMD_SET_MAC_ACL,
17426 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17427 .doit = nl80211_set_mac_acl,
17428 .flags = GENL_UNS_ADMIN_PERM,
17429 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
17430 NL80211_FLAG_MLO_UNSUPPORTED),
17433 .cmd = NL80211_CMD_RADAR_DETECT,
17434 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17435 .doit = nl80211_start_radar_detection,
17436 .flags = GENL_UNS_ADMIN_PERM,
17437 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17438 NL80211_FLAG_NO_WIPHY_MTX |
17439 NL80211_FLAG_MLO_VALID_LINK_ID),
17442 .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES,
17443 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17444 .doit = nl80211_get_protocol_features,
17447 .cmd = NL80211_CMD_UPDATE_FT_IES,
17448 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17449 .doit = nl80211_update_ft_ies,
17450 .flags = GENL_UNS_ADMIN_PERM,
17451 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17454 .cmd = NL80211_CMD_CRIT_PROTOCOL_START,
17455 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17456 .doit = nl80211_crit_protocol_start,
17457 .flags = GENL_UNS_ADMIN_PERM,
17458 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17461 .cmd = NL80211_CMD_CRIT_PROTOCOL_STOP,
17462 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17463 .doit = nl80211_crit_protocol_stop,
17464 .flags = GENL_UNS_ADMIN_PERM,
17465 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17468 .cmd = NL80211_CMD_GET_COALESCE,
17469 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17470 .doit = nl80211_get_coalesce,
17471 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
17474 .cmd = NL80211_CMD_SET_COALESCE,
17475 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17476 .doit = nl80211_set_coalesce,
17477 .flags = GENL_UNS_ADMIN_PERM,
17478 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY),
17481 .cmd = NL80211_CMD_CHANNEL_SWITCH,
17482 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17483 .doit = nl80211_channel_switch,
17484 .flags = GENL_UNS_ADMIN_PERM,
17485 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17486 NL80211_FLAG_MLO_VALID_LINK_ID),
17489 .cmd = NL80211_CMD_VENDOR,
17490 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17491 .doit = nl80211_vendor_cmd,
17492 .dumpit = nl80211_vendor_cmd_dump,
17493 .flags = GENL_UNS_ADMIN_PERM,
17494 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY |
17495 NL80211_FLAG_CLEAR_SKB),
17498 .cmd = NL80211_CMD_SET_QOS_MAP,
17499 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17500 .doit = nl80211_set_qos_map,
17501 .flags = GENL_UNS_ADMIN_PERM,
17502 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17505 .cmd = NL80211_CMD_ADD_TX_TS,
17506 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17507 .doit = nl80211_add_tx_ts,
17508 .flags = GENL_UNS_ADMIN_PERM,
17509 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17510 NL80211_FLAG_MLO_UNSUPPORTED),
17513 .cmd = NL80211_CMD_DEL_TX_TS,
17514 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17515 .doit = nl80211_del_tx_ts,
17516 .flags = GENL_UNS_ADMIN_PERM,
17517 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17520 .cmd = NL80211_CMD_TDLS_CHANNEL_SWITCH,
17521 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17522 .doit = nl80211_tdls_channel_switch,
17523 .flags = GENL_UNS_ADMIN_PERM,
17524 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17527 .cmd = NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH,
17528 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17529 .doit = nl80211_tdls_cancel_channel_switch,
17530 .flags = GENL_UNS_ADMIN_PERM,
17531 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17534 .cmd = NL80211_CMD_SET_MULTICAST_TO_UNICAST,
17535 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17536 .doit = nl80211_set_multicast_to_unicast,
17537 .flags = GENL_UNS_ADMIN_PERM,
17538 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV),
17541 .cmd = NL80211_CMD_SET_PMK,
17542 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17543 .doit = nl80211_set_pmk,
17544 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17545 NL80211_FLAG_CLEAR_SKB),
17548 .cmd = NL80211_CMD_DEL_PMK,
17549 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17550 .doit = nl80211_del_pmk,
17551 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17554 .cmd = NL80211_CMD_EXTERNAL_AUTH,
17555 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17556 .doit = nl80211_external_auth,
17557 .flags = GENL_ADMIN_PERM,
17558 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17561 .cmd = NL80211_CMD_CONTROL_PORT_FRAME,
17562 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17563 .doit = nl80211_tx_control_port,
17564 .flags = GENL_UNS_ADMIN_PERM,
17565 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17568 .cmd = NL80211_CMD_GET_FTM_RESPONDER_STATS,
17569 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17570 .doit = nl80211_get_ftm_responder_stats,
17571 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
17572 NL80211_FLAG_MLO_VALID_LINK_ID),
17575 .cmd = NL80211_CMD_PEER_MEASUREMENT_START,
17576 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17577 .doit = nl80211_pmsr_start,
17578 .flags = GENL_UNS_ADMIN_PERM,
17579 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP),
17582 .cmd = NL80211_CMD_NOTIFY_RADAR,
17583 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17584 .doit = nl80211_notify_radar_detection,
17585 .flags = GENL_UNS_ADMIN_PERM,
17586 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17589 .cmd = NL80211_CMD_UPDATE_OWE_INFO,
17590 .doit = nl80211_update_owe_info,
17591 .flags = GENL_ADMIN_PERM,
17592 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17595 .cmd = NL80211_CMD_PROBE_MESH_LINK,
17596 .doit = nl80211_probe_mesh_link,
17597 .flags = GENL_UNS_ADMIN_PERM,
17598 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17601 .cmd = NL80211_CMD_SET_TID_CONFIG,
17602 .doit = nl80211_set_tid_config,
17603 .flags = GENL_UNS_ADMIN_PERM,
17604 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV |
17605 NL80211_FLAG_MLO_VALID_LINK_ID),
17608 .cmd = NL80211_CMD_SET_SAR_SPECS,
17609 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17610 .doit = nl80211_set_sar_specs,
17611 .flags = GENL_UNS_ADMIN_PERM,
17612 .internal_flags = IFLAGS(NL80211_FLAG_NEED_WIPHY |
17613 NL80211_FLAG_NEED_RTNL),
17616 .cmd = NL80211_CMD_COLOR_CHANGE_REQUEST,
17617 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17618 .doit = nl80211_color_change,
17619 .flags = GENL_UNS_ADMIN_PERM,
17620 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17621 NL80211_FLAG_MLO_VALID_LINK_ID),
17624 .cmd = NL80211_CMD_SET_FILS_AAD,
17625 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
17626 .doit = nl80211_set_fils_aad,
17627 .flags = GENL_UNS_ADMIN_PERM,
17628 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17631 .cmd = NL80211_CMD_ADD_LINK,
17632 .doit = nl80211_add_link,
17633 .flags = GENL_UNS_ADMIN_PERM,
17634 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17637 .cmd = NL80211_CMD_REMOVE_LINK,
17638 .doit = nl80211_remove_link,
17639 .flags = GENL_UNS_ADMIN_PERM,
17640 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17641 NL80211_FLAG_MLO_VALID_LINK_ID),
17644 .cmd = NL80211_CMD_ADD_LINK_STA,
17645 .doit = nl80211_add_link_station,
17646 .flags = GENL_UNS_ADMIN_PERM,
17647 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17648 NL80211_FLAG_MLO_VALID_LINK_ID),
17651 .cmd = NL80211_CMD_MODIFY_LINK_STA,
17652 .doit = nl80211_modify_link_station,
17653 .flags = GENL_UNS_ADMIN_PERM,
17654 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17655 NL80211_FLAG_MLO_VALID_LINK_ID),
17658 .cmd = NL80211_CMD_REMOVE_LINK_STA,
17659 .doit = nl80211_remove_link_station,
17660 .flags = GENL_UNS_ADMIN_PERM,
17661 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP |
17662 NL80211_FLAG_MLO_VALID_LINK_ID),
17665 .cmd = NL80211_CMD_SET_HW_TIMESTAMP,
17666 .doit = nl80211_set_hw_timestamp,
17667 .flags = GENL_UNS_ADMIN_PERM,
17668 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17671 .cmd = NL80211_CMD_SET_TID_TO_LINK_MAPPING,
17672 .doit = nl80211_set_ttlm,
17673 .flags = GENL_UNS_ADMIN_PERM,
17674 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP),
17678 static struct genl_family nl80211_fam __ro_after_init = {
17679 .name = NL80211_GENL_NAME, /* have users key off the name instead */
17680 .hdrsize = 0, /* no private header */
17681 .version = 1, /* no particular meaning now */
17682 .maxattr = NL80211_ATTR_MAX,
17683 .policy = nl80211_policy,
17684 .netnsok = true,
17685 .pre_doit = nl80211_pre_doit,
17686 .post_doit = nl80211_post_doit,
17687 .module = THIS_MODULE,
17688 .ops = nl80211_ops,
17689 .n_ops = ARRAY_SIZE(nl80211_ops),
17690 .small_ops = nl80211_small_ops,
17691 .n_small_ops = ARRAY_SIZE(nl80211_small_ops),
17692 .resv_start_op = NL80211_CMD_REMOVE_LINK_STA + 1,
17693 .mcgrps = nl80211_mcgrps,
17694 .n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
17695 .parallel_ops = true,
17698 /* notification functions */
17700 void nl80211_notify_wiphy(struct cfg80211_registered_device *rdev,
17701 enum nl80211_commands cmd)
17703 struct sk_buff *msg;
17704 struct nl80211_dump_wiphy_state state = {};
17706 WARN_ON(cmd != NL80211_CMD_NEW_WIPHY &&
17707 cmd != NL80211_CMD_DEL_WIPHY);
17709 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17710 if (!msg)
17711 return;
17713 if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
17714 nlmsg_free(msg);
17715 return;
17718 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17719 NL80211_MCGRP_CONFIG, GFP_KERNEL);
17722 void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
17723 struct wireless_dev *wdev,
17724 enum nl80211_commands cmd)
17726 struct sk_buff *msg;
17728 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17729 if (!msg)
17730 return;
17732 if (nl80211_send_iface(msg, 0, 0, 0, rdev, wdev, cmd) < 0) {
17733 nlmsg_free(msg);
17734 return;
17737 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17738 NL80211_MCGRP_CONFIG, GFP_KERNEL);
17741 static int nl80211_add_scan_req(struct sk_buff *msg,
17742 struct cfg80211_registered_device *rdev)
17744 struct cfg80211_scan_request *req = rdev->scan_req;
17745 struct nlattr *nest;
17746 int i;
17747 struct cfg80211_scan_info *info;
17749 if (WARN_ON(!req))
17750 return 0;
17752 nest = nla_nest_start_noflag(msg, NL80211_ATTR_SCAN_SSIDS);
17753 if (!nest)
17754 goto nla_put_failure;
17755 for (i = 0; i < req->n_ssids; i++) {
17756 if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid))
17757 goto nla_put_failure;
17759 nla_nest_end(msg, nest);
17761 if (req->flags & NL80211_SCAN_FLAG_FREQ_KHZ) {
17762 nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQ_KHZ);
17763 if (!nest)
17764 goto nla_put_failure;
17765 for (i = 0; i < req->n_channels; i++) {
17766 if (nla_put_u32(msg, i,
17767 ieee80211_channel_to_khz(req->channels[i])))
17768 goto nla_put_failure;
17770 nla_nest_end(msg, nest);
17771 } else {
17772 nest = nla_nest_start_noflag(msg,
17773 NL80211_ATTR_SCAN_FREQUENCIES);
17774 if (!nest)
17775 goto nla_put_failure;
17776 for (i = 0; i < req->n_channels; i++) {
17777 if (nla_put_u32(msg, i, req->channels[i]->center_freq))
17778 goto nla_put_failure;
17780 nla_nest_end(msg, nest);
17783 if (req->ie &&
17784 nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie))
17785 goto nla_put_failure;
17787 if (req->flags &&
17788 nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags))
17789 goto nla_put_failure;
17791 info = rdev->int_scan_req ? &rdev->int_scan_req->info :
17792 &rdev->scan_req->info;
17793 if (info->scan_start_tsf &&
17794 (nla_put_u64_64bit(msg, NL80211_ATTR_SCAN_START_TIME_TSF,
17795 info->scan_start_tsf, NL80211_BSS_PAD) ||
17796 nla_put(msg, NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, ETH_ALEN,
17797 info->tsf_bssid)))
17798 goto nla_put_failure;
17800 return 0;
17801 nla_put_failure:
17802 return -ENOBUFS;
17805 static int nl80211_prep_scan_msg(struct sk_buff *msg,
17806 struct cfg80211_registered_device *rdev,
17807 struct wireless_dev *wdev,
17808 u32 portid, u32 seq, int flags,
17809 u32 cmd)
17811 void *hdr;
17813 hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
17814 if (!hdr)
17815 return -1;
17817 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
17818 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
17819 wdev->netdev->ifindex)) ||
17820 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
17821 NL80211_ATTR_PAD))
17822 goto nla_put_failure;
17824 /* ignore errors and send incomplete event anyway */
17825 nl80211_add_scan_req(msg, rdev);
17827 genlmsg_end(msg, hdr);
17828 return 0;
17830 nla_put_failure:
17831 genlmsg_cancel(msg, hdr);
17832 return -EMSGSIZE;
17835 static int
17836 nl80211_prep_sched_scan_msg(struct sk_buff *msg,
17837 struct cfg80211_sched_scan_request *req, u32 cmd)
17839 void *hdr;
17841 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
17842 if (!hdr)
17843 return -1;
17845 if (nla_put_u32(msg, NL80211_ATTR_WIPHY,
17846 wiphy_to_rdev(req->wiphy)->wiphy_idx) ||
17847 nla_put_u32(msg, NL80211_ATTR_IFINDEX, req->dev->ifindex) ||
17848 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->reqid,
17849 NL80211_ATTR_PAD))
17850 goto nla_put_failure;
17852 genlmsg_end(msg, hdr);
17853 return 0;
17855 nla_put_failure:
17856 genlmsg_cancel(msg, hdr);
17857 return -EMSGSIZE;
17860 void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
17861 struct wireless_dev *wdev)
17863 struct sk_buff *msg;
17865 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17866 if (!msg)
17867 return;
17869 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
17870 NL80211_CMD_TRIGGER_SCAN) < 0) {
17871 nlmsg_free(msg);
17872 return;
17875 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17876 NL80211_MCGRP_SCAN, GFP_KERNEL);
17879 struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
17880 struct wireless_dev *wdev, bool aborted)
17882 struct sk_buff *msg;
17884 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17885 if (!msg)
17886 return NULL;
17888 if (nl80211_prep_scan_msg(msg, rdev, wdev, 0, 0, 0,
17889 aborted ? NL80211_CMD_SCAN_ABORTED :
17890 NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
17891 nlmsg_free(msg);
17892 return NULL;
17895 return msg;
17898 /* send message created by nl80211_build_scan_msg() */
17899 void nl80211_send_scan_msg(struct cfg80211_registered_device *rdev,
17900 struct sk_buff *msg)
17902 if (!msg)
17903 return;
17905 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
17906 NL80211_MCGRP_SCAN, GFP_KERNEL);
17909 void nl80211_send_sched_scan(struct cfg80211_sched_scan_request *req, u32 cmd)
17911 struct sk_buff *msg;
17913 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17914 if (!msg)
17915 return;
17917 if (nl80211_prep_sched_scan_msg(msg, req, cmd) < 0) {
17918 nlmsg_free(msg);
17919 return;
17922 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(req->wiphy), msg, 0,
17923 NL80211_MCGRP_SCAN, GFP_KERNEL);
17926 static bool nl80211_reg_change_event_fill(struct sk_buff *msg,
17927 struct regulatory_request *request)
17929 /* Userspace can always count this one always being set */
17930 if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator))
17931 goto nla_put_failure;
17933 if (request->alpha2[0] == '0' && request->alpha2[1] == '0') {
17934 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
17935 NL80211_REGDOM_TYPE_WORLD))
17936 goto nla_put_failure;
17937 } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') {
17938 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
17939 NL80211_REGDOM_TYPE_CUSTOM_WORLD))
17940 goto nla_put_failure;
17941 } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') ||
17942 request->intersect) {
17943 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
17944 NL80211_REGDOM_TYPE_INTERSECTION))
17945 goto nla_put_failure;
17946 } else {
17947 if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE,
17948 NL80211_REGDOM_TYPE_COUNTRY) ||
17949 nla_put_string(msg, NL80211_ATTR_REG_ALPHA2,
17950 request->alpha2))
17951 goto nla_put_failure;
17954 if (request->wiphy_idx != WIPHY_IDX_INVALID) {
17955 struct wiphy *wiphy = wiphy_idx_to_wiphy(request->wiphy_idx);
17957 if (wiphy &&
17958 nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx))
17959 goto nla_put_failure;
17961 if (wiphy &&
17962 wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED &&
17963 nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
17964 goto nla_put_failure;
17967 return true;
17969 nla_put_failure:
17970 return false;
17974 * This can happen on global regulatory changes or device specific settings
17975 * based on custom regulatory domains.
17977 void nl80211_common_reg_change_event(enum nl80211_commands cmd_id,
17978 struct regulatory_request *request)
17980 struct sk_buff *msg;
17981 void *hdr;
17983 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
17984 if (!msg)
17985 return;
17987 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd_id);
17988 if (!hdr)
17989 goto nla_put_failure;
17991 if (!nl80211_reg_change_event_fill(msg, request))
17992 goto nla_put_failure;
17994 genlmsg_end(msg, hdr);
17996 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
17997 NL80211_MCGRP_REGULATORY);
17999 return;
18001 nla_put_failure:
18002 nlmsg_free(msg);
18005 struct nl80211_mlme_event {
18006 enum nl80211_commands cmd;
18007 const u8 *buf;
18008 size_t buf_len;
18009 int uapsd_queues;
18010 const u8 *req_ies;
18011 size_t req_ies_len;
18012 bool reconnect;
18015 static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
18016 struct net_device *netdev,
18017 const struct nl80211_mlme_event *event,
18018 gfp_t gfp)
18020 struct sk_buff *msg;
18021 void *hdr;
18023 msg = nlmsg_new(100 + event->buf_len + event->req_ies_len, gfp);
18024 if (!msg)
18025 return;
18027 hdr = nl80211hdr_put(msg, 0, 0, 0, event->cmd);
18028 if (!hdr) {
18029 nlmsg_free(msg);
18030 return;
18033 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18034 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18035 nla_put(msg, NL80211_ATTR_FRAME, event->buf_len, event->buf) ||
18036 (event->req_ies &&
18037 nla_put(msg, NL80211_ATTR_REQ_IE, event->req_ies_len,
18038 event->req_ies)))
18039 goto nla_put_failure;
18041 if (event->reconnect &&
18042 nla_put_flag(msg, NL80211_ATTR_RECONNECT_REQUESTED))
18043 goto nla_put_failure;
18045 if (event->uapsd_queues >= 0) {
18046 struct nlattr *nla_wmm =
18047 nla_nest_start_noflag(msg, NL80211_ATTR_STA_WME);
18048 if (!nla_wmm)
18049 goto nla_put_failure;
18051 if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES,
18052 event->uapsd_queues))
18053 goto nla_put_failure;
18055 nla_nest_end(msg, nla_wmm);
18058 genlmsg_end(msg, hdr);
18060 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18061 NL80211_MCGRP_MLME, gfp);
18062 return;
18064 nla_put_failure:
18065 nlmsg_free(msg);
18068 void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
18069 struct net_device *netdev, const u8 *buf,
18070 size_t len, gfp_t gfp)
18072 struct nl80211_mlme_event event = {
18073 .cmd = NL80211_CMD_AUTHENTICATE,
18074 .buf = buf,
18075 .buf_len = len,
18076 .uapsd_queues = -1,
18079 nl80211_send_mlme_event(rdev, netdev, &event, gfp);
18082 void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
18083 struct net_device *netdev,
18084 const struct cfg80211_rx_assoc_resp_data *data)
18086 struct nl80211_mlme_event event = {
18087 .cmd = NL80211_CMD_ASSOCIATE,
18088 .buf = data->buf,
18089 .buf_len = data->len,
18090 .uapsd_queues = data->uapsd_queues,
18091 .req_ies = data->req_ies,
18092 .req_ies_len = data->req_ies_len,
18095 nl80211_send_mlme_event(rdev, netdev, &event, GFP_KERNEL);
18098 void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
18099 struct net_device *netdev, const u8 *buf,
18100 size_t len, bool reconnect, gfp_t gfp)
18102 struct nl80211_mlme_event event = {
18103 .cmd = NL80211_CMD_DEAUTHENTICATE,
18104 .buf = buf,
18105 .buf_len = len,
18106 .reconnect = reconnect,
18107 .uapsd_queues = -1,
18110 nl80211_send_mlme_event(rdev, netdev, &event, gfp);
18113 void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
18114 struct net_device *netdev, const u8 *buf,
18115 size_t len, bool reconnect, gfp_t gfp)
18117 struct nl80211_mlme_event event = {
18118 .cmd = NL80211_CMD_DISASSOCIATE,
18119 .buf = buf,
18120 .buf_len = len,
18121 .reconnect = reconnect,
18122 .uapsd_queues = -1,
18125 nl80211_send_mlme_event(rdev, netdev, &event, gfp);
18128 void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
18129 size_t len)
18131 struct wireless_dev *wdev = dev->ieee80211_ptr;
18132 struct wiphy *wiphy = wdev->wiphy;
18133 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18134 const struct ieee80211_mgmt *mgmt = (void *)buf;
18135 struct nl80211_mlme_event event = {
18136 .buf = buf,
18137 .buf_len = len,
18138 .uapsd_queues = -1,
18141 if (WARN_ON(len < 2))
18142 return;
18144 if (ieee80211_is_deauth(mgmt->frame_control)) {
18145 event.cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
18146 } else if (ieee80211_is_disassoc(mgmt->frame_control)) {
18147 event.cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
18148 } else if (ieee80211_is_beacon(mgmt->frame_control)) {
18149 if (wdev->unprot_beacon_reported &&
18150 elapsed_jiffies_msecs(wdev->unprot_beacon_reported) < 10000)
18151 return;
18152 event.cmd = NL80211_CMD_UNPROT_BEACON;
18153 wdev->unprot_beacon_reported = jiffies;
18154 } else {
18155 return;
18158 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
18159 nl80211_send_mlme_event(rdev, dev, &event, GFP_ATOMIC);
18161 EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
18163 static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
18164 struct net_device *netdev, int cmd,
18165 const u8 *addr, gfp_t gfp)
18167 struct sk_buff *msg;
18168 void *hdr;
18170 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18171 if (!msg)
18172 return;
18174 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
18175 if (!hdr) {
18176 nlmsg_free(msg);
18177 return;
18180 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18181 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18182 nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
18183 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
18184 goto nla_put_failure;
18186 genlmsg_end(msg, hdr);
18188 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18189 NL80211_MCGRP_MLME, gfp);
18190 return;
18192 nla_put_failure:
18193 nlmsg_free(msg);
18196 void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
18197 struct net_device *netdev, const u8 *addr,
18198 gfp_t gfp)
18200 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
18201 addr, gfp);
18204 void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
18205 struct net_device *netdev, const u8 *addr,
18206 gfp_t gfp)
18208 nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE,
18209 addr, gfp);
18212 void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
18213 struct net_device *netdev,
18214 struct cfg80211_connect_resp_params *cr,
18215 gfp_t gfp)
18217 struct sk_buff *msg;
18218 void *hdr;
18219 unsigned int link;
18220 size_t link_info_size = 0;
18221 const u8 *connected_addr = cr->valid_links ?
18222 cr->ap_mld_addr : cr->links[0].bssid;
18224 if (cr->valid_links) {
18225 for_each_valid_link(cr, link) {
18226 /* Nested attribute header */
18227 link_info_size += NLA_HDRLEN;
18228 /* Link ID */
18229 link_info_size += nla_total_size(sizeof(u8));
18230 link_info_size += cr->links[link].addr ?
18231 nla_total_size(ETH_ALEN) : 0;
18232 link_info_size += (cr->links[link].bssid ||
18233 cr->links[link].bss) ?
18234 nla_total_size(ETH_ALEN) : 0;
18235 link_info_size += nla_total_size(sizeof(u16));
18239 msg = nlmsg_new(100 + cr->req_ie_len + cr->resp_ie_len +
18240 cr->fils.kek_len + cr->fils.pmk_len +
18241 (cr->fils.pmkid ? WLAN_PMKID_LEN : 0) + link_info_size,
18242 gfp);
18243 if (!msg)
18244 return;
18246 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT);
18247 if (!hdr) {
18248 nlmsg_free(msg);
18249 return;
18252 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18253 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18254 (connected_addr &&
18255 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, connected_addr)) ||
18256 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
18257 cr->status < 0 ? WLAN_STATUS_UNSPECIFIED_FAILURE :
18258 cr->status) ||
18259 (cr->status < 0 &&
18260 (nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) ||
18261 nla_put_u32(msg, NL80211_ATTR_TIMEOUT_REASON,
18262 cr->timeout_reason))) ||
18263 (cr->req_ie &&
18264 nla_put(msg, NL80211_ATTR_REQ_IE, cr->req_ie_len, cr->req_ie)) ||
18265 (cr->resp_ie &&
18266 nla_put(msg, NL80211_ATTR_RESP_IE, cr->resp_ie_len,
18267 cr->resp_ie)) ||
18268 (cr->fils.update_erp_next_seq_num &&
18269 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
18270 cr->fils.erp_next_seq_num)) ||
18271 (cr->status == WLAN_STATUS_SUCCESS &&
18272 ((cr->fils.kek &&
18273 nla_put(msg, NL80211_ATTR_FILS_KEK, cr->fils.kek_len,
18274 cr->fils.kek)) ||
18275 (cr->fils.pmk &&
18276 nla_put(msg, NL80211_ATTR_PMK, cr->fils.pmk_len, cr->fils.pmk)) ||
18277 (cr->fils.pmkid &&
18278 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, cr->fils.pmkid)))))
18279 goto nla_put_failure;
18281 if (cr->valid_links) {
18282 int i = 1;
18283 struct nlattr *nested;
18285 nested = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS);
18286 if (!nested)
18287 goto nla_put_failure;
18289 for_each_valid_link(cr, link) {
18290 struct nlattr *nested_mlo_links;
18291 const u8 *bssid = cr->links[link].bss ?
18292 cr->links[link].bss->bssid :
18293 cr->links[link].bssid;
18295 nested_mlo_links = nla_nest_start(msg, i);
18296 if (!nested_mlo_links)
18297 goto nla_put_failure;
18299 if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link) ||
18300 (bssid &&
18301 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, bssid)) ||
18302 (cr->links[link].addr &&
18303 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
18304 cr->links[link].addr)) ||
18305 nla_put_u16(msg, NL80211_ATTR_STATUS_CODE,
18306 cr->links[link].status))
18307 goto nla_put_failure;
18309 nla_nest_end(msg, nested_mlo_links);
18310 i++;
18312 nla_nest_end(msg, nested);
18315 genlmsg_end(msg, hdr);
18317 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18318 NL80211_MCGRP_MLME, gfp);
18319 return;
18321 nla_put_failure:
18322 nlmsg_free(msg);
18325 void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
18326 struct net_device *netdev,
18327 struct cfg80211_roam_info *info, gfp_t gfp)
18329 struct sk_buff *msg;
18330 void *hdr;
18331 size_t link_info_size = 0;
18332 unsigned int link;
18333 const u8 *connected_addr = info->ap_mld_addr ?
18334 info->ap_mld_addr :
18335 (info->links[0].bss ?
18336 info->links[0].bss->bssid :
18337 info->links[0].bssid);
18339 if (info->valid_links) {
18340 for_each_valid_link(info, link) {
18341 /* Nested attribute header */
18342 link_info_size += NLA_HDRLEN;
18343 /* Link ID */
18344 link_info_size += nla_total_size(sizeof(u8));
18345 link_info_size += info->links[link].addr ?
18346 nla_total_size(ETH_ALEN) : 0;
18347 link_info_size += (info->links[link].bssid ||
18348 info->links[link].bss) ?
18349 nla_total_size(ETH_ALEN) : 0;
18353 msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len +
18354 info->fils.kek_len + info->fils.pmk_len +
18355 (info->fils.pmkid ? WLAN_PMKID_LEN : 0) +
18356 link_info_size, gfp);
18357 if (!msg)
18358 return;
18360 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM);
18361 if (!hdr) {
18362 nlmsg_free(msg);
18363 return;
18366 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18367 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18368 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, connected_addr) ||
18369 (info->req_ie &&
18370 nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
18371 info->req_ie)) ||
18372 (info->resp_ie &&
18373 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
18374 info->resp_ie)) ||
18375 (info->fils.update_erp_next_seq_num &&
18376 nla_put_u16(msg, NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM,
18377 info->fils.erp_next_seq_num)) ||
18378 (info->fils.kek &&
18379 nla_put(msg, NL80211_ATTR_FILS_KEK, info->fils.kek_len,
18380 info->fils.kek)) ||
18381 (info->fils.pmk &&
18382 nla_put(msg, NL80211_ATTR_PMK, info->fils.pmk_len, info->fils.pmk)) ||
18383 (info->fils.pmkid &&
18384 nla_put(msg, NL80211_ATTR_PMKID, WLAN_PMKID_LEN, info->fils.pmkid)))
18385 goto nla_put_failure;
18387 if (info->valid_links) {
18388 int i = 1;
18389 struct nlattr *nested;
18391 nested = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS);
18392 if (!nested)
18393 goto nla_put_failure;
18395 for_each_valid_link(info, link) {
18396 struct nlattr *nested_mlo_links;
18397 const u8 *bssid = info->links[link].bss ?
18398 info->links[link].bss->bssid :
18399 info->links[link].bssid;
18401 nested_mlo_links = nla_nest_start(msg, i);
18402 if (!nested_mlo_links)
18403 goto nla_put_failure;
18405 if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link) ||
18406 (bssid &&
18407 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, bssid)) ||
18408 (info->links[link].addr &&
18409 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN,
18410 info->links[link].addr)))
18411 goto nla_put_failure;
18413 nla_nest_end(msg, nested_mlo_links);
18414 i++;
18416 nla_nest_end(msg, nested);
18419 genlmsg_end(msg, hdr);
18421 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18422 NL80211_MCGRP_MLME, gfp);
18423 return;
18425 nla_put_failure:
18426 nlmsg_free(msg);
18429 void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
18430 struct net_device *netdev, const u8 *peer_addr,
18431 const u8 *td_bitmap, u8 td_bitmap_len)
18433 struct sk_buff *msg;
18434 void *hdr;
18436 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
18437 if (!msg)
18438 return;
18440 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
18441 if (!hdr) {
18442 nlmsg_free(msg);
18443 return;
18446 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18447 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18448 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer_addr))
18449 goto nla_put_failure;
18451 if ((td_bitmap_len > 0) && td_bitmap)
18452 if (nla_put(msg, NL80211_ATTR_TD_BITMAP,
18453 td_bitmap_len, td_bitmap))
18454 goto nla_put_failure;
18456 genlmsg_end(msg, hdr);
18458 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18459 NL80211_MCGRP_MLME, GFP_KERNEL);
18460 return;
18462 nla_put_failure:
18463 nlmsg_free(msg);
18466 void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
18467 struct net_device *netdev, u16 reason,
18468 const u8 *ie, size_t ie_len, bool from_ap)
18470 struct sk_buff *msg;
18471 void *hdr;
18473 msg = nlmsg_new(100 + ie_len, GFP_KERNEL);
18474 if (!msg)
18475 return;
18477 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT);
18478 if (!hdr) {
18479 nlmsg_free(msg);
18480 return;
18483 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18484 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18485 (reason &&
18486 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) ||
18487 (from_ap &&
18488 nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) ||
18489 (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie)))
18490 goto nla_put_failure;
18492 genlmsg_end(msg, hdr);
18494 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18495 NL80211_MCGRP_MLME, GFP_KERNEL);
18496 return;
18498 nla_put_failure:
18499 nlmsg_free(msg);
18502 void cfg80211_links_removed(struct net_device *dev, u16 link_mask)
18504 struct wireless_dev *wdev = dev->ieee80211_ptr;
18505 struct wiphy *wiphy = wdev->wiphy;
18506 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18507 struct sk_buff *msg;
18508 struct nlattr *links;
18509 void *hdr;
18511 lockdep_assert_wiphy(wdev->wiphy);
18512 trace_cfg80211_links_removed(dev, link_mask);
18514 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION &&
18515 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
18516 return;
18518 if (WARN_ON(!wdev->valid_links || !link_mask ||
18519 (wdev->valid_links & link_mask) != link_mask ||
18520 wdev->valid_links == link_mask))
18521 return;
18523 cfg80211_wdev_release_link_bsses(wdev, link_mask);
18524 wdev->valid_links &= ~link_mask;
18526 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
18527 if (!msg)
18528 return;
18530 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_LINKS_REMOVED);
18531 if (!hdr) {
18532 nlmsg_free(msg);
18533 return;
18536 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18537 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
18538 goto nla_put_failure;
18540 links = nla_nest_start(msg, NL80211_ATTR_MLO_LINKS);
18541 if (!links)
18542 goto nla_put_failure;
18544 while (link_mask) {
18545 struct nlattr *link;
18546 int link_id = __ffs(link_mask);
18548 link = nla_nest_start(msg, link_id + 1);
18549 if (!link)
18550 goto nla_put_failure;
18552 if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
18553 goto nla_put_failure;
18555 nla_nest_end(msg, link);
18556 link_mask &= ~(1 << link_id);
18559 nla_nest_end(msg, links);
18561 genlmsg_end(msg, hdr);
18563 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18564 NL80211_MCGRP_MLME, GFP_KERNEL);
18565 return;
18567 nla_put_failure:
18568 nlmsg_free(msg);
18570 EXPORT_SYMBOL(cfg80211_links_removed);
18572 void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
18573 struct net_device *netdev, const u8 *bssid,
18574 gfp_t gfp)
18576 struct sk_buff *msg;
18577 void *hdr;
18579 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18580 if (!msg)
18581 return;
18583 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
18584 if (!hdr) {
18585 nlmsg_free(msg);
18586 return;
18589 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18590 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18591 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
18592 goto nla_put_failure;
18594 genlmsg_end(msg, hdr);
18596 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18597 NL80211_MCGRP_MLME, gfp);
18598 return;
18600 nla_put_failure:
18601 nlmsg_free(msg);
18604 void cfg80211_notify_new_peer_candidate(struct net_device *dev, const u8 *addr,
18605 const u8 *ie, u8 ie_len,
18606 int sig_dbm, gfp_t gfp)
18608 struct wireless_dev *wdev = dev->ieee80211_ptr;
18609 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
18610 struct sk_buff *msg;
18611 void *hdr;
18613 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT))
18614 return;
18616 trace_cfg80211_notify_new_peer_candidate(dev, addr);
18618 msg = nlmsg_new(100 + ie_len, gfp);
18619 if (!msg)
18620 return;
18622 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE);
18623 if (!hdr) {
18624 nlmsg_free(msg);
18625 return;
18628 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18629 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18630 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
18631 (ie_len && ie &&
18632 nla_put(msg, NL80211_ATTR_IE, ie_len, ie)) ||
18633 (sig_dbm &&
18634 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)))
18635 goto nla_put_failure;
18637 genlmsg_end(msg, hdr);
18639 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18640 NL80211_MCGRP_MLME, gfp);
18641 return;
18643 nla_put_failure:
18644 nlmsg_free(msg);
18646 EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate);
18648 void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
18649 struct net_device *netdev, const u8 *addr,
18650 enum nl80211_key_type key_type, int key_id,
18651 const u8 *tsc, gfp_t gfp)
18653 struct sk_buff *msg;
18654 void *hdr;
18656 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18657 if (!msg)
18658 return;
18660 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
18661 if (!hdr) {
18662 nlmsg_free(msg);
18663 return;
18666 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18667 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18668 (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) ||
18669 nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) ||
18670 (key_id != -1 &&
18671 nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) ||
18672 (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc)))
18673 goto nla_put_failure;
18675 genlmsg_end(msg, hdr);
18677 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18678 NL80211_MCGRP_MLME, gfp);
18679 return;
18681 nla_put_failure:
18682 nlmsg_free(msg);
18685 void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
18686 struct ieee80211_channel *channel_before,
18687 struct ieee80211_channel *channel_after)
18689 struct sk_buff *msg;
18690 void *hdr;
18691 struct nlattr *nl_freq;
18693 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
18694 if (!msg)
18695 return;
18697 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
18698 if (!hdr) {
18699 nlmsg_free(msg);
18700 return;
18704 * Since we are applying the beacon hint to a wiphy we know its
18705 * wiphy_idx is valid
18707 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy)))
18708 goto nla_put_failure;
18710 /* Before */
18711 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_BEFORE);
18712 if (!nl_freq)
18713 goto nla_put_failure;
18715 if (nl80211_msg_put_channel(msg, wiphy, channel_before, false))
18716 goto nla_put_failure;
18717 nla_nest_end(msg, nl_freq);
18719 /* After */
18720 nl_freq = nla_nest_start_noflag(msg, NL80211_ATTR_FREQ_AFTER);
18721 if (!nl_freq)
18722 goto nla_put_failure;
18724 if (nl80211_msg_put_channel(msg, wiphy, channel_after, false))
18725 goto nla_put_failure;
18726 nla_nest_end(msg, nl_freq);
18728 genlmsg_end(msg, hdr);
18730 genlmsg_multicast_allns(&nl80211_fam, msg, 0,
18731 NL80211_MCGRP_REGULATORY);
18733 return;
18735 nla_put_failure:
18736 nlmsg_free(msg);
18739 static void nl80211_send_remain_on_chan_event(
18740 int cmd, struct cfg80211_registered_device *rdev,
18741 struct wireless_dev *wdev, u64 cookie,
18742 struct ieee80211_channel *chan,
18743 unsigned int duration, gfp_t gfp)
18745 struct sk_buff *msg;
18746 void *hdr;
18748 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18749 if (!msg)
18750 return;
18752 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
18753 if (!hdr) {
18754 nlmsg_free(msg);
18755 return;
18758 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18759 (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
18760 wdev->netdev->ifindex)) ||
18761 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
18762 NL80211_ATTR_PAD) ||
18763 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) ||
18764 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
18765 NL80211_CHAN_NO_HT) ||
18766 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
18767 NL80211_ATTR_PAD))
18768 goto nla_put_failure;
18770 if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL &&
18771 nla_put_u32(msg, NL80211_ATTR_DURATION, duration))
18772 goto nla_put_failure;
18774 genlmsg_end(msg, hdr);
18776 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18777 NL80211_MCGRP_MLME, gfp);
18778 return;
18780 nla_put_failure:
18781 nlmsg_free(msg);
18784 void cfg80211_assoc_comeback(struct net_device *netdev,
18785 const u8 *ap_addr, u32 timeout)
18787 struct wireless_dev *wdev = netdev->ieee80211_ptr;
18788 struct wiphy *wiphy = wdev->wiphy;
18789 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18790 struct sk_buff *msg;
18791 void *hdr;
18793 trace_cfg80211_assoc_comeback(wdev, ap_addr, timeout);
18795 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
18796 if (!msg)
18797 return;
18799 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ASSOC_COMEBACK);
18800 if (!hdr) {
18801 nlmsg_free(msg);
18802 return;
18805 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18806 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
18807 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ap_addr) ||
18808 nla_put_u32(msg, NL80211_ATTR_TIMEOUT, timeout))
18809 goto nla_put_failure;
18811 genlmsg_end(msg, hdr);
18813 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18814 NL80211_MCGRP_MLME, GFP_KERNEL);
18815 return;
18817 nla_put_failure:
18818 nlmsg_free(msg);
18820 EXPORT_SYMBOL(cfg80211_assoc_comeback);
18822 void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie,
18823 struct ieee80211_channel *chan,
18824 unsigned int duration, gfp_t gfp)
18826 struct wiphy *wiphy = wdev->wiphy;
18827 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18829 trace_cfg80211_ready_on_channel(wdev, cookie, chan, duration);
18830 nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL,
18831 rdev, wdev, cookie, chan,
18832 duration, gfp);
18834 EXPORT_SYMBOL(cfg80211_ready_on_channel);
18836 void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
18837 struct ieee80211_channel *chan,
18838 gfp_t gfp)
18840 struct wiphy *wiphy = wdev->wiphy;
18841 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18843 trace_cfg80211_ready_on_channel_expired(wdev, cookie, chan);
18844 nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
18845 rdev, wdev, cookie, chan, 0, gfp);
18847 EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
18849 void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
18850 struct ieee80211_channel *chan,
18851 gfp_t gfp)
18853 struct wiphy *wiphy = wdev->wiphy;
18854 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18856 trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
18857 nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
18858 rdev, wdev, cookie, chan, 0, gfp);
18860 EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
18862 void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
18863 struct station_info *sinfo, gfp_t gfp)
18865 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
18866 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18867 struct sk_buff *msg;
18869 trace_cfg80211_new_sta(dev, mac_addr, sinfo);
18871 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18872 if (!msg)
18873 return;
18875 if (nl80211_send_station(msg, NL80211_CMD_NEW_STATION, 0, 0, 0,
18876 rdev, dev, mac_addr, sinfo) < 0) {
18877 nlmsg_free(msg);
18878 return;
18881 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18882 NL80211_MCGRP_MLME, gfp);
18884 EXPORT_SYMBOL(cfg80211_new_sta);
18886 void cfg80211_del_sta_sinfo(struct net_device *dev, const u8 *mac_addr,
18887 struct station_info *sinfo, gfp_t gfp)
18889 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
18890 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18891 struct sk_buff *msg;
18892 struct station_info empty_sinfo = {};
18894 if (!sinfo)
18895 sinfo = &empty_sinfo;
18897 trace_cfg80211_del_sta(dev, mac_addr);
18899 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
18900 if (!msg) {
18901 cfg80211_sinfo_release_content(sinfo);
18902 return;
18905 if (nl80211_send_station(msg, NL80211_CMD_DEL_STATION, 0, 0, 0,
18906 rdev, dev, mac_addr, sinfo) < 0) {
18907 nlmsg_free(msg);
18908 return;
18911 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18912 NL80211_MCGRP_MLME, gfp);
18914 EXPORT_SYMBOL(cfg80211_del_sta_sinfo);
18916 void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
18917 enum nl80211_connect_failed_reason reason,
18918 gfp_t gfp)
18920 struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
18921 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
18922 struct sk_buff *msg;
18923 void *hdr;
18925 msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
18926 if (!msg)
18927 return;
18929 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED);
18930 if (!hdr) {
18931 nlmsg_free(msg);
18932 return;
18935 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18936 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) ||
18937 nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason))
18938 goto nla_put_failure;
18940 genlmsg_end(msg, hdr);
18942 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
18943 NL80211_MCGRP_MLME, gfp);
18944 return;
18946 nla_put_failure:
18947 nlmsg_free(msg);
18949 EXPORT_SYMBOL(cfg80211_conn_failed);
18951 static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
18952 const u8 *addr, gfp_t gfp)
18954 struct wireless_dev *wdev = dev->ieee80211_ptr;
18955 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
18956 struct sk_buff *msg;
18957 void *hdr;
18958 u32 nlportid = READ_ONCE(wdev->ap_unexpected_nlportid);
18960 if (!nlportid)
18961 return false;
18963 msg = nlmsg_new(100, gfp);
18964 if (!msg)
18965 return true;
18967 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
18968 if (!hdr) {
18969 nlmsg_free(msg);
18970 return true;
18973 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
18974 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
18975 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
18976 goto nla_put_failure;
18978 genlmsg_end(msg, hdr);
18979 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
18980 return true;
18982 nla_put_failure:
18983 nlmsg_free(msg);
18984 return true;
18987 bool cfg80211_rx_spurious_frame(struct net_device *dev,
18988 const u8 *addr, gfp_t gfp)
18990 struct wireless_dev *wdev = dev->ieee80211_ptr;
18991 bool ret;
18993 trace_cfg80211_rx_spurious_frame(dev, addr);
18995 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
18996 wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
18997 trace_cfg80211_return_bool(false);
18998 return false;
19000 ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
19001 addr, gfp);
19002 trace_cfg80211_return_bool(ret);
19003 return ret;
19005 EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
19007 bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
19008 const u8 *addr, gfp_t gfp)
19010 struct wireless_dev *wdev = dev->ieee80211_ptr;
19011 bool ret;
19013 trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
19015 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
19016 wdev->iftype != NL80211_IFTYPE_P2P_GO &&
19017 wdev->iftype != NL80211_IFTYPE_AP_VLAN)) {
19018 trace_cfg80211_return_bool(false);
19019 return false;
19021 ret = __nl80211_unexpected_frame(dev,
19022 NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
19023 addr, gfp);
19024 trace_cfg80211_return_bool(ret);
19025 return ret;
19027 EXPORT_SYMBOL(cfg80211_rx_unexpected_4addr_frame);
19029 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
19030 struct wireless_dev *wdev, u32 nlportid,
19031 struct cfg80211_rx_info *info, gfp_t gfp)
19033 struct net_device *netdev = wdev->netdev;
19034 struct sk_buff *msg;
19035 void *hdr;
19037 msg = nlmsg_new(100 + info->len, gfp);
19038 if (!msg)
19039 return -ENOMEM;
19041 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
19042 if (!hdr) {
19043 nlmsg_free(msg);
19044 return -ENOMEM;
19047 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19048 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
19049 netdev->ifindex)) ||
19050 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
19051 NL80211_ATTR_PAD) ||
19052 (info->have_link_id &&
19053 nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, info->link_id)) ||
19054 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, KHZ_TO_MHZ(info->freq)) ||
19055 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET, info->freq % 1000) ||
19056 (info->sig_dbm &&
19057 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, info->sig_dbm)) ||
19058 nla_put(msg, NL80211_ATTR_FRAME, info->len, info->buf) ||
19059 (info->flags &&
19060 nla_put_u32(msg, NL80211_ATTR_RXMGMT_FLAGS, info->flags)) ||
19061 (info->rx_tstamp && nla_put_u64_64bit(msg,
19062 NL80211_ATTR_RX_HW_TIMESTAMP,
19063 info->rx_tstamp,
19064 NL80211_ATTR_PAD)) ||
19065 (info->ack_tstamp && nla_put_u64_64bit(msg,
19066 NL80211_ATTR_TX_HW_TIMESTAMP,
19067 info->ack_tstamp,
19068 NL80211_ATTR_PAD)))
19069 goto nla_put_failure;
19071 genlmsg_end(msg, hdr);
19073 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
19075 nla_put_failure:
19076 nlmsg_free(msg);
19077 return -ENOBUFS;
19080 static void nl80211_frame_tx_status(struct wireless_dev *wdev,
19081 struct cfg80211_tx_status *status,
19082 gfp_t gfp, enum nl80211_commands command)
19084 struct wiphy *wiphy = wdev->wiphy;
19085 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19086 struct net_device *netdev = wdev->netdev;
19087 struct sk_buff *msg;
19088 void *hdr;
19090 if (command == NL80211_CMD_FRAME_TX_STATUS)
19091 trace_cfg80211_mgmt_tx_status(wdev, status->cookie,
19092 status->ack);
19093 else
19094 trace_cfg80211_control_port_tx_status(wdev, status->cookie,
19095 status->ack);
19097 msg = nlmsg_new(100 + status->len, gfp);
19098 if (!msg)
19099 return;
19101 hdr = nl80211hdr_put(msg, 0, 0, 0, command);
19102 if (!hdr) {
19103 nlmsg_free(msg);
19104 return;
19107 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19108 (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
19109 netdev->ifindex)) ||
19110 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
19111 NL80211_ATTR_PAD) ||
19112 nla_put(msg, NL80211_ATTR_FRAME, status->len, status->buf) ||
19113 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, status->cookie,
19114 NL80211_ATTR_PAD) ||
19115 (status->ack && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
19116 (status->tx_tstamp &&
19117 nla_put_u64_64bit(msg, NL80211_ATTR_TX_HW_TIMESTAMP,
19118 status->tx_tstamp, NL80211_ATTR_PAD)) ||
19119 (status->ack_tstamp &&
19120 nla_put_u64_64bit(msg, NL80211_ATTR_RX_HW_TIMESTAMP,
19121 status->ack_tstamp, NL80211_ATTR_PAD)))
19122 goto nla_put_failure;
19124 genlmsg_end(msg, hdr);
19126 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19127 NL80211_MCGRP_MLME, gfp);
19128 return;
19130 nla_put_failure:
19131 nlmsg_free(msg);
19134 void cfg80211_control_port_tx_status(struct wireless_dev *wdev, u64 cookie,
19135 const u8 *buf, size_t len, bool ack,
19136 gfp_t gfp)
19138 struct cfg80211_tx_status status = {
19139 .cookie = cookie,
19140 .buf = buf,
19141 .len = len,
19142 .ack = ack
19145 nl80211_frame_tx_status(wdev, &status, gfp,
19146 NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS);
19148 EXPORT_SYMBOL(cfg80211_control_port_tx_status);
19150 void cfg80211_mgmt_tx_status_ext(struct wireless_dev *wdev,
19151 struct cfg80211_tx_status *status, gfp_t gfp)
19153 nl80211_frame_tx_status(wdev, status, gfp, NL80211_CMD_FRAME_TX_STATUS);
19155 EXPORT_SYMBOL(cfg80211_mgmt_tx_status_ext);
19157 static int __nl80211_rx_control_port(struct net_device *dev,
19158 struct sk_buff *skb,
19159 bool unencrypted,
19160 int link_id,
19161 gfp_t gfp)
19163 struct wireless_dev *wdev = dev->ieee80211_ptr;
19164 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
19165 struct ethhdr *ehdr = eth_hdr(skb);
19166 const u8 *addr = ehdr->h_source;
19167 u16 proto = be16_to_cpu(skb->protocol);
19168 struct sk_buff *msg;
19169 void *hdr;
19170 struct nlattr *frame;
19172 u32 nlportid = READ_ONCE(wdev->conn_owner_nlportid);
19174 if (!nlportid)
19175 return -ENOENT;
19177 msg = nlmsg_new(100 + skb->len, gfp);
19178 if (!msg)
19179 return -ENOMEM;
19181 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONTROL_PORT_FRAME);
19182 if (!hdr) {
19183 nlmsg_free(msg);
19184 return -ENOBUFS;
19187 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19188 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
19189 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
19190 NL80211_ATTR_PAD) ||
19191 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
19192 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) ||
19193 (link_id >= 0 &&
19194 nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)) ||
19195 (unencrypted && nla_put_flag(msg,
19196 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)))
19197 goto nla_put_failure;
19199 frame = nla_reserve(msg, NL80211_ATTR_FRAME, skb->len);
19200 if (!frame)
19201 goto nla_put_failure;
19203 skb_copy_bits(skb, 0, nla_data(frame), skb->len);
19204 genlmsg_end(msg, hdr);
19206 return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
19208 nla_put_failure:
19209 nlmsg_free(msg);
19210 return -ENOBUFS;
19213 bool cfg80211_rx_control_port(struct net_device *dev, struct sk_buff *skb,
19214 bool unencrypted, int link_id)
19216 int ret;
19218 trace_cfg80211_rx_control_port(dev, skb, unencrypted, link_id);
19219 ret = __nl80211_rx_control_port(dev, skb, unencrypted, link_id,
19220 GFP_ATOMIC);
19221 trace_cfg80211_return_bool(ret == 0);
19222 return ret == 0;
19224 EXPORT_SYMBOL(cfg80211_rx_control_port);
19226 static struct sk_buff *cfg80211_prepare_cqm(struct net_device *dev,
19227 const char *mac, gfp_t gfp)
19229 struct wireless_dev *wdev = dev->ieee80211_ptr;
19230 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
19231 struct sk_buff *msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
19232 void **cb;
19234 if (!msg)
19235 return NULL;
19237 cb = (void **)msg->cb;
19239 cb[0] = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM);
19240 if (!cb[0]) {
19241 nlmsg_free(msg);
19242 return NULL;
19245 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19246 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
19247 goto nla_put_failure;
19249 if (mac && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
19250 goto nla_put_failure;
19252 cb[1] = nla_nest_start_noflag(msg, NL80211_ATTR_CQM);
19253 if (!cb[1])
19254 goto nla_put_failure;
19256 cb[2] = rdev;
19258 return msg;
19259 nla_put_failure:
19260 nlmsg_free(msg);
19261 return NULL;
19264 static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp)
19266 void **cb = (void **)msg->cb;
19267 struct cfg80211_registered_device *rdev = cb[2];
19269 nla_nest_end(msg, cb[1]);
19270 genlmsg_end(msg, cb[0]);
19272 memset(msg->cb, 0, sizeof(msg->cb));
19274 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19275 NL80211_MCGRP_MLME, gfp);
19278 void cfg80211_cqm_rssi_notify(struct net_device *dev,
19279 enum nl80211_cqm_rssi_threshold_event rssi_event,
19280 s32 rssi_level, gfp_t gfp)
19282 struct wireless_dev *wdev = dev->ieee80211_ptr;
19283 struct cfg80211_cqm_config *cqm_config;
19285 trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level);
19287 if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW &&
19288 rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH))
19289 return;
19291 rcu_read_lock();
19292 cqm_config = rcu_dereference(wdev->cqm_config);
19293 if (cqm_config) {
19294 cqm_config->last_rssi_event_value = rssi_level;
19295 cqm_config->last_rssi_event_type = rssi_event;
19296 wiphy_work_queue(wdev->wiphy, &wdev->cqm_rssi_work);
19298 rcu_read_unlock();
19300 EXPORT_SYMBOL(cfg80211_cqm_rssi_notify);
19302 void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work)
19304 struct wireless_dev *wdev = container_of(work, struct wireless_dev,
19305 cqm_rssi_work);
19306 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19307 enum nl80211_cqm_rssi_threshold_event rssi_event;
19308 struct cfg80211_cqm_config *cqm_config;
19309 struct sk_buff *msg;
19310 s32 rssi_level;
19312 cqm_config = wiphy_dereference(wdev->wiphy, wdev->cqm_config);
19313 if (!cqm_config)
19314 return;
19316 if (cqm_config->use_range_api)
19317 cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config);
19319 rssi_level = cqm_config->last_rssi_event_value;
19320 rssi_event = cqm_config->last_rssi_event_type;
19322 msg = cfg80211_prepare_cqm(wdev->netdev, NULL, GFP_KERNEL);
19323 if (!msg)
19324 return;
19326 if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT,
19327 rssi_event))
19328 goto nla_put_failure;
19330 if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL,
19331 rssi_level))
19332 goto nla_put_failure;
19334 cfg80211_send_cqm(msg, GFP_KERNEL);
19336 return;
19338 nla_put_failure:
19339 nlmsg_free(msg);
19342 void cfg80211_cqm_txe_notify(struct net_device *dev,
19343 const u8 *peer, u32 num_packets,
19344 u32 rate, u32 intvl, gfp_t gfp)
19346 struct sk_buff *msg;
19348 msg = cfg80211_prepare_cqm(dev, peer, gfp);
19349 if (!msg)
19350 return;
19352 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets))
19353 goto nla_put_failure;
19355 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate))
19356 goto nla_put_failure;
19358 if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl))
19359 goto nla_put_failure;
19361 cfg80211_send_cqm(msg, gfp);
19362 return;
19364 nla_put_failure:
19365 nlmsg_free(msg);
19367 EXPORT_SYMBOL(cfg80211_cqm_txe_notify);
19369 void cfg80211_cqm_pktloss_notify(struct net_device *dev,
19370 const u8 *peer, u32 num_packets, gfp_t gfp)
19372 struct sk_buff *msg;
19374 trace_cfg80211_cqm_pktloss_notify(dev, peer, num_packets);
19376 msg = cfg80211_prepare_cqm(dev, peer, gfp);
19377 if (!msg)
19378 return;
19380 if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets))
19381 goto nla_put_failure;
19383 cfg80211_send_cqm(msg, gfp);
19384 return;
19386 nla_put_failure:
19387 nlmsg_free(msg);
19389 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
19391 void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp)
19393 struct sk_buff *msg;
19395 msg = cfg80211_prepare_cqm(dev, NULL, gfp);
19396 if (!msg)
19397 return;
19399 if (nla_put_flag(msg, NL80211_ATTR_CQM_BEACON_LOSS_EVENT))
19400 goto nla_put_failure;
19402 cfg80211_send_cqm(msg, gfp);
19403 return;
19405 nla_put_failure:
19406 nlmsg_free(msg);
19408 EXPORT_SYMBOL(cfg80211_cqm_beacon_loss_notify);
19410 static void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
19411 struct net_device *netdev, const u8 *bssid,
19412 const u8 *replay_ctr, gfp_t gfp)
19414 struct sk_buff *msg;
19415 struct nlattr *rekey_attr;
19416 void *hdr;
19418 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
19419 if (!msg)
19420 return;
19422 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
19423 if (!hdr) {
19424 nlmsg_free(msg);
19425 return;
19428 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19429 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
19430 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
19431 goto nla_put_failure;
19433 rekey_attr = nla_nest_start_noflag(msg, NL80211_ATTR_REKEY_DATA);
19434 if (!rekey_attr)
19435 goto nla_put_failure;
19437 if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR,
19438 NL80211_REPLAY_CTR_LEN, replay_ctr))
19439 goto nla_put_failure;
19441 nla_nest_end(msg, rekey_attr);
19443 genlmsg_end(msg, hdr);
19445 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19446 NL80211_MCGRP_MLME, gfp);
19447 return;
19449 nla_put_failure:
19450 nlmsg_free(msg);
19453 void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
19454 const u8 *replay_ctr, gfp_t gfp)
19456 struct wireless_dev *wdev = dev->ieee80211_ptr;
19457 struct wiphy *wiphy = wdev->wiphy;
19458 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19460 trace_cfg80211_gtk_rekey_notify(dev, bssid);
19461 nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
19463 EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
19465 static void
19466 nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
19467 struct net_device *netdev, int index,
19468 const u8 *bssid, bool preauth, gfp_t gfp)
19470 struct sk_buff *msg;
19471 struct nlattr *attr;
19472 void *hdr;
19474 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
19475 if (!msg)
19476 return;
19478 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
19479 if (!hdr) {
19480 nlmsg_free(msg);
19481 return;
19484 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19485 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
19486 goto nla_put_failure;
19488 attr = nla_nest_start_noflag(msg, NL80211_ATTR_PMKSA_CANDIDATE);
19489 if (!attr)
19490 goto nla_put_failure;
19492 if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) ||
19493 nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) ||
19494 (preauth &&
19495 nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH)))
19496 goto nla_put_failure;
19498 nla_nest_end(msg, attr);
19500 genlmsg_end(msg, hdr);
19502 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19503 NL80211_MCGRP_MLME, gfp);
19504 return;
19506 nla_put_failure:
19507 nlmsg_free(msg);
19510 void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
19511 const u8 *bssid, bool preauth, gfp_t gfp)
19513 struct wireless_dev *wdev = dev->ieee80211_ptr;
19514 struct wiphy *wiphy = wdev->wiphy;
19515 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19517 trace_cfg80211_pmksa_candidate_notify(dev, index, bssid, preauth);
19518 nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
19520 EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
19522 static void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
19523 struct net_device *netdev,
19524 unsigned int link_id,
19525 struct cfg80211_chan_def *chandef,
19526 gfp_t gfp,
19527 enum nl80211_commands notif,
19528 u8 count, bool quiet)
19530 struct wireless_dev *wdev = netdev->ieee80211_ptr;
19531 struct sk_buff *msg;
19532 void *hdr;
19534 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
19535 if (!msg)
19536 return;
19538 hdr = nl80211hdr_put(msg, 0, 0, 0, notif);
19539 if (!hdr) {
19540 nlmsg_free(msg);
19541 return;
19544 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
19545 goto nla_put_failure;
19547 if (wdev->valid_links &&
19548 nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
19549 goto nla_put_failure;
19551 if (nl80211_send_chandef(msg, chandef))
19552 goto nla_put_failure;
19554 if (notif == NL80211_CMD_CH_SWITCH_STARTED_NOTIFY) {
19555 if (nla_put_u32(msg, NL80211_ATTR_CH_SWITCH_COUNT, count))
19556 goto nla_put_failure;
19557 if (quiet &&
19558 nla_put_flag(msg, NL80211_ATTR_CH_SWITCH_BLOCK_TX))
19559 goto nla_put_failure;
19562 genlmsg_end(msg, hdr);
19564 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19565 NL80211_MCGRP_MLME, gfp);
19566 return;
19568 nla_put_failure:
19569 nlmsg_free(msg);
19572 void cfg80211_ch_switch_notify(struct net_device *dev,
19573 struct cfg80211_chan_def *chandef,
19574 unsigned int link_id)
19576 struct wireless_dev *wdev = dev->ieee80211_ptr;
19577 struct wiphy *wiphy = wdev->wiphy;
19578 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19580 lockdep_assert_wiphy(wdev->wiphy);
19581 WARN_INVALID_LINK_ID(wdev, link_id);
19583 trace_cfg80211_ch_switch_notify(dev, chandef, link_id);
19585 switch (wdev->iftype) {
19586 case NL80211_IFTYPE_STATION:
19587 case NL80211_IFTYPE_P2P_CLIENT:
19588 if (!WARN_ON(!wdev->links[link_id].client.current_bss))
19589 cfg80211_update_assoc_bss_entry(wdev, link_id,
19590 chandef->chan);
19591 break;
19592 case NL80211_IFTYPE_MESH_POINT:
19593 wdev->u.mesh.chandef = *chandef;
19594 wdev->u.mesh.preset_chandef = *chandef;
19595 break;
19596 case NL80211_IFTYPE_AP:
19597 case NL80211_IFTYPE_P2P_GO:
19598 wdev->links[link_id].ap.chandef = *chandef;
19599 break;
19600 case NL80211_IFTYPE_ADHOC:
19601 wdev->u.ibss.chandef = *chandef;
19602 break;
19603 default:
19604 WARN_ON(1);
19605 break;
19608 cfg80211_schedule_channels_check(wdev);
19609 cfg80211_sched_dfs_chan_update(rdev);
19611 nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
19612 NL80211_CMD_CH_SWITCH_NOTIFY, 0, false);
19614 EXPORT_SYMBOL(cfg80211_ch_switch_notify);
19616 void cfg80211_ch_switch_started_notify(struct net_device *dev,
19617 struct cfg80211_chan_def *chandef,
19618 unsigned int link_id, u8 count,
19619 bool quiet)
19621 struct wireless_dev *wdev = dev->ieee80211_ptr;
19622 struct wiphy *wiphy = wdev->wiphy;
19623 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19625 lockdep_assert_wiphy(wdev->wiphy);
19626 WARN_INVALID_LINK_ID(wdev, link_id);
19628 trace_cfg80211_ch_switch_started_notify(dev, chandef, link_id);
19631 nl80211_ch_switch_notify(rdev, dev, link_id, chandef, GFP_KERNEL,
19632 NL80211_CMD_CH_SWITCH_STARTED_NOTIFY,
19633 count, quiet);
19635 EXPORT_SYMBOL(cfg80211_ch_switch_started_notify);
19637 int cfg80211_bss_color_notify(struct net_device *dev,
19638 enum nl80211_commands cmd, u8 count,
19639 u64 color_bitmap, u8 link_id)
19641 struct wireless_dev *wdev = dev->ieee80211_ptr;
19642 struct wiphy *wiphy = wdev->wiphy;
19643 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19644 struct sk_buff *msg;
19645 void *hdr;
19647 lockdep_assert_wiphy(wdev->wiphy);
19649 trace_cfg80211_bss_color_notify(dev, cmd, count, color_bitmap);
19651 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
19652 if (!msg)
19653 return -ENOMEM;
19655 hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
19656 if (!hdr)
19657 goto nla_put_failure;
19659 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
19660 goto nla_put_failure;
19662 if (wdev->valid_links &&
19663 nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
19664 goto nla_put_failure;
19666 if (cmd == NL80211_CMD_COLOR_CHANGE_STARTED &&
19667 nla_put_u32(msg, NL80211_ATTR_COLOR_CHANGE_COUNT, count))
19668 goto nla_put_failure;
19670 if (cmd == NL80211_CMD_OBSS_COLOR_COLLISION &&
19671 nla_put_u64_64bit(msg, NL80211_ATTR_OBSS_COLOR_BITMAP,
19672 color_bitmap, NL80211_ATTR_PAD))
19673 goto nla_put_failure;
19675 genlmsg_end(msg, hdr);
19677 return genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy),
19678 msg, 0, NL80211_MCGRP_MLME, GFP_KERNEL);
19680 nla_put_failure:
19681 nlmsg_free(msg);
19682 return -EINVAL;
19684 EXPORT_SYMBOL(cfg80211_bss_color_notify);
19686 void
19687 nl80211_radar_notify(struct cfg80211_registered_device *rdev,
19688 const struct cfg80211_chan_def *chandef,
19689 enum nl80211_radar_event event,
19690 struct net_device *netdev, gfp_t gfp)
19692 struct sk_buff *msg;
19693 void *hdr;
19695 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
19696 if (!msg)
19697 return;
19699 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_RADAR_DETECT);
19700 if (!hdr) {
19701 nlmsg_free(msg);
19702 return;
19705 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
19706 goto nla_put_failure;
19708 /* NOP and radar events don't need a netdev parameter */
19709 if (netdev) {
19710 struct wireless_dev *wdev = netdev->ieee80211_ptr;
19712 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
19713 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
19714 NL80211_ATTR_PAD))
19715 goto nla_put_failure;
19718 if (nla_put_u32(msg, NL80211_ATTR_RADAR_EVENT, event))
19719 goto nla_put_failure;
19721 if (nl80211_send_chandef(msg, chandef))
19722 goto nla_put_failure;
19724 genlmsg_end(msg, hdr);
19726 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19727 NL80211_MCGRP_MLME, gfp);
19728 return;
19730 nla_put_failure:
19731 nlmsg_free(msg);
19734 void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
19735 struct sta_opmode_info *sta_opmode,
19736 gfp_t gfp)
19738 struct sk_buff *msg;
19739 struct wireless_dev *wdev = dev->ieee80211_ptr;
19740 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
19741 void *hdr;
19743 if (WARN_ON(!mac))
19744 return;
19746 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
19747 if (!msg)
19748 return;
19750 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STA_OPMODE_CHANGED);
19751 if (!hdr) {
19752 nlmsg_free(msg);
19753 return;
19756 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx))
19757 goto nla_put_failure;
19759 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex))
19760 goto nla_put_failure;
19762 if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac))
19763 goto nla_put_failure;
19765 if ((sta_opmode->changed & STA_OPMODE_SMPS_MODE_CHANGED) &&
19766 nla_put_u8(msg, NL80211_ATTR_SMPS_MODE, sta_opmode->smps_mode))
19767 goto nla_put_failure;
19769 if ((sta_opmode->changed & STA_OPMODE_MAX_BW_CHANGED) &&
19770 nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, sta_opmode->bw))
19771 goto nla_put_failure;
19773 if ((sta_opmode->changed & STA_OPMODE_N_SS_CHANGED) &&
19774 nla_put_u8(msg, NL80211_ATTR_NSS, sta_opmode->rx_nss))
19775 goto nla_put_failure;
19777 genlmsg_end(msg, hdr);
19779 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19780 NL80211_MCGRP_MLME, gfp);
19782 return;
19784 nla_put_failure:
19785 nlmsg_free(msg);
19787 EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
19789 void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
19790 u64 cookie, bool acked, s32 ack_signal,
19791 bool is_valid_ack_signal, gfp_t gfp)
19793 struct wireless_dev *wdev = dev->ieee80211_ptr;
19794 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
19795 struct sk_buff *msg;
19796 void *hdr;
19798 trace_cfg80211_probe_status(dev, addr, cookie, acked);
19800 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
19802 if (!msg)
19803 return;
19805 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
19806 if (!hdr) {
19807 nlmsg_free(msg);
19808 return;
19811 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19812 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
19813 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
19814 nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
19815 NL80211_ATTR_PAD) ||
19816 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
19817 (is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
19818 ack_signal)))
19819 goto nla_put_failure;
19821 genlmsg_end(msg, hdr);
19823 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
19824 NL80211_MCGRP_MLME, gfp);
19825 return;
19827 nla_put_failure:
19828 nlmsg_free(msg);
19830 EXPORT_SYMBOL(cfg80211_probe_status);
19832 void cfg80211_report_obss_beacon_khz(struct wiphy *wiphy, const u8 *frame,
19833 size_t len, int freq, int sig_dbm)
19835 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
19836 struct sk_buff *msg;
19837 void *hdr;
19838 struct cfg80211_beacon_registration *reg;
19840 trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm);
19842 spin_lock_bh(&rdev->beacon_registrations_lock);
19843 list_for_each_entry(reg, &rdev->beacon_registrations, list) {
19844 msg = nlmsg_new(len + 100, GFP_ATOMIC);
19845 if (!msg) {
19846 spin_unlock_bh(&rdev->beacon_registrations_lock);
19847 return;
19850 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
19851 if (!hdr)
19852 goto nla_put_failure;
19854 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19855 (freq &&
19856 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
19857 KHZ_TO_MHZ(freq)) ||
19858 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ_OFFSET,
19859 freq % 1000))) ||
19860 (sig_dbm &&
19861 nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) ||
19862 nla_put(msg, NL80211_ATTR_FRAME, len, frame))
19863 goto nla_put_failure;
19865 genlmsg_end(msg, hdr);
19867 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid);
19869 spin_unlock_bh(&rdev->beacon_registrations_lock);
19870 return;
19872 nla_put_failure:
19873 spin_unlock_bh(&rdev->beacon_registrations_lock);
19874 nlmsg_free(msg);
19876 EXPORT_SYMBOL(cfg80211_report_obss_beacon_khz);
19878 #ifdef CONFIG_PM
19879 static int cfg80211_net_detect_results(struct sk_buff *msg,
19880 struct cfg80211_wowlan_wakeup *wakeup)
19882 struct cfg80211_wowlan_nd_info *nd = wakeup->net_detect;
19883 struct nlattr *nl_results, *nl_match, *nl_freqs;
19884 int i, j;
19886 nl_results = nla_nest_start_noflag(msg,
19887 NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS);
19888 if (!nl_results)
19889 return -EMSGSIZE;
19891 for (i = 0; i < nd->n_matches; i++) {
19892 struct cfg80211_wowlan_nd_match *match = nd->matches[i];
19894 nl_match = nla_nest_start_noflag(msg, i);
19895 if (!nl_match)
19896 break;
19898 /* The SSID attribute is optional in nl80211, but for
19899 * simplicity reasons it's always present in the
19900 * cfg80211 structure. If a driver can't pass the
19901 * SSID, that needs to be changed. A zero length SSID
19902 * is still a valid SSID (wildcard), so it cannot be
19903 * used for this purpose.
19905 if (nla_put(msg, NL80211_ATTR_SSID, match->ssid.ssid_len,
19906 match->ssid.ssid)) {
19907 nla_nest_cancel(msg, nl_match);
19908 goto out;
19911 if (match->n_channels) {
19912 nl_freqs = nla_nest_start_noflag(msg,
19913 NL80211_ATTR_SCAN_FREQUENCIES);
19914 if (!nl_freqs) {
19915 nla_nest_cancel(msg, nl_match);
19916 goto out;
19919 for (j = 0; j < match->n_channels; j++) {
19920 if (nla_put_u32(msg, j, match->channels[j])) {
19921 nla_nest_cancel(msg, nl_freqs);
19922 nla_nest_cancel(msg, nl_match);
19923 goto out;
19927 nla_nest_end(msg, nl_freqs);
19930 nla_nest_end(msg, nl_match);
19933 out:
19934 nla_nest_end(msg, nl_results);
19935 return 0;
19938 void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
19939 struct cfg80211_wowlan_wakeup *wakeup,
19940 gfp_t gfp)
19942 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
19943 struct sk_buff *msg;
19944 void *hdr;
19945 int size = 200;
19947 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
19949 if (wakeup)
19950 size += wakeup->packet_present_len;
19952 msg = nlmsg_new(size, gfp);
19953 if (!msg)
19954 return;
19956 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_WOWLAN);
19957 if (!hdr)
19958 goto free_msg;
19960 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
19961 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
19962 NL80211_ATTR_PAD))
19963 goto free_msg;
19965 if (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX,
19966 wdev->netdev->ifindex))
19967 goto free_msg;
19969 if (wakeup) {
19970 struct nlattr *reasons;
19972 reasons = nla_nest_start_noflag(msg,
19973 NL80211_ATTR_WOWLAN_TRIGGERS);
19974 if (!reasons)
19975 goto free_msg;
19977 if (wakeup->disconnect &&
19978 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT))
19979 goto free_msg;
19980 if (wakeup->magic_pkt &&
19981 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT))
19982 goto free_msg;
19983 if (wakeup->gtk_rekey_failure &&
19984 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE))
19985 goto free_msg;
19986 if (wakeup->eap_identity_req &&
19987 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST))
19988 goto free_msg;
19989 if (wakeup->four_way_handshake &&
19990 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE))
19991 goto free_msg;
19992 if (wakeup->rfkill_release &&
19993 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))
19994 goto free_msg;
19996 if (wakeup->pattern_idx >= 0 &&
19997 nla_put_u32(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
19998 wakeup->pattern_idx))
19999 goto free_msg;
20001 if (wakeup->tcp_match &&
20002 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH))
20003 goto free_msg;
20005 if (wakeup->tcp_connlost &&
20006 nla_put_flag(msg, NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST))
20007 goto free_msg;
20009 if (wakeup->tcp_nomoretokens &&
20010 nla_put_flag(msg,
20011 NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS))
20012 goto free_msg;
20014 if (wakeup->unprot_deauth_disassoc &&
20015 nla_put_flag(msg,
20016 NL80211_WOWLAN_TRIG_UNPROTECTED_DEAUTH_DISASSOC))
20017 goto free_msg;
20019 if (wakeup->packet) {
20020 u32 pkt_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211;
20021 u32 len_attr = NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN;
20023 if (!wakeup->packet_80211) {
20024 pkt_attr =
20025 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023;
20026 len_attr =
20027 NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN;
20030 if (wakeup->packet_len &&
20031 nla_put_u32(msg, len_attr, wakeup->packet_len))
20032 goto free_msg;
20034 if (nla_put(msg, pkt_attr, wakeup->packet_present_len,
20035 wakeup->packet))
20036 goto free_msg;
20039 if (wakeup->net_detect &&
20040 cfg80211_net_detect_results(msg, wakeup))
20041 goto free_msg;
20043 nla_nest_end(msg, reasons);
20046 genlmsg_end(msg, hdr);
20048 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
20049 NL80211_MCGRP_MLME, gfp);
20050 return;
20052 free_msg:
20053 nlmsg_free(msg);
20055 EXPORT_SYMBOL(cfg80211_report_wowlan_wakeup);
20056 #endif
20058 void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
20059 enum nl80211_tdls_operation oper,
20060 u16 reason_code, gfp_t gfp)
20062 struct wireless_dev *wdev = dev->ieee80211_ptr;
20063 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
20064 struct sk_buff *msg;
20065 void *hdr;
20067 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
20068 reason_code);
20070 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
20071 if (!msg)
20072 return;
20074 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER);
20075 if (!hdr) {
20076 nlmsg_free(msg);
20077 return;
20080 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
20081 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
20082 nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) ||
20083 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) ||
20084 (reason_code > 0 &&
20085 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
20086 goto nla_put_failure;
20088 genlmsg_end(msg, hdr);
20090 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
20091 NL80211_MCGRP_MLME, gfp);
20092 return;
20094 nla_put_failure:
20095 nlmsg_free(msg);
20097 EXPORT_SYMBOL(cfg80211_tdls_oper_request);
20099 static int nl80211_netlink_notify(struct notifier_block * nb,
20100 unsigned long state,
20101 void *_notify)
20103 struct netlink_notify *notify = _notify;
20104 struct cfg80211_registered_device *rdev;
20105 struct wireless_dev *wdev;
20106 struct cfg80211_beacon_registration *reg, *tmp;
20108 if (state != NETLINK_URELEASE || notify->protocol != NETLINK_GENERIC)
20109 return NOTIFY_DONE;
20111 rcu_read_lock();
20113 list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
20114 struct cfg80211_sched_scan_request *sched_scan_req;
20116 list_for_each_entry_rcu(sched_scan_req,
20117 &rdev->sched_scan_req_list,
20118 list) {
20119 if (sched_scan_req->owner_nlportid == notify->portid) {
20120 sched_scan_req->nl_owner_dead = true;
20121 wiphy_work_queue(&rdev->wiphy,
20122 &rdev->sched_scan_stop_wk);
20126 list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
20127 cfg80211_mlme_unregister_socket(wdev, notify->portid);
20129 if (wdev->owner_nlportid == notify->portid) {
20130 wdev->nl_owner_dead = true;
20131 schedule_work(&rdev->destroy_work);
20132 } else if (wdev->conn_owner_nlportid == notify->portid) {
20133 schedule_work(&wdev->disconnect_wk);
20136 cfg80211_release_pmsr(wdev, notify->portid);
20139 spin_lock_bh(&rdev->beacon_registrations_lock);
20140 list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
20141 list) {
20142 if (reg->nlportid == notify->portid) {
20143 list_del(&reg->list);
20144 kfree(reg);
20145 break;
20148 spin_unlock_bh(&rdev->beacon_registrations_lock);
20151 rcu_read_unlock();
20154 * It is possible that the user space process that is controlling the
20155 * indoor setting disappeared, so notify the regulatory core.
20157 regulatory_netlink_notify(notify->portid);
20158 return NOTIFY_OK;
20161 static struct notifier_block nl80211_netlink_notifier = {
20162 .notifier_call = nl80211_netlink_notify,
20165 void cfg80211_ft_event(struct net_device *netdev,
20166 struct cfg80211_ft_event_params *ft_event)
20168 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
20169 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
20170 struct sk_buff *msg;
20171 void *hdr;
20173 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
20175 if (!ft_event->target_ap)
20176 return;
20178 msg = nlmsg_new(100 + ft_event->ies_len + ft_event->ric_ies_len,
20179 GFP_KERNEL);
20180 if (!msg)
20181 return;
20183 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FT_EVENT);
20184 if (!hdr)
20185 goto out;
20187 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
20188 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
20189 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, ft_event->target_ap))
20190 goto out;
20192 if (ft_event->ies &&
20193 nla_put(msg, NL80211_ATTR_IE, ft_event->ies_len, ft_event->ies))
20194 goto out;
20195 if (ft_event->ric_ies &&
20196 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
20197 ft_event->ric_ies))
20198 goto out;
20200 genlmsg_end(msg, hdr);
20202 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
20203 NL80211_MCGRP_MLME, GFP_KERNEL);
20204 return;
20205 out:
20206 nlmsg_free(msg);
20208 EXPORT_SYMBOL(cfg80211_ft_event);
20210 void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp)
20212 struct cfg80211_registered_device *rdev;
20213 struct sk_buff *msg;
20214 void *hdr;
20215 u32 nlportid;
20217 rdev = wiphy_to_rdev(wdev->wiphy);
20218 if (!rdev->crit_proto_nlportid)
20219 return;
20221 nlportid = rdev->crit_proto_nlportid;
20222 rdev->crit_proto_nlportid = 0;
20224 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
20225 if (!msg)
20226 return;
20228 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CRIT_PROTOCOL_STOP);
20229 if (!hdr)
20230 goto nla_put_failure;
20232 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
20233 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
20234 NL80211_ATTR_PAD))
20235 goto nla_put_failure;
20237 genlmsg_end(msg, hdr);
20239 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
20240 return;
20242 nla_put_failure:
20243 nlmsg_free(msg);
20245 EXPORT_SYMBOL(cfg80211_crit_proto_stopped);
20247 void nl80211_send_ap_stopped(struct wireless_dev *wdev, unsigned int link_id)
20249 struct wiphy *wiphy = wdev->wiphy;
20250 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
20251 struct sk_buff *msg;
20252 void *hdr;
20254 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
20255 if (!msg)
20256 return;
20258 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_STOP_AP);
20259 if (!hdr)
20260 goto out;
20262 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
20263 nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex) ||
20264 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev),
20265 NL80211_ATTR_PAD) ||
20266 (wdev->valid_links &&
20267 nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)))
20268 goto out;
20270 genlmsg_end(msg, hdr);
20272 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(wiphy), msg, 0,
20273 NL80211_MCGRP_MLME, GFP_KERNEL);
20274 return;
20275 out:
20276 nlmsg_free(msg);
20279 int cfg80211_external_auth_request(struct net_device *dev,
20280 struct cfg80211_external_auth_params *params,
20281 gfp_t gfp)
20283 struct wireless_dev *wdev = dev->ieee80211_ptr;
20284 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
20285 struct sk_buff *msg;
20286 void *hdr;
20288 if (!wdev->conn_owner_nlportid)
20289 return -EINVAL;
20291 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
20292 if (!msg)
20293 return -ENOMEM;
20295 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_EXTERNAL_AUTH);
20296 if (!hdr)
20297 goto nla_put_failure;
20299 /* Some historical mistakes in drivers <-> userspace interface (notably
20300 * between drivers and wpa_supplicant) led to a big-endian conversion
20301 * being needed on NL80211_ATTR_AKM_SUITES _only_ when its value is
20302 * WLAN_AKM_SUITE_SAE. This is now fixed on userspace side, but for the
20303 * benefit of older wpa_supplicant versions, send this particular value
20304 * in big-endian. Note that newer wpa_supplicant will also detect this
20305 * particular value in big endian still, so it all continues to work.
20307 if (params->key_mgmt_suite == WLAN_AKM_SUITE_SAE) {
20308 if (nla_put_be32(msg, NL80211_ATTR_AKM_SUITES,
20309 cpu_to_be32(WLAN_AKM_SUITE_SAE)))
20310 goto nla_put_failure;
20311 } else {
20312 if (nla_put_u32(msg, NL80211_ATTR_AKM_SUITES,
20313 params->key_mgmt_suite))
20314 goto nla_put_failure;
20317 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
20318 nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
20319 nla_put_u32(msg, NL80211_ATTR_EXTERNAL_AUTH_ACTION,
20320 params->action) ||
20321 nla_put(msg, NL80211_ATTR_BSSID, ETH_ALEN, params->bssid) ||
20322 nla_put(msg, NL80211_ATTR_SSID, params->ssid.ssid_len,
20323 params->ssid.ssid) ||
20324 (!is_zero_ether_addr(params->mld_addr) &&
20325 nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN, params->mld_addr)))
20326 goto nla_put_failure;
20328 genlmsg_end(msg, hdr);
20329 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg,
20330 wdev->conn_owner_nlportid);
20331 return 0;
20333 nla_put_failure:
20334 nlmsg_free(msg);
20335 return -ENOBUFS;
20337 EXPORT_SYMBOL(cfg80211_external_auth_request);
20339 void cfg80211_update_owe_info_event(struct net_device *netdev,
20340 struct cfg80211_update_owe_info *owe_info,
20341 gfp_t gfp)
20343 struct wiphy *wiphy = netdev->ieee80211_ptr->wiphy;
20344 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
20345 struct sk_buff *msg;
20346 void *hdr;
20348 trace_cfg80211_update_owe_info_event(wiphy, netdev, owe_info);
20350 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
20351 if (!msg)
20352 return;
20354 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UPDATE_OWE_INFO);
20355 if (!hdr)
20356 goto nla_put_failure;
20358 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
20359 nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
20360 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, owe_info->peer))
20361 goto nla_put_failure;
20363 if (!owe_info->ie_len ||
20364 nla_put(msg, NL80211_ATTR_IE, owe_info->ie_len, owe_info->ie))
20365 goto nla_put_failure;
20367 if (owe_info->assoc_link_id != -1) {
20368 if (nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID,
20369 owe_info->assoc_link_id))
20370 goto nla_put_failure;
20372 if (!is_zero_ether_addr(owe_info->peer_mld_addr) &&
20373 nla_put(msg, NL80211_ATTR_MLD_ADDR, ETH_ALEN,
20374 owe_info->peer_mld_addr))
20375 goto nla_put_failure;
20378 genlmsg_end(msg, hdr);
20380 genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
20381 NL80211_MCGRP_MLME, gfp);
20382 return;
20384 nla_put_failure:
20385 genlmsg_cancel(msg, hdr);
20386 nlmsg_free(msg);
20388 EXPORT_SYMBOL(cfg80211_update_owe_info_event);
20390 void cfg80211_schedule_channels_check(struct wireless_dev *wdev)
20392 struct wiphy *wiphy = wdev->wiphy;
20394 /* Schedule channels check if NO_IR or DFS relaxations are supported */
20395 if (wdev->iftype == NL80211_IFTYPE_STATION &&
20396 (wiphy_ext_feature_isset(wiphy,
20397 NL80211_EXT_FEATURE_DFS_CONCURRENT) ||
20398 (IS_ENABLED(CONFIG_CFG80211_REG_RELAX_NO_IR) &&
20399 wiphy->regulatory_flags & REGULATORY_ENABLE_RELAX_NO_IR)))
20400 reg_check_channels();
20402 EXPORT_SYMBOL(cfg80211_schedule_channels_check);
20404 /* initialisation/exit functions */
20406 int __init nl80211_init(void)
20408 int err;
20410 err = genl_register_family(&nl80211_fam);
20411 if (err)
20412 return err;
20414 err = netlink_register_notifier(&nl80211_netlink_notifier);
20415 if (err)
20416 goto err_out;
20418 return 0;
20419 err_out:
20420 genl_unregister_family(&nl80211_fam);
20421 return err;
20424 void nl80211_exit(void)
20426 netlink_unregister_notifier(&nl80211_netlink_notifier);
20427 genl_unregister_family(&nl80211_fam);